[PATCH] D107355: [ptr_provenance] Introduce llvm.experimental.ptr.provenance

Jeroen Dobbelaere via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 3 07:52:16 PDT 2021


jeroen.dobbelaere created this revision.
jeroen.dobbelaere added reviewers: jdoerfert, nikic.
Herald added a subscriber: hiraditya.
jeroen.dobbelaere requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The llvm.experimental.ptr.provenance intrinsics combines a pointer value (=operand 0) with a pointer provenance (= operand 1).
This intrinsic is provided so that the provenance can be tracked when a pointer (with provenance) is returned, passed to a function, stored into memory.

When loading and storing through such a pointer, the intrinsic can be omited and the operand 1 can be connected to the ptr_provenance operand of the load/store instructions.


https://reviews.llvm.org/D107355

Files:
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/IR/IRBuilder.cpp
  llvm/unittests/IR/IRBuilderTest.cpp


Index: llvm/unittests/IR/IRBuilderTest.cpp
===================================================================
--- llvm/unittests/IR/IRBuilderTest.cpp
+++ llvm/unittests/IR/IRBuilderTest.cpp
@@ -432,6 +432,18 @@
   EXPECT_EQ(S->getPtrProvenance(), GV);
 }
 
+TEST_F(IRBuilderTest, PtrProvenanceIntrinsics) {
+  IRBuilder<> Builder(BB);
+  auto *A = Builder.CreateAlloca(GV->getValueType());
+
+  auto *PP = Builder.CreatePtrProvenance(GV, A);
+  IntrinsicInst *II_PP = dyn_cast<IntrinsicInst>(PP);
+  ASSERT_TRUE(II_PP != nullptr);
+  EXPECT_EQ(II_PP->getIntrinsicID(), Intrinsic::experimental_ptr_provenance);
+  EXPECT_EQ(PP->getOperand(0), GV);
+  EXPECT_EQ(PP->getOperand(1), A);
+}
+
 TEST_F(IRBuilderTest, Lifetime) {
   IRBuilder<> Builder(BB);
   AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
Index: llvm/lib/IR/IRBuilder.cpp
===================================================================
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -492,6 +492,17 @@
   return createCallHelper(FnIntrinsic, {Scope}, this);
 }
 
+Instruction *IRBuilderBase::CreatePtrProvenance(Value *PtrValue,
+                                                Value *PtrProvenance) {
+  assert(PtrValue->getType() == PtrProvenance->getType() &&
+         "pointer and provenance must have the same type");
+  Module *M = BB->getModule();
+  auto *FnIntrinsic =
+      Intrinsic::getDeclaration(M, Intrinsic::experimental_ptr_provenance,
+                                {PtrValue->getType(), PtrValue->getType()});
+  return createCallHelper(FnIntrinsic, {PtrValue, PtrProvenance}, this);
+}
+
 /// Create a call to a Masked Load intrinsic.
 /// \p Ty        - vector type to load
 /// \p Ptr       - base pointer for the load
Index: llvm/include/llvm/IR/Intrinsics.td
===================================================================
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -571,6 +571,22 @@
     : DefaultAttrsIntrinsic<[], [llvm_metadata_ty],
         [IntrInaccessibleMemOnly]>; // blocks LICM and some more
 
+// 'llvm.experimental.ptr.provenance' intrinsic: Associates a (different)
+// ptr_provenance path to the pointer value. This serves as a guard for pointers
+// that escape through function arguments, through memory or are returned.
+// For Load/Store instructions, there is a separate ptr_provenance operand for
+// tracking the provenance of the pointer operand.
+//
+// Purpose of the different arguments:
+// - arg0: p.val: the incoming pointer value.
+// - arg1: p.prov: the ptr_provenance, associated with this pointer
+//         computation.
+// - returns: arg0 (hidden for most optimization passes)
+def int_experimental_ptr_provenance
+    : DefaultAttrsIntrinsic<[llvm_anyptr_ty],
+                [LLVMMatchType<0>, llvm_anyptr_ty],
+                [IntrNoMem, IntrSpeculatable]>; // NOTE: Returned<0> must not be used here
+
 // Stack Protector Intrinsic - The stackprotector intrinsic writes the stack
 // guard to the correct place on the stack frame.
 def int_stackprotector : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
Index: llvm/include/llvm/IR/IRBuilder.h
===================================================================
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -783,6 +783,9 @@
         MetadataAsValue::get(Context, ScopeTag));
   }
 
+  /// Create a llvm.experimental.ptr.provenance intrinsic call.
+  Instruction *CreatePtrProvenance(Value *PtrValue, Value *PtrProvenance);
+
   /// Create a call to the experimental.gc.statepoint intrinsic to
   /// start a new statepoint sequence.
   CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107355.363741.patch
Type: text/x-patch
Size: 3712 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210803/cf8cc177/attachment.bin>


More information about the llvm-commits mailing list