Index: llvm/lib/CodeGen/IntrinsicLowering.cpp =================================================================== --- llvm/lib/CodeGen/IntrinsicLowering.cpp +++ llvm/lib/CodeGen/IntrinsicLowering.cpp @@ -333,6 +333,11 @@ case Intrinsic::var_annotation: break; // Strip out these intrinsics + case Intrinsic::experimental_ptr_provenance: + // Drop the provenance, but forward the value + CI->replaceAllUsesWith(CI->getOperand(0)); + break; + case Intrinsic::memcpy: { Type *IntPtr = DL.getIntPtrType(Context); Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4164,6 +4164,7 @@ SmallVector Chains(std::min(MaxParallelChains, NumValues)); EVT PtrVT = Ptr.getValueType(); + const auto *PtrProvenance = I.getOptionalPtrProvenance().value_or(nullptr); unsigned ChainI = 0; for (unsigned i = 0; i != NumValues; ++i, ++ChainI) { // Serializing loads here may result in excessive register pressure, and @@ -4184,9 +4185,10 @@ DAG.getConstant(Offsets[i], dl, PtrVT), Flags); - SDValue L = DAG.getLoad(MemVTs[i], dl, Root, A, - MachinePointerInfo(SV, Offsets[i]), Alignment, - MMOFlags, AAInfo, Ranges); + SDValue L = + DAG.getLoad(MemVTs[i], dl, Root, A, + MachinePointerInfo(SV, Offsets[i], 0, PtrProvenance), + Alignment, MMOFlags, AAInfo, Ranges); Chains[ChainI] = L.getValue(1); if (MemVTs[i] != ValueVTs[i]) @@ -4313,6 +4315,7 @@ SDNodeFlags Flags; Flags.setNoUnsignedWrap(true); + const auto *PtrProvenance = I.getOptionalPtrProvenance().value_or(nullptr); unsigned ChainI = 0; for (unsigned i = 0; i != NumValues; ++i, ++ChainI) { // See visitLoad comments. @@ -4328,7 +4331,8 @@ if (MemVTs[i] != ValueVTs[i]) Val = DAG.getPtrExtOrTrunc(Val, dl, MemVTs[i]); SDValue St = - DAG.getStore(Root, dl, Val, Add, MachinePointerInfo(PtrV, Offsets[i]), + DAG.getStore(Root, dl, Val, Add, + MachinePointerInfo(PtrV, Offsets[i], 0, PtrProvenance), Alignment, MMOFlags, AAInfo); Chains[ChainI] = St; } @@ -6764,6 +6768,7 @@ case Intrinsic::ptr_annotation: case Intrinsic::launder_invariant_group: case Intrinsic::strip_invariant_group: + case Intrinsic::experimental_ptr_provenance: // Drop the intrinsic, but forward the value setValue(&I, getValue(I.getOperand(0))); return; Index: llvm/test/CodeGen/Generic/ptr_provenance.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/Generic/ptr_provenance.ll @@ -0,0 +1,8 @@ +; RUN: llc < %s + +define i32* @test(i32* %p, i32* %p.provenance) { + %p.joined = call i32* @llvm.experimental.ptr.provenance.p0i32.p0i32(i32* %p, i32* %p.provenance) + ret i32* %p.joined +} + +declare i32* @llvm.experimental.ptr.provenance.p0i32.p0i32(i32*, i32*) nounwind readnone