Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -3945,6 +3945,21 @@ LLVMAtomicRMWBinOp LLVMGetAtomicRMWBinOp(LLVMValueRef AtomicRMWInst); void LLVMSetAtomicRMWBinOp(LLVMValueRef AtomicRMWInst, LLVMAtomicRMWBinOp BinOp); +/** + * \returns the ptr_provenance operand of a load/store instruction. Returns a + * NULL if the load/store instruction does not has a ptr_provenance operand. + */ +LLVMValueRef +LLVMExperimentalGetPtrProvenanceOperand(LLVMValueRef LoadOrStoreInst); + +/** + * Sets or removes the optional ptr_provenance operand of a load/store + * instruction. When a NULL is passed as PtrProvenance, the ptr_provenance + * operand will be removed. + */ +void LLVMExperimentalSetPtrProvenanceOperand(LLVMValueRef LoadOrStoreInst, + LLVMValueRef PtrProvenance); + /* Casts */ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -3813,6 +3813,40 @@ unwrap(Inst)->setOperation(mapFromLLVMRMWBinOp(BinOp)); } +LLVMValueRef +LLVMExperimentalGetPtrProvenanceOperand(LLVMValueRef LoadOrStoreInst) { + Value *P = unwrap(LoadOrStoreInst); + if (LoadInst *LI = dyn_cast(P)) { + if (LI->hasPtrProvenanceOperand()) + return wrap(LI->getPtrProvenanceOperand()); + else + return NULL; + } else { + StoreInst *SI = cast(P); + if (SI->hasPtrProvenanceOperand()) + return wrap(SI->getPtrProvenanceOperand()); + else + return NULL; + } +} + +void LLVMExperimentalSetPtrProvenanceOperand(LLVMValueRef LoadOrStoreInst, + LLVMValueRef PtrProvenance) { + Value *P = unwrap(LoadOrStoreInst); + if (LoadInst *LI = dyn_cast(P)) { + if (PtrProvenance) + LI->setPtrProvenanceOperand(unwrap(PtrProvenance)); + else if (LI->hasPtrProvenanceOperand()) + LI->removePtrProvenanceOperand(); + } else { + StoreInst *SI = cast(P); + if (PtrProvenance) + SI->setPtrProvenanceOperand(unwrap(PtrProvenance)); + else if (SI->hasPtrProvenanceOperand()) + SI->removePtrProvenanceOperand(); + } +} + /*--.. Casts ...............................................................--*/ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, Index: llvm/test/Bindings/llvm-c/echo.ll =================================================================== --- llvm/test/Bindings/llvm-c/echo.ll +++ llvm/test/Bindings/llvm-c/echo.ll @@ -156,6 +156,10 @@ %g = cmpxchg i8* %ptr, i8 1, i8 2 seq_cst acquire, align 1 %h = cmpxchg weak i8* %ptr, i8 1, i8 2 seq_cst acquire, align 8 %i = cmpxchg volatile i8* %ptr, i8 1, i8 2 monotonic monotonic, align 16 + %j = load i8, i8* %ptr, ptr_provenance i8* %ptr + %k = load i8, i8* %ptr, ptr_provenance i8* unknown_provenance + store i8 0, i8* %ptr, ptr_provenance i8* %ptr + store i8 1, i8* %ptr, ptr_provenance i8* unknown_provenance ret void } Index: llvm/tools/llvm-c-test/echo.cpp =================================================================== --- llvm/tools/llvm-c-test/echo.cpp +++ llvm/tools/llvm-c-test/echo.cpp @@ -646,6 +646,8 @@ LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); LLVMSetOrdering(Dst, LLVMGetOrdering(Src)); LLVMSetVolatile(Dst, LLVMGetVolatile(Src)); + if (LLVMValueRef PtrProv = LLVMExperimentalGetPtrProvenanceOperand(Src)) + LLVMExperimentalSetPtrProvenanceOperand(Dst, CloneValue(PtrProv)); break; } case LLVMStore: { @@ -655,6 +657,8 @@ LLVMSetAlignment(Dst, LLVMGetAlignment(Src)); LLVMSetOrdering(Dst, LLVMGetOrdering(Src)); LLVMSetVolatile(Dst, LLVMGetVolatile(Src)); + if (LLVMValueRef PtrProv = LLVMExperimentalGetPtrProvenanceOperand(Src)) + LLVMExperimentalSetPtrProvenanceOperand(Dst, CloneValue(PtrProv)); break; } case LLVMGetElementPtr: {