[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