Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -284,7 +284,8 @@ LLVMInlineAsmValueKind, LLVMInstructionValueKind, - LLVMPoisonValueValueKind + LLVMPoisonValueValueKind, + LLVMUnknownProvenanceValueKind } LLVMValueKind; typedef enum { @@ -1904,6 +1905,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/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 @@ -1774,6 +1774,20 @@ getContext().pImpl->CPNConstants.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 @@ -1098,6 +1098,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 @@ -1430,6 +1430,8 @@ DenseMap> CPNConstants; + 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(); + 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 @@ -349,6 +349,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);