[llvm] [AMDGPU] CallInst -> CallBase for divergence analysis (PR #228744)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 09:49:31 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Robert Imschweiler (ro-i)

<details>
<summary>Changes</summary>

This handles non-call instructions like callbr.

The test changes in infinite-loop.ll, where there are now two return blocks (the original one + the dummy) instead of the unified return block is a symptom of the callbr in those functions being not marked as divergent anymore.

This patch was hand-manufactured using Neovim.

---

Patch is 24.67 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/228744.diff


4 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp (+14-14) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/infinite-loop.ll (+109-91) 
- (modified) llvm/test/CodeGen/AMDGPU/si-unify-exit-multiple-unreachables.ll (+38-38) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
index 9662be4530f78..cea518cde4776 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
@@ -1306,15 +1306,15 @@ InstructionCost GCNTTIImpl::getVectorInstrCost(
 /// this is only querying a specific result index if this returns multiple
 /// registers in a struct.
 bool GCNTTIImpl::isInlineAsmSourceOfDivergence(
-  const CallInst *CI, ArrayRef<unsigned> Indices) const {
+    const CallBase *CB, ArrayRef<unsigned> Indices) const {
   // TODO: Handle complex extract indices
   if (Indices.size() > 1)
     return true;
 
-  const DataLayout &DL = CI->getDataLayout();
+  const DataLayout &DL = CB->getDataLayout();
   const SIRegisterInfo *TRI = ST->getRegisterInfo();
   TargetLowering::AsmOperandInfoVector TargetConstraints =
-      TLI->ParseConstraints(DL, ST->getRegisterInfo(), *CI);
+      TLI->ParseConstraints(DL, ST->getRegisterInfo(), *CB);
 
   const int TargetOutputIdx = Indices.empty() ? -1 : Indices[0];
 
@@ -1405,9 +1405,9 @@ bool GCNTTIImpl::isSourceOfDivergence(const Value *V) const {
   }
 
   // Assume all function calls are a source of divergence.
-  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
-    if (CI->isInlineAsm())
-      return isInlineAsmSourceOfDivergence(CI);
+  if (const CallBase *CB = dyn_cast<CallBase>(V)) {
+    if (CB->isInlineAsm())
+      return isInlineAsmSourceOfDivergence(CB);
     return true;
   }
 
@@ -1431,9 +1431,9 @@ bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
   if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(V))
     return AMDGPU::isIntrinsicAlwaysUniform(Intrinsic->getIntrinsicID());
 
-  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
-    if (CI->isInlineAsm())
-      return !isInlineAsmSourceOfDivergence(CI);
+  if (const CallBase *CB = dyn_cast<CallBase>(V)) {
+    if (CB->isInlineAsm())
+      return !isInlineAsmSourceOfDivergence(CB);
     return false;
   }
 
@@ -1476,11 +1476,11 @@ bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
   if (!ExtValue)
     return false;
 
-  const CallInst *CI = dyn_cast<CallInst>(ExtValue->getOperand(0));
-  if (!CI)
+  const CallBase *CB = dyn_cast<CallBase>(ExtValue->getOperand(0));
+  if (!CB)
     return false;
 
-  if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(CI)) {
+  if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(CB)) {
     switch (Intrinsic->getIntrinsicID()) {
     default:
       return false;
@@ -1495,8 +1495,8 @@ bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
   // If we have inline asm returning mixed SGPR and VGPR results, we inferred
   // divergent for the overall struct return. We need to override it in the
   // case we're extracting an SGPR component here.
-  if (CI->isInlineAsm())
-    return !isInlineAsmSourceOfDivergence(CI, ExtValue->getIndices());
+  if (CB->isInlineAsm())
+    return !isInlineAsmSourceOfDivergence(CB, ExtValue->getIndices());
 
   return false;
 }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h
index 593aa5ebc43a2..ae218097e990b 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h
@@ -182,7 +182,7 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
       TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
       const Instruction *I = nullptr) const override;
 
-  bool isInlineAsmSourceOfDivergence(const CallInst *CI,
+  bool isInlineAsmSourceOfDivergence(const CallBase *CB,
                                      ArrayRef<unsigned> Indices = {}) const;
 
   using BaseT::getVectorInstrCost;
diff --git a/llvm/test/CodeGen/AMDGPU/infinite-loop.ll b/llvm/test/CodeGen/AMDGPU/infinite-loop.ll
index d38808e1a4498..fea649f7efc6a 100644
--- a/llvm/test/CodeGen/AMDGPU/infinite-loop.ll
+++ b/llvm/test/CodeGen/AMDGPU/infinite-loop.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc -mtriple=amdgpu6.00 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck -check-prefix=SI %s
 ; RUN: opt -mtriple=amdgpu6.00 -S -amdgpu-unify-divergent-exit-nodes -verify -simplifycfg-require-and-preserve-domtree=1 %s | FileCheck -check-prefix=IR %s
 
@@ -19,14 +19,16 @@ define amdgpu_kernel void @infinite_loop(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_cbranch_vccnz .LBB0_1
 ; SI-NEXT:  ; %bb.2: ; %DummyReturnBlock
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop(
-; IR-NEXT:  entry:
-; IR-NEXT:    br label [[LOOP:%.*]]
-; IR:       loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[LOOP]], label [[DUMMYRETURNBLOCK:%.*]]
-; IR:       DummyReturnBlock:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
+; IR-NEXT:    br label %[[LOOP:.*]]
+; IR:       [[LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[LOOP]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[DUMMYRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   br label %loop
 
@@ -60,18 +62,20 @@ define amdgpu_kernel void @infinite_loop_callbr(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_cbranch_vccz .LBB1_1
 ; SI-NEXT:  .LBB1_2: ; %DummyReturnBlock
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop_callbr(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop_callbr(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[LOOP:%.*]] []
-; IR:       loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK:%.*]], label [[DUMMYRETURNBLOCK:%.*]]
-; IR:       TransitionBlock:
+; IR-NEXT:            to label %[[LOOP:.*]] []
+; IR:       [[LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK:.*]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[TRANSITIONBLOCK]]:
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[LOOP]] []
-; IR:       DummyReturnBlock:
+; IR-NEXT:            to label %[[LOOP]] []
+; IR:       [[DUMMYRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   callbr void asm "", ""() to label %loop []
 
@@ -101,16 +105,18 @@ define amdgpu_kernel void @infinite_loop_ret(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_cbranch_vccnz .LBB2_2
 ; SI-NEXT:  .LBB2_3: ; %UnifiedReturnBlock
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop_ret(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop_ret(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    [[TMP:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
 ; IR-NEXT:    [[COND:%.*]] = icmp eq i32 [[TMP]], 1
-; IR-NEXT:    br i1 [[COND]], label [[LOOP:%.*]], label [[UNIFIEDRETURNBLOCK:%.*]]
-; IR:       loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[LOOP]], label [[UNIFIEDRETURNBLOCK]]
-; IR:       UnifiedReturnBlock:
+; IR-NEXT:    br i1 [[COND]], label %[[LOOP:.*]], label %[[UNIFIEDRETURNBLOCK:.*]]
+; IR:       [[LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[LOOP]], label %[[UNIFIEDRETURNBLOCK]]
+; IR:       [[UNIFIEDRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   %tmp = tail call i32 @llvm.amdgcn.workitem.id.x()
   %cond = icmp eq i32 %tmp, 1
@@ -151,24 +157,28 @@ define amdgpu_kernel void @infinite_loop_ret_callbr(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_mov_b64 vcc, vcc
 ; SI-NEXT:    s_cbranch_vccz .LBB3_2
 ; SI-NEXT:  .LBB3_3: ; Inline asm indirect target
-; SI-NEXT:    ; %UnifiedReturnBlock
+; SI-NEXT:    ; %return
 ; SI-NEXT:    ; Label of block must be emitted
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop_ret_callbr(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop_ret_callbr(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    [[TMP:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
 ; IR-NEXT:    [[COND:%.*]] = icmp eq i32 [[TMP]], 1
 ; IR-NEXT:    [[COND32:%.*]] = zext i1 [[COND]] to i32
 ; IR-NEXT:    callbr void asm "", "r,!i"(i32 [[COND32]])
-; IR-NEXT:            to label [[LOOP:%.*]] [label [[UNIFIEDRETURNBLOCK:%.*]]]
-; IR:       loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK:%.*]], label [[UNIFIEDRETURNBLOCK]]
-; IR:       TransitionBlock:
+; IR-NEXT:            to label %[[LOOP:.*]] [label %[[RETURN:.*]]]
+; IR:       [[LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK:.*]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[TRANSITIONBLOCK]]:
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[LOOP]] []
-; IR:       UnifiedReturnBlock:
+; IR-NEXT:            to label %[[LOOP]] []
+; IR:       [[RETURN]]:
 ; IR-NEXT:    ret void
+; IR:       [[DUMMYRETURNBLOCK]]:
+; IR-NEXT:    ret void
+;
 entry:
   %tmp = tail call i32 @llvm.amdgcn.workitem.id.x()
   %cond = icmp eq i32 %tmp, 1
@@ -213,17 +223,19 @@ define amdgpu_kernel void @infinite_loops(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_cbranch_vccnz .LBB4_4
 ; SI-NEXT:  .LBB4_5: ; %DummyReturnBlock
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loops(
-; IR-NEXT:  entry:
-; IR-NEXT:    br i1 poison, label [[LOOP1:%.*]], label [[LOOP2:%.*]]
-; IR:       loop1:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[LOOP1]], label [[DUMMYRETURNBLOCK:%.*]]
-; IR:       loop2:
+; IR-LABEL: define amdgpu_kernel void @infinite_loops(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
+; IR-NEXT:    br i1 poison, label %[[LOOP1:.*]], label %[[LOOP2:.*]]
+; IR:       [[LOOP1]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[LOOP1]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[LOOP2]]:
 ; IR-NEXT:    store volatile i32 888, ptr addrspace(1) [[OUT]], align 4
-; IR-NEXT:    br i1 true, label [[LOOP2]], label [[DUMMYRETURNBLOCK]]
-; IR:       DummyReturnBlock:
+; IR-NEXT:    br i1 true, label %[[LOOP2]], label %[[DUMMYRETURNBLOCK]]
+; IR:       [[DUMMYRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   br i1 poison, label %loop1, label %loop2
 
@@ -278,24 +290,26 @@ define amdgpu_kernel void @infinite_loops_callbr(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_mov_b64 vcc, vcc
 ; SI-NEXT:    s_cbranch_vccz .LBB5_5
 ; SI-NEXT:    s_branch .LBB5_3
-; IR-LABEL: @infinite_loops_callbr(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loops_callbr(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    callbr void asm "", "r,!i"(i32 poison)
-; IR-NEXT:            to label [[LOOP1:%.*]] [label [[LOOP2:%.*]]]
-; IR:       loop1:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK:%.*]], label [[DUMMYRETURNBLOCK:%.*]]
-; IR:       TransitionBlock:
+; IR-NEXT:            to label %[[LOOP1:.*]] [label %[[LOOP2:.*]]]
+; IR:       [[LOOP1]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK:.*]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[TRANSITIONBLOCK]]:
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[LOOP1]] []
-; IR:       loop2:
+; IR-NEXT:            to label %[[LOOP1]] []
+; IR:       [[LOOP2]]:
 ; IR-NEXT:    store volatile i32 888, ptr addrspace(1) [[OUT]], align 4
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK1:%.*]], label [[DUMMYRETURNBLOCK]]
-; IR:       TransitionBlock1:
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK1:.*]], label %[[DUMMYRETURNBLOCK]]
+; IR:       [[TRANSITIONBLOCK1]]:
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[LOOP2]] []
-; IR:       DummyReturnBlock:
+; IR-NEXT:            to label %[[LOOP2]] []
+; IR:       [[DUMMYRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   callbr void asm "", "r,!i"(i32 poison) to label %loop1 [label %loop2]
 
@@ -340,21 +354,23 @@ define amdgpu_kernel void @infinite_loop_nest_ret(ptr addrspace(1) %out) {
 ; SI-NEXT:    s_branch .LBB6_2
 ; SI-NEXT:  .LBB6_5: ; %UnifiedReturnBlock
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop_nest_ret(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop_nest_ret(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    [[TMP:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
 ; IR-NEXT:    [[COND1:%.*]] = icmp ne i32 [[TMP]], 1
-; IR-NEXT:    br i1 [[COND1]], label [[OUTER_LOOP:%.*]], label [[UNIFIEDRETURNBLOCK:%.*]]
-; IR:       outer_loop:
-; IR-NEXT:    br label [[INNER_LOOP:%.*]]
-; IR:       inner_loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
+; IR-NEXT:    br i1 [[COND1]], label %[[OUTER_LOOP:.*]], label %[[UNIFIEDRETURNBLOCK:.*]]
+; IR:       [[OUTER_LOOP]]:
+; IR-NEXT:    br label %[[INNER_LOOP:.*]]
+; IR:       [[INNER_LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
 ; IR-NEXT:    [[COND3:%.*]] = icmp eq i32 [[TMP]], 3
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK:%.*]], label [[UNIFIEDRETURNBLOCK]]
-; IR:       TransitionBlock:
-; IR-NEXT:    br i1 [[COND3]], label [[INNER_LOOP]], label [[OUTER_LOOP]]
-; IR:       UnifiedReturnBlock:
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK:.*]], label %[[UNIFIEDRETURNBLOCK]]
+; IR:       [[TRANSITIONBLOCK]]:
+; IR-NEXT:    br i1 [[COND3]], label %[[INNER_LOOP]], label %[[OUTER_LOOP]]
+; IR:       [[UNIFIEDRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   %tmp = tail call i32 @llvm.amdgcn.workitem.id.x()
   %cond1 = icmp ne i32 %tmp, 1  ; avoid following BB optimizing away through the domination
@@ -382,13 +398,13 @@ define amdgpu_kernel void @infinite_loop_nest_ret_callbr(ptr addrspace(1) %out)
 ; SI-NEXT:    ;;#ASMSTART
 ; SI-NEXT:    ;;#ASMEND
 ; SI-NEXT:  ; %bb.1: ; %outer_loop.preheader
-; SI-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
+; SI-NEXT:    s_load_dwordx2 s[4:5], s[4:5], 0x9
 ; SI-NEXT:    v_cmp_eq_u32_e32 vcc, 3, v0
 ; SI-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
-; SI-NEXT:    s_mov_b64 s[4:5], 0
-; SI-NEXT:    s_mov_b32 s3, 0xf000
-; SI-NEXT:    s_mov_b32 s2, -1
+; SI-NEXT:    s_mov_b32 s7, 0xf000
+; SI-NEXT:    s_mov_b32 s6, -1
 ; SI-NEXT:    v_mov_b32_e32 v1, 0x3e7
+; SI-NEXT:    s_and_b64 s[0:1], exec, 0
 ; SI-NEXT:  .LBB7_2: ; %outer_loop
 ; SI-NEXT:    ; =>This Loop Header: Depth=1
 ; SI-NEXT:    ; Child Loop BB7_3 Depth 2
@@ -397,9 +413,9 @@ define amdgpu_kernel void @infinite_loop_nest_ret_callbr(ptr addrspace(1) %out)
 ; SI-NEXT:  .LBB7_3: ; %inner_loop
 ; SI-NEXT:    ; Parent Loop BB7_2 Depth=1
 ; SI-NEXT:    ; => This Inner Loop Header: Depth=2
-; SI-NEXT:    s_and_b64 vcc, exec, 0
+; SI-NEXT:    s_mov_b64 vcc, s[0:1]
 ; SI-NEXT:    s_waitcnt lgkmcnt(0)
-; SI-NEXT:    buffer_store_dword v1, off, s[0:3], 0
+; SI-NEXT:    buffer_store_dword v1, off, s[4:7], 0
 ; SI-NEXT:    s_waitcnt vmcnt(0)
 ; SI-NEXT:    s_mov_b64 vcc, vcc
 ; SI-NEXT:    s_cbranch_vccnz .LBB7_6
@@ -412,40 +428,42 @@ define amdgpu_kernel void @infinite_loop_nest_ret_callbr(ptr addrspace(1) %out)
 ; SI-NEXT:    ; %TransitionBlock.target.outer_loop
 ; SI-NEXT:    ; in Loop: Header=BB7_2 Depth=1
 ; SI-NEXT:    ; Label of block must be emitted
-; SI-NEXT:    s_mov_b64 s[6:7], 0
+; SI-NEXT:    s_mov_b64 s[2:3], 0
 ; SI-NEXT:    s_branch .LBB7_7
 ; SI-NEXT:  .LBB7_6: ; in Loop: Header=BB7_2 Depth=1
-; SI-NEXT:    s_mov_b64 s[6:7], -1
+; SI-NEXT:    s_mov_b64 s[2:3], -1
 ; SI-NEXT:  .LBB7_7: ; %loop.exit.guard
 ; SI-NEXT:    ; in Loop: Header=BB7_2 Depth=1
-; SI-NEXT:    s_and_b64 s[6:7], exec, s[6:7]
-; SI-NEXT:    s_or_b64 s[4:5], s[6:7], s[4:5]
-; SI-NEXT:    s_andn2_b64 exec, exec, s[4:5]
-; SI-NEXT:    s_cbranch_execnz .LBB7_2
+; SI-NEXT:    s_and_b64 vcc, exec, s[2:3]
+; SI-NEXT:    s_cbranch_vccz .LBB7_2
 ; SI-NEXT:  .LBB7_8: ; Inline asm indirect target
-; SI-NEXT:    ; %UnifiedReturnBlock
+; SI-NEXT:    ; %return
 ; SI-NEXT:    ; Label of block must be emitted
 ; SI-NEXT:    s_endpgm
-; IR-LABEL: @infinite_loop_nest_ret_callbr(
-; IR-NEXT:  entry:
+; IR-LABEL: define amdgpu_kernel void @infinite_loop_nest_ret_callbr(
+; IR-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; IR-NEXT:  [[ENTRY:.*:]]
 ; IR-NEXT:    [[TMP:%.*]] = tail call i32 @llvm.amdgcn.workitem.id.x()
 ; IR-NEXT:    [[COND1:%.*]] = icmp ne i32 [[TMP]], 1
 ; IR-NEXT:    [[COND1_32:%.*]] = zext i1 [[COND1]] to i32
 ; IR-NEXT:    callbr void asm "", "r,!i"(i32 [[COND1_32]])
-; IR-NEXT:            to label [[OUTER_LOOP:%.*]] [label [[UNIFIEDRETURNBLOCK:%.*]]]
-; IR:       outer_loop:
+; IR-NEXT:            to label %[[OUTER_LOOP:.*]] [label %[[RETURN:.*]]]
+; IR:       [[OUTER_LOOP]]:
 ; IR-NEXT:    callbr void asm "", ""()
-; IR-NEXT:            to label [[INNER_LOOP:%.*]] []
-; IR:       inner_loop:
-; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT:%.*]], align 4
+; IR-NEXT:            to label %[[INNER_LOOP:.*]] []
+; IR:       [[INNER_LOOP]]:
+; IR-NEXT:    store volatile i32 999, ptr addrspace(1) [[OUT]], align 4
 ; IR-NEXT:    [[COND3:%.*]] = icmp eq i32 [[TMP]], 3
 ; IR-NEXT:    [[COND3_32:%.*]] = zext i1 [[COND3]] to i32
-; IR-NEXT:    br i1 true, label [[TRANSITIONBLOCK:%.*]], label [[UNIFIEDRETURNBLOCK]]
-; IR:       TransitionBlock:
+; IR-NEXT:    br i1 true, label %[[TRANSITIONBLOCK:.*]], label %[[DUMMYRETURNBLOCK:.*]]
+; IR:       [[TRANSITIONBLOCK]]:
 ; IR-NEXT:    callbr void asm "", "r,!i"(i32 [[COND3_32]])
-; IR-NEXT:            to label [[INNER_LOOP]] [label [[OUTER_LOOP]]]
-; IR:       UnifiedReturnBlock:
+; IR-NEXT:            to label %[[INNER_LOOP]] [label %[[OUTER_LOOP]]]
+; IR:       [[RETURN]]:
+; IR-NEXT:    ret void
+; IR:       [[DUMMYRETURNBLOCK]]:
 ; IR-NEXT:    ret void
+;
 entry:
   %tmp = tail call i32 @llvm.amdgcn.workitem.id.x()
   %cond1 = icmp ne i32 %tmp, 1  ; avoid following BB optimizing away through the domination
diff --git a/llvm/test/CodeGen/AMDGPU/si-unify-exit-multiple-unreachables.ll b/llvm/test/CodeGen/AMDGPU/si-unify-exit-multiple-unreachables.ll
index 645239b047781..c95224fda27d3 100644
--- a/llvm/test/CodeGen/AMDGPU/si-unify-exit-multiple-unreachables.ll
+++ b/llvm/test/CodeGen/AMDGPU/si-unify-exit-multiple-unreachables.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -S -mtriple=amdgpu9.06-amd-amdhsa -stop-after=amdgpu-unify-divergent-exit-nodes | FileCheck %s --check-prefix=UNIFY
 ; RUN: llc < %s -mtriple=amdgpu9.06-amd-amdhsa | FileCheck %s
 
@@ -70,31 +70,32 @@ define amdgpu_kernel void @kernel(i32 %a, ptr addrspace(1) %x, i32 noundef %n) {
 ; CHECK-NEXT:    s_mov_b64 s[2:3], -1
 ; CHECK-NEXT:    s_trap 2
 ; CHECK-NEXT:    s_branch .LBB0_4
-; UNIFY-LABEL: @kernel(
-; UNIFY-NEXT:  entry:
+; UNIFY-LABEL: define amdgpu_kernel void @kernel(
+; UNIFY-SAME: i32 [[A:%.*]], ptr addrspace(1) [[X:%.*]], i32 noundef [[N:%.*]]) {
+; UNIFY-NEXT:  [[ENTRY:.*:]]
 ; UNIFY-NEXT:    [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()
-; UNIFY-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 256
-; UNIFY-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
-; UNIFY:       if.then:
-; UNIFY-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0
-; UNIFY-NEXT:    br i1 [[CMP1]], label [[IF_END6_SINK_SPLIT:%.*]], label [[COND_FALSE:%.*]]
-; UNIFY:       cond.false:
+; UNIFY-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N]], 256
+; UNIFY-NEXT:    br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; UNIFY:       [[IF_THEN]]:
+; UNIFY-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A]], 0
+; UNIFY-NEXT:    br i1 [[CMP1]], label %[[IF_END6_SINK_SPLIT:.*]], label %[[COND_FALSE:.*]]
+; UNIFY:       [[COND_FALSE]]:
 ; UN...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/228744


More information about the llvm-commits mailing list