[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