[llvm] [Instrumentor] Ignore amdgcn intrinsics (PR #216205)

Vincent Arcila via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 15:50:47 PDT 2026


https://github.com/jandrovins updated https://github.com/llvm/llvm-project/pull/216205

>From 54ec2b1a49eeb3cd6397d096f563076a3f73176e Mon Sep 17 00:00:00 2001
From: "Vincent A. Arcila Larrea" <arcilalarrea1 at llnl.gov>
Date: Thu, 23 Jul 2026 18:20:21 -0700
Subject: [PATCH 1/4] [Instrumentor] Avoid instrumenting load/store pointers
 from AMDGCN intrinsics

---
 llvm/lib/Transforms/IPO/Instrumentor.cpp | 42 ++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp
index bfa22199ef9f6..68c26ed9cd2e1 100644
--- a/llvm/lib/Transforms/IPO/Instrumentor.cpp
+++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp
@@ -1208,6 +1208,38 @@ Value *AllocaIO::getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
 }
 ///}
 
+// Check if a pointer comes from an intrinsic function and is one of the AMD GCN intrinsics we avoid when instrumenting
+static bool ptrOriginatesFromAMDGCNIntrinsic(llvm::Value *PtrArg) {
+  llvm::errs() << "checking if should instrument a pointer...";
+  SmallVector<const llvm::Value *, 4> Objs;
+  llvm::getUnderlyingObjects(PtrArg, Objs, nullptr, 20);
+  assert(!Objs.empty() && "How can a pointer have no underlying objects?");
+
+  auto IsAMDGCNObj = [](const llvm::Value *Obj) {
+    if (auto *II = llvm::dyn_cast<llvm::IntrinsicInst>(Obj))
+      if (llvm::Function *CalledFunc = II->getCalledFunction())
+        return CalledFunc->getName().contains("amdgcn");
+    return false;
+  };
+
+  bool SawAMDGCN = false;
+  bool SawNonAMDGCN = false;
+  for (const llvm::Value *Obj : Objs) {
+    if (IsAMDGCNObj(Obj))
+      SawAMDGCN = true;
+    else
+      SawNonAMDGCN = true;
+  }
+
+  assert(!(SawAMDGCN && SawNonAMDGCN) &&
+         "Mixed underlying objects: either all underlying objects must contain "
+         "'amdgcn' or none of them may contain it");
+
+  bool ShouldInstrument = !SawAMDGCN;
+  llvm::errs() << "shouldInstrument =" << ShouldInstrument << "\n";
+  return ShouldInstrument;
+}
+
 void StoreIO::init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
                    ConfigTy *UserConfig) {
   if (UserConfig)
@@ -1278,6 +1310,11 @@ void StoreIO::init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
 
   addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
   IConf.addChoice(*this, IIRB.Ctx);
+
+  CB = [&](Value &V) -> bool {
+    Value *Ptr = cast<StoreInst>(V).getPointerOperand();
+    return ptrOriginatesFromAMDGCNIntrinsic(Ptr);
+  };
 }
 
 Value *StoreIO::getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf,
@@ -1428,6 +1465,11 @@ void LoadIO::init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
 
   addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
   IConf.addChoice(*this, IIRB.Ctx);
+
+  CB = [&](Value &V) -> bool {
+    Value *Ptr = cast<LoadInst>(V).getPointerOperand();
+    return ptrOriginatesFromAMDGCNIntrinsic(Ptr);
+  };
 }
 
 Value *LoadIO::getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf,

>From a783f7ae6613e7d70d101e16b1e023106143dfb0 Mon Sep 17 00:00:00 2001
From: "Vincent A. Arcila Larrea" <arcilalarrea1 at llnl.gov>
Date: Thu, 13 Aug 2026 15:38:08 -0700
Subject: [PATCH 2/4] [Instrumentor] Add AMDGCN intrinsic ignore test

---
 .../load_store_ignore_amdgcn_intrinsics.ll    | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 llvm/test/Instrumentation/Instrumentor/load_store_ignore_amdgcn_intrinsics.ll

