[llvm] [AMDGPU][Verifier] Allow llvm.amdgcn.unreachable after cs.chain (PR #139494)
Carl Ritson via llvm-commits
llvm-commits at lists.llvm.org
Mon May 12 01:47:17 PDT 2025
https://github.com/perlfu updated https://github.com/llvm/llvm-project/pull/139494
>From 4ffa31aa24bf5a7f7946605f8f8740dd1d18076e Mon Sep 17 00:00:00 2001
From: Carl Ritson <carl.ritson at amd.com>
Date: Mon, 12 May 2025 13:12:41 +0900
Subject: [PATCH 1/4] [AMDGPU][Verifier] Allow llvm.amdgcn.unreachable after
cs.chain
Unreachable is transformed to llvm.amdgcn.unreachable() during
exit unification. Make sure the verifier tolerates this.
---
llvm/lib/IR/Verifier.cpp | 7 +++-
.../AMDGPU/unreachable-after-cs-chain.ll | 38 +++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 83c1264aef12b..9f67ba272c298 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6417,7 +6417,12 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"SGPR arguments must have the `inreg` attribute", &Call);
Check(!Call.paramHasAttr(3, Attribute::InReg),
"VGPR arguments must not have the `inreg` attribute", &Call);
- Check(isa_and_present<UnreachableInst>(Call.getNextNode()),
+
+ auto *Next = Call.getNextNode();
+ bool IsAMDUnreachable = isa<IntrinsicInst>(Next) &&
+ cast<IntrinsicInst>(Next)->getIntrinsicID() ==
+ Intrinsic::amdgcn_unreachable;
+ Check(Next && (isa<UnreachableInst>(Next) || IsAMDUnreachable),
"llvm.amdgcn.cs.chain must be followed by unreachable", &Call);
break;
}
diff --git a/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll b/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
new file mode 100644
index 0000000000000..a71bbe5a8f530
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -mtriple=amdgcn--amdpal -mcpu=gfx1200 -verify -amdgpu-unify-divergent-exit-nodes -verify -S %s -o - | FileCheck %s
+
+; Check @llvm.amdgcn.unreachable is a valid alternative to unreachable after @llvm.amdgcn.cs.chain
+
+declare amdgpu_cs_chain void @callee() #0
+
+define amdgpu_cs_chain void @test_unreachable(i32 %val) {
+; CHECK-LABEL: define amdgpu_cs_chain void @test_unreachable(
+; CHECK-SAME: i32 [[VAL:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[TAIL_BLOCK:.*:]]
+; CHECK-NEXT: [[DOTCOND:%.*]] = icmp ne i32 [[VAL]], 0
+; CHECK-NEXT: br i1 [[DOTCOND]], label %[[CHAIN_BLOCK:.*]], label %[[UNIFIEDRETURNBLOCK:.*]]
+; CHECK: [[CHAIN_BLOCK]]:
+; CHECK-NEXT: call void (ptr, i64, i32, i32, i32, ...) @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr @callee, i64 -1, i32 inreg 1, i32 2, i32 1, i32 inreg 32, i32 inreg -1, ptr @callee)
+; CHECK-NEXT: call void @llvm.amdgcn.unreachable()
+; CHECK-NEXT: br label %[[UNIFIEDRETURNBLOCK]]
+; CHECK: [[UNIFIEDRETURNBLOCK]]:
+; CHECK-NEXT: ret void
+;
+tail.block:
+ %.cond = icmp ne i32 %val, 0
+ br i1 %.cond, label %chain.block, label %ret.block
+
+chain.block:
+ call void(ptr, i64, i32, i32, i32, ...) @llvm.amdgcn.cs.chain(ptr @callee, i64 -1, i32 inreg 1, i32 2, i32 1, i32 inreg 32, i32 inreg -1, ptr @callee)
+ unreachable
+
+ret.block:
+ ret void
+}
+
+; Function Attrs: convergent noreturn nounwind
+declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { convergent noreturn nounwind }
+
>From c411015f0e7b7d74e33d5313c2e8811f3abd8251 Mon Sep 17 00:00:00 2001
From: Carl Ritson <carl.ritson at amd.com>
Date: Mon, 12 May 2025 14:17:10 +0900
Subject: [PATCH 2/4] - Tidy test attributes
---
llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll b/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
index a71bbe5a8f530..2c7705311cf57 100644
--- a/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
+++ b/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
@@ -3,7 +3,7 @@
; Check @llvm.amdgcn.unreachable is a valid alternative to unreachable after @llvm.amdgcn.cs.chain
-declare amdgpu_cs_chain void @callee() #0
+declare amdgpu_cs_chain void @callee() nounwind
define amdgpu_cs_chain void @test_unreachable(i32 %val) {
; CHECK-LABEL: define amdgpu_cs_chain void @test_unreachable(
@@ -30,9 +30,5 @@ ret.block:
ret void
}
-; Function Attrs: convergent noreturn nounwind
-declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...) #1
-
-attributes #0 = { nounwind }
-attributes #1 = { convergent noreturn nounwind }
+declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...)
>From 3393a3c39fe9a497ba953f7545ececbacc29f73d Mon Sep 17 00:00:00 2001
From: Carl Ritson <carl.ritson at amd.com>
Date: Mon, 12 May 2025 15:48:52 +0900
Subject: [PATCH 3/4] - Move test
---
.../AMDGPU/unreachable-after-cs-chain.ll | 34 -------------------
.../AMDGPU/unreachable-after-cs-chain.ll | 21 ++++++++++++
2 files changed, 21 insertions(+), 34 deletions(-)
delete mode 100644 llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
create mode 100644 llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll
diff --git a/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll b/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
deleted file mode 100644
index 2c7705311cf57..0000000000000
--- a/llvm/test/CodeGen/AMDGPU/unreachable-after-cs-chain.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -mtriple=amdgcn--amdpal -mcpu=gfx1200 -verify -amdgpu-unify-divergent-exit-nodes -verify -S %s -o - | FileCheck %s
-
-; Check @llvm.amdgcn.unreachable is a valid alternative to unreachable after @llvm.amdgcn.cs.chain
-
-declare amdgpu_cs_chain void @callee() nounwind
-
-define amdgpu_cs_chain void @test_unreachable(i32 %val) {
-; CHECK-LABEL: define amdgpu_cs_chain void @test_unreachable(
-; CHECK-SAME: i32 [[VAL:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT: [[TAIL_BLOCK:.*:]]
-; CHECK-NEXT: [[DOTCOND:%.*]] = icmp ne i32 [[VAL]], 0
-; CHECK-NEXT: br i1 [[DOTCOND]], label %[[CHAIN_BLOCK:.*]], label %[[UNIFIEDRETURNBLOCK:.*]]
-; CHECK: [[CHAIN_BLOCK]]:
-; CHECK-NEXT: call void (ptr, i64, i32, i32, i32, ...) @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr @callee, i64 -1, i32 inreg 1, i32 2, i32 1, i32 inreg 32, i32 inreg -1, ptr @callee)
-; CHECK-NEXT: call void @llvm.amdgcn.unreachable()
-; CHECK-NEXT: br label %[[UNIFIEDRETURNBLOCK]]
-; CHECK: [[UNIFIEDRETURNBLOCK]]:
-; CHECK-NEXT: ret void
-;
-tail.block:
- %.cond = icmp ne i32 %val, 0
- br i1 %.cond, label %chain.block, label %ret.block
-
-chain.block:
- call void(ptr, i64, i32, i32, i32, ...) @llvm.amdgcn.cs.chain(ptr @callee, i64 -1, i32 inreg 1, i32 2, i32 1, i32 inreg 32, i32 inreg -1, ptr @callee)
- unreachable
-
-ret.block:
- ret void
-}
-
-declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...)
-
diff --git a/llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll b/llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll
new file mode 100644
index 0000000000000..0c5c856158963
--- /dev/null
+++ b/llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll
@@ -0,0 +1,21 @@
+; RUN: llvm-as %s --disable-output
+
+; Check @llvm.amdgcn.unreachable is a valid alternative to unreachable after @llvm.amdgcn.cs.chain
+
+declare amdgpu_cs_chain void @callee() nounwind
+declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...)
+declare void @llvm.amdgcn.unreachable()
+
+define amdgpu_cs_chain void @test_unreachable(i32 %val) {
+tail.block:
+ %.cond = icmp ne i32 %val, 0
+ br i1 %.cond, label %chain.block, label %UnifiedReturnBlock
+
+chain.block:
+ call void (ptr, i64, i32, i32, i32, ...) @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr @callee, i64 -1, i32 inreg 1, i32 2, i32 1, i32 inreg 32, i32 inreg -1, ptr @callee)
+ call void @llvm.amdgcn.unreachable()
+ br label %UnifiedReturnBlock
+
+UnifiedReturnBlock:
+ ret void
+}
>From 7d46fa4bc9fd4bf19f0691470622f3fbeb11915b Mon Sep 17 00:00:00 2001
From: Carl Ritson <carl.ritson at amd.com>
Date: Mon, 12 May 2025 17:46:09 +0900
Subject: [PATCH 4/4] - Address reviewer comments
---
llvm/lib/IR/Verifier.cpp | 2 +-
.../amdgcn-unreachable.ll} | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
rename llvm/test/{Verifier/AMDGPU/unreachable-after-cs-chain.ll => Assembler/amdgcn-unreachable.ll} (69%)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 9f67ba272c298..08224d7f54c02 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6419,7 +6419,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"VGPR arguments must not have the `inreg` attribute", &Call);
auto *Next = Call.getNextNode();
- bool IsAMDUnreachable = isa<IntrinsicInst>(Next) &&
+ bool IsAMDUnreachable = Next && isa<IntrinsicInst>(Next) &&
cast<IntrinsicInst>(Next)->getIntrinsicID() ==
Intrinsic::amdgcn_unreachable;
Check(Next && (isa<UnreachableInst>(Next) || IsAMDUnreachable),
diff --git a/llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll b/llvm/test/Assembler/amdgcn-unreachable.ll
similarity index 69%
rename from llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll
rename to llvm/test/Assembler/amdgcn-unreachable.ll
index 0c5c856158963..14af62f45f74c 100644
--- a/llvm/test/Verifier/AMDGPU/unreachable-after-cs-chain.ll
+++ b/llvm/test/Assembler/amdgcn-unreachable.ll
@@ -1,12 +1,12 @@
-; RUN: llvm-as %s --disable-output
-
-; Check @llvm.amdgcn.unreachable is a valid alternative to unreachable after @llvm.amdgcn.cs.chain
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
declare amdgpu_cs_chain void @callee() nounwind
declare void @llvm.amdgcn.cs.chain.p0.i64.i32.i32(ptr, i64, i32, i32, i32 immarg, ...)
declare void @llvm.amdgcn.unreachable()
-define amdgpu_cs_chain void @test_unreachable(i32 %val) {
+; @llvm.amdgcn.unreachable is legal after @llvm.amdgcn.cs.chain
+; CHECK: define amdgpu_cs_chain void @test_cc_chain_unreachable(i32 %val)
+define amdgpu_cs_chain void @test_cc_chain_unreachable(i32 %val) {
tail.block:
%.cond = icmp ne i32 %val, 0
br i1 %.cond, label %chain.block, label %UnifiedReturnBlock
More information about the llvm-commits
mailing list