[llvm] [AMDGPU][Verifier] Allow llvm.amdgcn.unreachable after cs.chain (PR #139494)

Carl Ritson via llvm-commits llvm-commits at lists.llvm.org
Sun May 11 21:26:03 PDT 2025


https://github.com/perlfu created https://github.com/llvm/llvm-project/pull/139494

Unreachable is transformed to llvm.amdgcn.unreachable() during exit unification.  Make sure the verifier tolerates this.

>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] [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 }
+



More information about the llvm-commits mailing list