[llvm] [AMDGPU] Add verification for amdgcn.init.exec.from.input (PR #128172)
Robert Imschweiler via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 21 12:01:30 PST 2025
https://github.com/ro-i updated https://github.com/llvm/llvm-project/pull/128172
>From dda8be4f0c7229d670e7e5e3058b28d7eebfc59a Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 21 Feb 2025 07:05:04 -0600
Subject: [PATCH 1/5] [AMDGPU] Add verification for amdgcn.init.exec.from.input
Check that the input register is an inreg argument to the parent
function. (See the comment in `IntrinsicsAMDGPU.td`.)
This LLVM defect was identified via the AMD Fuzzing project.
---
llvm/lib/IR/Verifier.cpp | 15 +++++++++++
.../intrinsic-amdgpu-init-exec-from-input.ll | 27 +++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644 llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 8432779c107de..55923fd56a109 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6369,6 +6369,21 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"VGPR arguments must not have the `inreg` attribute", &Call);
break;
}
+ case Intrinsic::amdgcn_init_exec_from_input: {
+ const Value *InputVal = Call.getOperand(0);
+ bool InRegArgFound = false;
+ for (const Argument &Arg : Call.getCaller()->args()) {
+ if (Arg.hasInRegAttr() && &Arg == InputVal) {
+ InRegArgFound = true;
+ break;
+ }
+ }
+ Check(InRegArgFound,
+ "only inreg arguments to the parent function are valid as inputs to "
+ "this intrinsic",
+ &Call);
+ break;
+ }
case Intrinsic::amdgcn_set_inactive_chain_arg: {
auto CallerCC = Call.getCaller()->getCallingConv();
switch (CallerCC) {
diff --git a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
new file mode 100644
index 0000000000000..5e4a6638dc170
--- /dev/null
+++ b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
@@ -0,0 +1,27 @@
+; RUN: sed -e '/^; MARK$/,$d' %s | not llc -mtriple=amdgcn -mcpu=gfx942 2>&1 | FileCheck %s
+; RUN: sed -e '1,/^; MARK$/d' %s | llc -mtriple=amdgcn -mcpu=gfx942 -filetype=null
+
+; Function Attrs: convergent nocallback nofree nounwind willreturn
+declare void @llvm.amdgcn.init.exec.from.input(i32, i32 immarg) #0
+attributes #0 = { convergent nocallback nofree nounwind willreturn }
+
+; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
+; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 0, i32 0)
+define amdgpu_ps void @init_exec_from_input_fail_immarg(i32 inreg %a, i32 %b) {
+ call void @llvm.amdgcn.init.exec.from.input(i32 0, i32 0)
+ ret void
+}
+
+; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
+; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
+define amdgpu_ps void @init_exec_from_input_fail_not_inreg(i32 inreg %a, i32 %b) {
+ call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
+ ret void
+}
+
+; MARK
+
+define amdgpu_ps void @init_exec_from_input_success(i32 inreg %a, i32 %b) {
+ call void @llvm.amdgcn.init.exec.from.input(i32 %a, i32 0)
+ ret void
+}
>From c6f3b88f44f1c364282b8836c09f12ebf8dbe7c7 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 21 Feb 2025 08:42:07 -0600
Subject: [PATCH 2/5] implement feedback
---
llvm/lib/IR/Verifier.cpp | 11 ++---------
.../AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll | 10 +---------
2 files changed, 3 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 55923fd56a109..a19de550d092a 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6370,15 +6370,8 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
break;
}
case Intrinsic::amdgcn_init_exec_from_input: {
- const Value *InputVal = Call.getOperand(0);
- bool InRegArgFound = false;
- for (const Argument &Arg : Call.getCaller()->args()) {
- if (Arg.hasInRegAttr() && &Arg == InputVal) {
- InRegArgFound = true;
- break;
- }
- }
- Check(InRegArgFound,
+ const Argument *Arg = dyn_cast<Argument>(Call.getOperand(0));
+ Check(Arg && Arg->hasInRegAttr(),
"only inreg arguments to the parent function are valid as inputs to "
"this intrinsic",
&Call);
diff --git a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
index 5e4a6638dc170..cea12cdae9498 100644
--- a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
+++ b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
@@ -1,5 +1,4 @@
-; RUN: sed -e '/^; MARK$/,$d' %s | not llc -mtriple=amdgcn -mcpu=gfx942 2>&1 | FileCheck %s
-; RUN: sed -e '1,/^; MARK$/d' %s | llc -mtriple=amdgcn -mcpu=gfx942 -filetype=null
+; RUN: not llvm-as -o /dev/null 2>&1 %s | FileCheck %s
; Function Attrs: convergent nocallback nofree nounwind willreturn
declare void @llvm.amdgcn.init.exec.from.input(i32, i32 immarg) #0
@@ -18,10 +17,3 @@ define amdgpu_ps void @init_exec_from_input_fail_not_inreg(i32 inreg %a, i32 %b)
call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
ret void
}
-
-; MARK
-
-define amdgpu_ps void @init_exec_from_input_success(i32 inreg %a, i32 %b) {
- call void @llvm.amdgcn.init.exec.from.input(i32 %a, i32 0)
- ret void
-}
>From aa34d1e661c27af2d293ab7609f246279d054be9 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 21 Feb 2025 09:17:06 -0600
Subject: [PATCH 3/5] implement feedback
---
.../AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
index cea12cdae9498..cd2773d68e936 100644
--- a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
+++ b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
@@ -1,4 +1,4 @@
-; RUN: not llvm-as -o /dev/null 2>&1 %s | FileCheck %s
+; RUN: not llvm-as -disable-output 2>&1 %s | FileCheck %s
; Function Attrs: convergent nocallback nofree nounwind willreturn
declare void @llvm.amdgcn.init.exec.from.input(i32, i32 immarg) #0
@@ -17,3 +17,11 @@ define amdgpu_ps void @init_exec_from_input_fail_not_inreg(i32 inreg %a, i32 %b)
call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
ret void
}
+
+; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
+; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 %c, i32 0)
+define amdgpu_ps void @init_exec_from_input_fail_constant(i32 inreg %a, i32 %b) {
+ %c = add i32 %a, %b
+ call void @llvm.amdgcn.init.exec.from.input(i32 %c, i32 0)
+ ret void
+}
>From 7d2779ee3af41c36238d315bcccfd5800b85fa62 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 21 Feb 2025 09:34:20 -0600
Subject: [PATCH 4/5] implement feedback
---
.../AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
index cd2773d68e936..3a619f6ea13af 100644
--- a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
+++ b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
@@ -6,21 +6,21 @@ attributes #0 = { convergent nocallback nofree nounwind willreturn }
; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 0, i32 0)
-define amdgpu_ps void @init_exec_from_input_fail_immarg(i32 inreg %a, i32 %b) {
+define void @init_exec_from_input_fail_immarg(i32 inreg %a, i32 %b) {
call void @llvm.amdgcn.init.exec.from.input(i32 0, i32 0)
ret void
}
; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
-define amdgpu_ps void @init_exec_from_input_fail_not_inreg(i32 inreg %a, i32 %b) {
+define void @init_exec_from_input_fail_not_inreg(i32 inreg %a, i32 %b) {
call void @llvm.amdgcn.init.exec.from.input(i32 %b, i32 0)
ret void
}
; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 %c, i32 0)
-define amdgpu_ps void @init_exec_from_input_fail_constant(i32 inreg %a, i32 %b) {
+define void @init_exec_from_input_fail_constant(i32 inreg %a, i32 %b) {
%c = add i32 %a, %b
call void @llvm.amdgcn.init.exec.from.input(i32 %c, i32 0)
ret void
>From f291bc6a35181ff176296af81aa2ef6949e69977 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 21 Feb 2025 14:01:15 -0600
Subject: [PATCH 5/5] implement feedback
---
.../Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
index 3a619f6ea13af..0c35ed13a5a15 100644
--- a/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
+++ b/llvm/test/Verifier/AMDGPU/intrinsic-amdgpu-init-exec-from-input.ll
@@ -1,8 +1,6 @@
; RUN: not llvm-as -disable-output 2>&1 %s | FileCheck %s
-; Function Attrs: convergent nocallback nofree nounwind willreturn
-declare void @llvm.amdgcn.init.exec.from.input(i32, i32 immarg) #0
-attributes #0 = { convergent nocallback nofree nounwind willreturn }
+declare void @llvm.amdgcn.init.exec.from.input(i32, i32 immarg)
; CHECK: only inreg arguments to the parent function are valid as inputs to this intrinsic
; CHECK-NEXT: call void @llvm.amdgcn.init.exec.from.input(i32 0, i32 0)
More information about the llvm-commits
mailing list