diff --git a/llvm/test/Instrumentation/Instrumentor/load_store_ignore_amdgcn_intrinsics.ll b/llvm/test/Instrumentation/Instrumentor/load_store_ignore_amdgcn_intrinsics.ll
new file mode 100644
index 0000000000000..c974fdcde902a
--- /dev/null
+++ b/llvm/test/Instrumentation/Instrumentor/load_store_ignore_amdgcn_intrinsics.ll
@@ -0,0 +1,47 @@
+; REQUIRES: amdgpu-registered-target
+; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/load_store_config.json -S | FileCheck %s
+
+target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
+target triple = "amdgcn-amd-amdhsa"
+
+declare noundef nonnull align 4 dereferenceable(64) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
+
+define void @instrument_regular_pointer(ptr %dst, ptr %src) {
+; CHECK-LABEL: define void @instrument_regular_pointer(
+; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRC:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SRC_PRE:%.*]] = call ptr @__instrumentor_pre_load(ptr [[SRC]], i32 0, i64 4, i64 4, i32 12, i32 0, i8 1, i8 0)
+; CHECK-NEXT: [[SRC_VAL:%.*]] = load i32, ptr [[SRC_PRE]], align 4
+; CHECK-NEXT: [[SRC_VAL_ZEXT:%.*]] = zext i32 [[SRC_VAL]] to i64
+; CHECK-NEXT: [[SRC_POST:%.*]] = call i64 @__instrumentor_post_load(ptr [[SRC]], i32 0, i64 [[SRC_VAL_ZEXT]], i64 4, i64 4, i32 12, i32 0, i8 1, i8 0)
+; CHECK-NEXT: [[STORE_VAL:%.*]] = trunc i64 [[SRC_POST]] to i32
+; CHECK-NEXT: [[STORE_VAL_ZEXT:%.*]] = zext i32 [[STORE_VAL]] to i64
+; CHECK-NEXT: [[DST_PRE:%.*]] = call ptr @__instrumentor_pre_store(ptr [[DST]], i32 0, i64 [[STORE_VAL_ZEXT]], i64 4, i64 4, i32 12, i32 0, i8 1, i8 0)
+; CHECK-NEXT: store i32 [[STORE_VAL]], ptr [[DST_PRE]], align 4
+; CHECK-NEXT: call void @__instrumentor_post_store(ptr [[DST]], i32 0, i64 [[STORE_VAL_ZEXT]], i64 4, i64 4, i32 12, i32 0, i8 1, i8 0)
+; CHECK-NEXT: ret void
+entry:
+  %value = load i32, ptr %src, align 4
+  store i32 %value, ptr %dst, align 4
+  ret void
+}
+
+define void @ignore_intrinsic_pointer() {
+; CHECK-LABEL: define void @ignore_intrinsic_pointer() {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[DISPATCH:%.*]] = call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
+; CHECK-NEXT: [[GENERIC:%.*]] = addrspacecast ptr addrspace(4) [[DISPATCH]] to ptr
+; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds i8, ptr [[GENERIC]], i64 16
+; CHECK-NEXT: [[VALUE:%.*]] = load i32, ptr [[SRC]], align 4
+; CHECK-NEXT: [[DST:%.*]] = getelementptr inbounds i8, ptr [[GENERIC]], i64 20
+; CHECK-NEXT: store i32 [[VALUE]], ptr [[DST]], align 4
+; CHECK-NEXT: ret void
+entry:
+  %dispatch = call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
+  %generic = addrspacecast ptr addrspace(4) %dispatch to ptr
+  %src = getelementptr inbounds i8, ptr %generic, i64 16
+  %value = load i32, ptr %src, align 4
+  %dst = getelementptr inbounds i8, ptr %generic, i64 20
+  store i32 %value, ptr %dst, align 4
+  ret void
+}

>From bc6176cf5368eaf5abd81544a449f4d01cd97a3e Mon Sep 17 00:00:00 2001
From: "Vincent A. Arcila Larrea" <arcilalarrea1 at llnl.gov>
Date: Thu, 13 Aug 2026 15:40:02 -0700
Subject: [PATCH 3/4] Remove prints

---
 llvm/lib/Transforms/IPO/Instrumentor.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp
index 68c26ed9cd2e1..1f30cd4c3d331 100644
--- a/llvm/lib/Transforms/IPO/Instrumentor.cpp
+++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp
@@ -1210,7 +1210,6 @@ Value *AllocaIO::getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
 
 // Check if a pointer comes from an intrinsic function and is one of the AMD GCN intrinsics we avoid when instrumenting
 static bool ptrOriginatesFromAMDGCNIntrinsic(llvm::Value *PtrArg) {
-  llvm::errs() << "checking if should instrument a pointer...";
   SmallVector<const llvm::Value *, 4> Objs;
   llvm::getUnderlyingObjects(PtrArg, Objs, nullptr, 20);
   assert(!Objs.empty() && "How can a pointer have no underlying objects?");
@@ -1236,7 +1235,6 @@ static bool ptrOriginatesFromAMDGCNIntrinsic(llvm::Value *PtrArg) {
          "'amdgcn' or none of them may contain it");
 
   bool ShouldInstrument = !SawAMDGCN;
-  llvm::errs() << "shouldInstrument =" << ShouldInstrument << "\n";
   return ShouldInstrument;
 }
 

>From 9fe357cd849038967247b1c2d2b19e8de8e4cf82 Mon Sep 17 00:00:00 2001
From: "Vincent A. Arcila Larrea" <arcilalarrea1 at llnl.gov>
Date: Thu, 13 Aug 2026 15:50:24 -0700
Subject: [PATCH 4/4] Format

---
 llvm/lib/Transforms/IPO/Instrumentor.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp
index 1f30cd4c3d331..c1e04a44f5c49 100644
--- a/llvm/lib/Transforms/IPO/Instrumentor.cpp
+++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp
@@ -1208,7 +1208,8 @@ Value *AllocaIO::getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
 }
 ///}
 
-// Check if a pointer comes from an intrinsic function and is one of the AMD GCN intrinsics we avoid when instrumenting
+// Check if a pointer comes from an intrinsic function and is one of the AMD GCN
+// intrinsics we avoid when instrumenting
 static bool ptrOriginatesFromAMDGCNIntrinsic(llvm::Value *PtrArg) {
   SmallVector<const llvm::Value *, 4> Objs;
   llvm::getUnderlyingObjects(PtrArg, Objs, nullptr, 20);



More information about the llvm-commits mailing list