Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -287,6 +287,7 @@ LLVMInstructionValueKind, LLVMPoisonValueValueKind, LLVMConstantTargetNoneValueKind, + LLVMUnknownProvenanceValueKind } LLVMValueKind; typedef enum { @@ -1948,6 +1949,19 @@ */ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); +/** + * Determine whether a value instance is unknown_provenance. + * + * @see llvm::UnknownProvenance + */ +LLVMBool LLVMIsUnknownProvenance(LLVMValueRef Val); + +/** + * Obtain a constant that is an constant pointer pointing to unknown_provenance + * for a specified type. + */ +LLVMValueRef LLVMGetUnknownProvenance(LLVMTypeRef Ty); + /** * @defgroup LLVMCCoreValueConstantScalar Scalar constants * Index: llvm/include/llvm/IR/Constant.h =================================================================== --- llvm/include/llvm/IR/Constant.h +++ llvm/include/llvm/IR/Constant.h @@ -183,6 +183,8 @@ static Constant *getNullValue(Type* Ty); + static Constant *getUnknownProvenance(Type *Ty); + /// @returns the value for an integer or vector of integer constant of the /// given type that has all its bits set to true. /// Get the all ones value Index: llvm/include/llvm/IR/Constants.h =================================================================== --- llvm/include/llvm/IR/Constants.h +++ llvm/include/llvm/IR/Constants.h @@ -557,6 +557,33 @@ } }; +//===----------------------------------------------------------------------===// +/// A provenance pointer value indicating that the provenance can be anything. +/// +class UnknownProvenance final : public ConstantData { + friend class Constant; + + explicit UnknownProvenance(PointerType *T) + : ConstantData(T, Value::UnknownProvenanceVal) {} + + void destroyConstantImpl(); + +public: + UnknownProvenance(const UnknownProvenance &) = delete; + + /// Static factory methods - Return objects of the specified value + static UnknownProvenance *get(PointerType *T); + + /// Specialize the getType() method to always return an PointerType, + /// which reduces the amount of casting needed in parts of the compiler. + PointerType *getType() const { return cast(Value::getType()); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Value *V) { + return V->getValueID() == UnknownProvenanceVal; + } +}; + //===----------------------------------------------------------------------===// /// ConstantDataSequential - A vector or array constant whose element type is a /// simple 1/2/4/8-byte integer or half/bfloat/float/double, and whose elements Index: llvm/include/llvm/IR/Value.def =================================================================== --- llvm/include/llvm/IR/Value.def +++ llvm/include/llvm/IR/Value.def @@ -89,6 +89,7 @@ // ConstantData. HANDLE_CONSTANT(UndefValue) +HANDLE_CONSTANT(UnknownProvenance) HANDLE_CONSTANT(PoisonValue) HANDLE_CONSTANT(ConstantAggregateZero) HANDLE_CONSTANT(ConstantDataArray) Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -383,6 +383,12 @@ } } +// Constructor to create a 'unknown_provenance' constant. +Constant *Constant::getUnknownProvenance(Type *Ty) { + assert(Ty->isPointerTy() && "unknown_provenance must always be a pointer"); + return UnknownProvenance::get(cast(Ty)); +} + Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) { Type *ScalarTy = Ty->getScalarType(); @@ -1737,6 +1743,20 @@ getContext().pImpl->CTNConstants.erase(getType()); } +UnknownProvenance *UnknownProvenance::get(PointerType *Ty) { + std::unique_ptr &Entry = + Ty->getContext().pImpl->UPConstants[Ty]; + if (!Entry) + Entry.reset(new UnknownProvenance(Ty)); + + return Entry.get(); +} + +/// Remove the constant from the constant table. +void UnknownProvenance::destroyConstantImpl() { + getContext().pImpl->UPConstants.erase(getType()); +} + UndefValue *UndefValue::get(Type *Ty) { std::unique_ptr &Entry = Ty->getContext().pImpl->UVConstants[Ty]; if (!Entry) Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -1130,6 +1130,14 @@ return wrap(ConstantPointerNull::get(unwrap(Ty))); } +LLVMBool LLVMIsUnknownProvenance(LLVMValueRef Val) { + return isa(unwrap(Val)); +} + +LLVMValueRef LLVMGetUnknownProvenance(LLVMTypeRef Ty) { + return wrap(UnknownProvenance::get(unwrap(Ty))); +} + /*--.. Operations on metadata nodes ........................................--*/ LLVMMetadataRef LLVMMDStringInContext2(LLVMContextRef C, const char *Str, Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -1490,6 +1490,8 @@ DenseMap> CTNConstants; + DenseMap> UPConstants; + DenseMap> UVConstants; DenseMap> PVConstants; Index: llvm/lib/IR/LLVMContextImpl.cpp =================================================================== --- llvm/lib/IR/LLVMContextImpl.cpp +++ llvm/lib/IR/LLVMContextImpl.cpp @@ -114,6 +114,7 @@ CAZConstants.clear(); CPNConstants.clear(); CTNConstants.clear(); + UPConstants.clear(); UVConstants.clear(); PVConstants.clear(); IntConstants.clear(); Index: llvm/tools/llvm-c-test/echo.cpp =================================================================== --- llvm/tools/llvm-c-test/echo.cpp +++ llvm/tools/llvm-c-test/echo.cpp @@ -343,6 +343,12 @@ return LLVMGetUndef(TypeCloner(M).Clone(Cst)); } + // Try unknown_provenance + if (LLVMIsUnknownProvenance(Cst)) { + check_value_kind(Cst, LLVMUnknownProvenanceValueKind); + return LLVMGetUnknownProvenance(TypeCloner(M).Clone(Cst)); + } + // Try poison if (LLVMIsPoison(Cst)) { check_value_kind(Cst, LLVMPoisonValueValueKind);