[llvm] [AMDGPU] Don't apply gfx950 fetch-window loop align to the wrong block (PR #221821)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 14:11:23 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Akash Dutta (akadutta)

<details>
<summary>Changes</summary>

MachineBlockPlacement aligns the backedge destination after loop rotation, which may not be the LoopInfo header. Query that block for the 32-byte request and the 4-byte pad cap so they stay consistent. 
## Summary
- Pass the block being aligned into `getPrefLoopAlignment` so gfx950 fetch-window alignment uses the backedge destination, not only the LoopInfo header.
- Unrotated 8-byte headers still get capped.
- Rotated 4-byte landing pads are no longer given uncapped 32-byte alignment.


---
Full diff: https://github.com/llvm/llvm-project/pull/221821.diff


5 Files Affected:

- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+10) 
- (modified) llvm/lib/CodeGen/MachineBlockPlacement.cpp (+3-1) 
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+12-9) 
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.h (+3-1) 
- (modified) llvm/test/CodeGen/AMDGPU/loop-header-align-gfx950.mir (+275-20) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 69f5e0e4e3011..ed15ec1fdb7eb 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2177,6 +2177,16 @@ class LLVM_ABI TargetLoweringBase {
   /// Return the preferred loop alignment.
   virtual Align getPrefLoopAlignment(MachineLoop *ML = nullptr) const;
 
+  /// Return the preferred alignment for MBB when it is being aligned as part
+  /// of ML. Callers that have no specific block should use the one-argument
+  /// hook. Targets with block-specific loop alignment requirements can
+  /// override this hook; AMDGPU requires MBB to be non-null. The default
+  /// preserves existing one-argument overrides.
+  virtual Align getPrefLoopAlignment(MachineLoop *ML,
+                                     const MachineBasicBlock *MBB) const {
+    return getPrefLoopAlignment(ML);
+  }
+
   /// Return the maximum amount of bytes allowed to be emitted when padding for
   /// alignment
   virtual unsigned
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 1378aaa67ba39..a8bd36cfb22c5 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -3032,7 +3032,9 @@ void MachineBlockPlacement::alignBlocks() {
     if (!L)
       continue;
 
-    const Align TLIAlign = TLI->getPrefLoopAlignment(L);
+    // Query the block being aligned rather than only the LoopInfo header.
+    // After loop rotation, ChainBB can be a different backedge destination.
+    const Align TLIAlign = TLI->getPrefLoopAlignment(L, ChainBB);
     unsigned MDAlign = 1;
     MDNode *LoopID = L->getLoopID();
     if (LoopID) {
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 5fb904aa4970f..0a6dadafc9e03 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -20436,21 +20436,24 @@ Align SITargetLowering::computeKnownAlignForTargetInstr(
   return Align(1);
 }
 
-Align SITargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {
+Align SITargetLowering::getPrefLoopAlignment(
+    MachineLoop *ML, const MachineBasicBlock *BlockToAlign) const {
   const Align PrefAlign = TargetLowering::getPrefLoopAlignment(ML);
   const Align CacheLineAlign = Align(64);
 
-  // GFX950: Prevent an 8-byte instruction at loop header from being split by
-  // the 32-byte instruction fetch window boundary. This avoids a significant
-  // fetch delay after backward branch. We use 32-byte alignment with max
-  // padding of 4 bytes (one s_nop), see getMaxPermittedBytesForAlignment().
+  // GFX950: Prevent an 8-byte instruction at the block being aligned from being
+  // split by the 32-byte instruction fetch window boundary. This avoids a
+  // significant fetch delay after a backward branch. We use 32-byte alignment
+  // with max padding of 4 bytes (one s_nop), see
+  // getMaxPermittedBytesForAlignment().
   if (ML && !DisableLoopAlignment &&
       getSubtarget()->hasLoopHeadInstSplitSensitivity()) {
-    const MachineBasicBlock *Header = ML->getHeader();
+    assert(BlockToAlign &&
+           "gfx950 fetch-window alignment requires the block being aligned");
     // Respect user-specified or previously set alignment.
-    if (Header->getAlignment() != PrefAlign)
-      return Header->getAlignment();
-    if (needsFetchWindowAlignment(*Header))
+    if (BlockToAlign->getAlignment() != PrefAlign)
+      return BlockToAlign->getAlignment();
+    if (needsFetchWindowAlignment(*BlockToAlign))
       return Align(32);
   }
 
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 215107fcec712..324c1ab708e13 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -624,7 +624,9 @@ class SITargetLowering final : public AMDGPUTargetLowering {
                                             bool isDivergent) const override;
   bool requiresUniformRegister(MachineFunction &MF,
                                const Value *V) const override;
-  Align getPrefLoopAlignment(MachineLoop *ML) const override;
+  Align
+  getPrefLoopAlignment(MachineLoop *ML,
+                       const MachineBasicBlock *BlockToAlign) const override;
   unsigned
   getMaxPermittedBytesForAlignment(MachineBasicBlock *MBB) const override;
 
diff --git a/llvm/test/CodeGen/AMDGPU/loop-header-align-gfx950.mir b/llvm/test/CodeGen/AMDGPU/loop-header-align-gfx950.mir
index a23fb912893b1..3acb7da6b3e96 100644
--- a/llvm/test/CodeGen/AMDGPU/loop-header-align-gfx950.mir
+++ b/llvm/test/CodeGen/AMDGPU/loop-header-align-gfx950.mir
@@ -1,22 +1,39 @@
-# RUN: llc -mtriple=amdgpu9.50 -start-before=block-placement -o - %s | FileCheck %s
-
-# Test that loop headers are aligned to 32 bytes on GFX950 when the first
-# instruction is 8 bytes, to prevent the instruction from being split by the
-# 32-byte fetch window boundary.
-# The second test case verifies that 4-byte instructions do NOT trigger
-# alignment (CHECK-NEXT chain would break if .p2align were inserted).
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=amdgpu9.50 -start-before=block-placement \
+# RUN:   -stop-after=block-placement -o - %s | FileCheck %s
+#
+# GFX950 fetch-window loop alignment: 32-byte align with a 4-byte pad cap when
+# the block being aligned starts with an instruction wider than 4 bytes.
+# Rotated loops must use the backedge destination, not the LoopInfo header.
+# The extra preheaders keep function entry out of the rotated chain; the
+# diamonds give block placement a landing pad that is not the natural header.
 
 ---
 name:            loop_with_8byte_first_inst
 tracksRegLiveness: true
 body:             |
-  ; CHECK-LABEL: loop_with_8byte_first_inst:
-  ; CHECK:       ; %bb.0:
-  ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-  ; CHECK-NEXT:    s_mov_b64 s[0:1], 0
-  ; CHECK-NEXT:    .p2align 5, , 4
-  ; CHECK-NEXT:  .LBB0_1: ; =>This Inner Loop Header: Depth=1
-  ; CHECK-NEXT:    v_lshrrev_b64 v[0:1], 1, v[0:1]
+  ; CHECK-LABEL: name: loop_with_8byte_first_inst
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $sgpr0_sgpr1 = S_MOV_B64 0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1 (align 32):
+  ; CHECK-NEXT:   successors: %bb.2(0x04000000), %bb.1(0x7c000000)
+  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1, $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, killed $vgpr0_vgpr1, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U64_e32 0, $vgpr0_vgpr1, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   renamable $sgpr0_sgpr1 = S_OR_B64 killed renamable $vcc, killed renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   $exec = S_ANDN2_B64 $exec, renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   $exec = S_OR_B64 $exec, killed renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   S_SETPC_B64_return undef $sgpr30_sgpr31
   bb.0:
     successors: %bb.1(0x80000000)
     liveins: $vgpr0_vgpr1
@@ -44,12 +61,28 @@ body:             |
 name:            loop_with_4byte_first_inst
 tracksRegLiveness: true
 body:             |
-  ; CHECK-LABEL: loop_with_4byte_first_inst:
-  ; CHECK:       ; %bb.0:
-  ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-  ; CHECK-NEXT:    s_mov_b64 s[0:1], 0
-  ; CHECK-NEXT:  .LBB1_1: ; =>This Inner Loop Header: Depth=1
-  ; CHECK-NEXT:    v_add_u32_e32 v0, 1, v0
+  ; CHECK-LABEL: name: loop_with_4byte_first_inst
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $sgpr0_sgpr1 = S_MOV_B64 0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x04000000), %bb.1(0x7c000000)
+  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1, $vgpr0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, killed $vgpr0, implicit $exec
+  ; CHECK-NEXT:   V_CMP_LT_U32_e32 10, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   renamable $sgpr0_sgpr1 = S_OR_B64 killed renamable $vcc, killed renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   $exec = S_ANDN2_B64 $exec, renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   $exec = S_OR_B64 $exec, killed renamable $sgpr0_sgpr1, implicit-def $scc
+  ; CHECK-NEXT:   S_SETPC_B64_return undef $sgpr30_sgpr31
   bb.0:
     successors: %bb.1(0x80000000)
     liveins: $vgpr0
@@ -72,3 +105,225 @@ body:             |
     $exec = S_OR_B64 $exec, killed renamable $sgpr0_sgpr1, implicit-def $scc
     S_SETPC_B64_return undef $sgpr30_sgpr31
 ...
+
+---
+name:            rotated_loop_with_4byte_landing_pad
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: rotated_loop_with_4byte_landing_pad
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   S_BRANCH %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6:
+  ; CHECK-NEXT:   successors: %bb.7(0x04000000), %bb.2(0x7c000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCNZ %bb.7, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, killed $vgpr0_vgpr1, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCZ %bb.4, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4:
+  ; CHECK-NEXT:   successors: %bb.5(0x40000000), %bb.6(0x40000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCZ %bb.6, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5:
+  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT:   S_BRANCH %bb.6
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7:
+  ; CHECK-NEXT:   S_SETPC_B64_return undef $sgpr30_sgpr31
+  bb.0:
+    successors: %bb.1(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    S_BRANCH %bb.1
+
+  bb.1:
+    successors: %bb.2(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    S_BRANCH %bb.2
+
+  bb.2:
+    successors: %bb.3(0x40000000), %bb.4(0x40000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, killed renamable $vgpr0_vgpr1, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.3, implicit killed $vcc
+    S_BRANCH %bb.4
+
+  bb.3:
+    successors: %bb.4(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    S_BRANCH %bb.4
+
+  bb.4:
+    successors: %bb.5(0x40000000), %bb.6(0x40000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.5, implicit killed $vcc
+    S_BRANCH %bb.6
+
+  bb.5:
+    successors: %bb.6(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    S_BRANCH %bb.6
+
+  bb.6:
+    successors: %bb.7(0x04000000), %bb.2(0x7c000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.7, implicit killed $vcc
+    S_BRANCH %bb.2
+
+  bb.7:
+    S_SETPC_B64_return undef $sgpr30_sgpr31
+...
+
+---
+name:            rotated_loop_with_8byte_landing_pad
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: rotated_loop_with_8byte_landing_pad
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   S_BRANCH %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6 (align 32):
+  ; CHECK-NEXT:   successors: %bb.7(0x04000000), %bb.2(0x7c000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, $vgpr0_vgpr1, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCNZ %bb.7, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, $vgpr0_vgpr1, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCZ %bb.4, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4:
+  ; CHECK-NEXT:   successors: %bb.5(0x40000000), %bb.6(0x40000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT:   V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+  ; CHECK-NEXT:   S_CBRANCH_VCCZ %bb.6, implicit killed $vcc
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5:
+  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
+  ; CHECK-NEXT:   liveins: $vgpr0_vgpr1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $vgpr0 = V_ADD_U32_e32 1, $vgpr0, implicit $exec
+  ; CHECK-NEXT:   S_BRANCH %bb.6
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7:
+  ; CHECK-NEXT:   S_SETPC_B64_return undef $sgpr30_sgpr31
+  bb.0:
+    successors: %bb.1(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    S_BRANCH %bb.1
+
+  bb.1:
+    successors: %bb.2(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    S_BRANCH %bb.2
+
+  bb.2:
+    successors: %bb.3(0x40000000), %bb.4(0x40000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, renamable $vgpr0_vgpr1, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.3, implicit killed $vcc
+    S_BRANCH %bb.4
+
+  bb.3:
+    successors: %bb.4(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    S_BRANCH %bb.4
+
+  bb.4:
+    successors: %bb.5(0x40000000), %bb.6(0x40000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.5, implicit killed $vcc
+    S_BRANCH %bb.6
+
+  bb.5:
+    successors: %bb.6(0x80000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0 = V_ADD_U32_e32 1, renamable $vgpr0, implicit $exec
+    S_BRANCH %bb.6
+
+  bb.6:
+    successors: %bb.7(0x04000000), %bb.2(0x7c000000)
+    liveins: $vgpr0_vgpr1
+
+    renamable $vgpr0_vgpr1 = V_LSHRREV_B64_e64 1, renamable $vgpr0_vgpr1, implicit $exec
+    V_CMP_EQ_U32_e32 0, $vgpr0, implicit-def $vcc, implicit $exec
+    S_CBRANCH_VCCNZ %bb.7, implicit killed $vcc
+    S_BRANCH %bb.2
+
+  bb.7:
+    S_SETPC_B64_return undef $sgpr30_sgpr31
+...

``````````

</details>


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


More information about the llvm-commits mailing list