[llvm] [AMDGPU] Use the reserved EXEC copy register for emergency SGPR spills (PR #221972)
Pankaj Dwivedi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 05:20:25 PDT 2026
https://github.com/PankajDwivedi-25 updated https://github.com/llvm/llvm-project/pull/221972
>From 19a05ae0e9fe4e58a44e2a806cd144f214ff0e71 Mon Sep 17 00:00:00 2001
From: padivedi <pankajkumar.divedi at amd.com>
Date: Wed, 9 Sep 2026 17:49:19 +0530
Subject: [PATCH] [AMDGPU] Scale the frame register in place when lowering
scalar frame indices
---
llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp | 80 +++++++-
.../AMDGPU/sgpr-scavenge-fi-stack-id.ll | 26 +--
...to-vmem-scc-clobber-reserved-exec-copy.mir | 184 ++++++++++++++++++
3 files changed, 260 insertions(+), 30 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/sgpr-spill-to-vmem-scc-clobber-reserved-exec-copy.mir
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index f570aa4e2f6fb..7dee87df9f998 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -3419,11 +3419,40 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
bool IsCopy = MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
MI->getOpcode() == AMDGPU::S_MOV_B32;
- Register ResultReg =
- IsCopy ? MI->getOperand(0).getReg()
- : RS->scavengeRegisterBackwards(*RC, MI, false, 0);
int64_t Offset = FrameInfo.getObjectOffset(Index);
+ int64_t ScaledOffset = -Offset * ST.getWavefrontSize();
+
+ // Scaling FrameReg in place is the last resort when there is nothing to
+ // scavenge. It has to be undone after MI, which is only possible while MI
+ // does not use FrameReg for anything besides the frame index, and while
+ // the offset can be folded back in wave space. A second frame index on MI
+ // would be lowered while FrameReg is still scaled, so keep away from it.
+ bool HasOneFrameIndex =
+ llvm::count_if(MI->operands(), [](const MachineOperand &MO) {
+ return MO.isFI();
+ }) == 1;
+ bool CanUseFrameRegAsScratch =
+ IsSALU && !LiveSCC && FrameReg && HasOneFrameIndex &&
+ !MI->readsRegister(FrameReg, this) &&
+ !MI->modifiesRegister(FrameReg, this) && isInt<32>(ScaledOffset);
+
+ bool RestoreFrameReg = false;
+ Register ResultReg;
+ if (IsCopy) {
+ ResultReg = MI->getOperand(0).getReg();
+ } else {
+ ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0,
+ /*AllowSpill=*/false);
+ if (!ResultReg && CanUseFrameRegAsScratch) {
+ // Spilling an SGPR here instead would flip EXEC with S_NOT, and that
+ // clobbers the SCC MI may be defining for a later use.
+ ResultReg = FrameReg;
+ RestoreFrameReg = true;
+ } else if (!ResultReg) {
+ ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0);
+ }
+ }
// The carry-out lane of Add is unused, so it is safe to write with
// S_MOV_B32 even into a VGPR.
@@ -3512,7 +3541,11 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
: RS->scavengeRegisterBackwards(
AMDGPU::SReg_32_XM0RegClass, MI,
false, 0, /*AllowSpill=*/false);
- Register ScaledReg = TmpScaledReg.isValid() ? TmpScaledReg : FrameReg;
+ // A scalar result is already materialized in ResultReg, which holds
+ // the scavenged register, or FrameReg itself if nothing was free.
+ Register ScaledReg = TmpScaledReg;
+ if (!ScaledReg)
+ ScaledReg = IsSALU ? ResultReg : FrameReg;
Register TmpResultReg = ScaledReg;
if (!LiveSCC) {
@@ -3590,8 +3623,10 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
if (!IsSALU)
BuildMI(*MBB, MI, DL, TII->get(AMDGPU::COPY), ResultReg)
.addReg(TmpResultReg, RegState::Kill);
- // If there were truly no free SGPRs, we need to undo everything.
- if (!TmpScaledReg.isValid()) {
+ // If there were truly no free SGPRs, we need to undo everything. A
+ // scalar result keeps using FrameReg until MI has consumed it, so it
+ // is put back after MI instead.
+ if (!TmpScaledReg.isValid() && !IsSALU) {
BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_I32), ScaledReg)
.addReg(ScaledReg, RegState::Kill)
.addImm(-Offset);
@@ -3602,12 +3637,43 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
}
}
+ if (RestoreFrameReg) {
+ // Put FrameReg back now that MI has consumed the scaled address.
+ // S_MUL_I32 undoes the scaling without writing SCC, which S_LSHL_B32
+ // would. When MI leaves SCC live, fold the offset back with the carry
+ // sequence that smuggles SCC through bit 0, which the scaling has just
+ // cleared.
+ MachineBasicBlock::iterator InsPt = std::next(MI);
+ BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_MUL_I32), FrameReg)
+ .addReg(FrameReg)
+ .addImm(ST.getWavefrontSize());
+
+ bool SCCLiveAfterMI = MI->definesRegister(AMDGPU::SCC, this) &&
+ !MI->registerDefIsDead(AMDGPU::SCC, this);
+ if (Offset && !SCCLiveAfterMI) {
+ BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_ADD_I32), FrameReg)
+ .addReg(FrameReg)
+ .addImm(ScaledOffset);
+ } else if (Offset) {
+ BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_ADDC_U32), FrameReg)
+ .addReg(FrameReg)
+ .addImm(ScaledOffset);
+ BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_BITCMP1_B32))
+ .addReg(FrameReg)
+ .addImm(0);
+ BuildMI(*MBB, InsPt, DL, TII->get(AMDGPU::S_BITSET0_B32), FrameReg)
+ .addImm(0)
+ .addReg(FrameReg);
+ }
+ }
+
// Don't introduce an extra copy if we're just materializing in a mov.
if (IsCopy) {
MI->eraseFromParent();
return true;
}
- FIOp->ChangeToRegister(ResultReg, false, false, true);
+ // FrameReg is restored after MI, so MI does not kill it.
+ FIOp->ChangeToRegister(ResultReg, false, false, !RestoreFrameReg);
return false;
}
diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-scavenge-fi-stack-id.ll b/llvm/test/CodeGen/AMDGPU/sgpr-scavenge-fi-stack-id.ll
index 4d33d0020fff0..72736e1da863a 100644
--- a/llvm/test/CodeGen/AMDGPU/sgpr-scavenge-fi-stack-id.ll
+++ b/llvm/test/CodeGen/AMDGPU/sgpr-scavenge-fi-stack-id.ll
@@ -155,34 +155,14 @@ define void @sgpr_scavenge_fi_stack_id(double %input, i1 %enter_fma_path, i1 %re
; CHECK-NEXT: ; => This Inner Loop Header: Depth=5
; CHECK-NEXT: s_and_b64 s[30:31], exec, s[6:7]
; CHECK-NEXT: s_or_b64 s[94:95], s[30:31], s[94:95]
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8
-; CHECK-NEXT: v_writelane_b32 v7, s4, 0
-; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: buffer_store_dword v7, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: buffer_load_dword v7, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_waitcnt vmcnt(0)
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: s_lshr_b32 s4, s32, 6
-; CHECK-NEXT: s_lshl3_add_u32 vcc_hi, vcc_lo, s4
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: buffer_store_dword v8, off, s[0:3], s32 offset:8
-; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_not_b64 exec, exec
-; CHECK-NEXT: s_waitcnt vmcnt(0)
-; CHECK-NEXT: v_readlane_b32 s4, v8, 0
-; CHECK-NEXT: buffer_load_dword v8, off, s[0:3], s32 offset:8
-; CHECK-NEXT: s_waitcnt vmcnt(0)
-; CHECK-NEXT: s_not_b64 exec, exec
+; CHECK-NEXT: s_lshr_b32 s32, s32, 6
+; CHECK-NEXT: s_lshl3_add_u32 vcc_hi, vcc_lo, s32
; CHECK-NEXT: v_mov_b32_e32 v7, vcc_hi
; CHECK-NEXT: buffer_load_dword v8, v7, s[0:3], 0 offen
; CHECK-NEXT: buffer_load_dword v9, v7, s[0:3], 0 offen offset:4
; CHECK-NEXT: v_mov_b32_e32 v7, vcc_lo
; CHECK-NEXT: s_mov_b32 vcc_lo, 1
+; CHECK-NEXT: s_mul_i32 s32, s32, 64
; CHECK-NEXT: s_waitcnt vmcnt(0)
; CHECK-NEXT: v_mul_f64 v[8:9], v[4:5], v[8:9]
; CHECK-NEXT: buffer_store_dword v9, off, s[0:3], 0 offset:4
diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-spill-to-vmem-scc-clobber-reserved-exec-copy.mir b/llvm/test/CodeGen/AMDGPU/sgpr-spill-to-vmem-scc-clobber-reserved-exec-copy.mir
new file mode 100644
index 0000000000000..413500e32d91f
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/sgpr-spill-to-vmem-scc-clobber-reserved-exec-copy.mir
@@ -0,0 +1,184 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=amdgpu9.0a-amd-amdhsa -run-pass=prolog-epilog -o - %s 2>&1 | FileCheck %s
+---
+name: scc_live_across_scalar_frame_index
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 16
+stack:
+ - { id: 0, size: 64, alignment: 16 }
+machineFunctionInfo:
+ isEntryFunction: false
+ scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
+ frameOffsetReg: '$sgpr33'
+ stackPtrOffsetReg: '$sgpr32'
+ sgprForEXECCopy: '$sgpr100_sgpr101'
+ occupancy: 2
+body: |
+ ; CHECK-LABEL: name: scc_live_across_scalar_frame_index
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.1(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; CHECK-NEXT: S_BRANCH %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $sgpr32 = S_LSHR_B32 $sgpr32, 6, implicit-def dead $scc
+ ; CHECK-NEXT: renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, $sgpr32, implicit-def $scc
+ ; CHECK-NEXT: $sgpr32 = S_MUL_I32 $sgpr32, 64
+ ; CHECK-NEXT: renamable $vcc_hi = S_SUBB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc, implicit $scc
+ ; CHECK-NEXT: S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ ; CHECK-NEXT: S_BRANCH %bb.2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: liveins: $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: S_ENDPGM 0, implicit $vcc
+ bb.0:
+ S_BRANCH %bb.1
+
+ bb.1:
+ liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+
+ renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, %stack.0, implicit-def $scc
+ renamable $vcc_hi = S_SUBB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc, implicit $scc
+ S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ S_BRANCH %bb.2
+
+ bb.2:
+ liveins: $vcc
+
+ S_ENDPGM 0, implicit $vcc
+...
+
+# The frame index has a non-zero offset here, so the offset has to be folded
+# back into the frame register too. That addition writes SCC, so it is done
+# with the carry sequence that smuggles SCC through bit 0.
+
+---
+name: scc_live_across_scalar_frame_index_nonzero_offset
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 16
+stack:
+ - { id: 0, size: 64, alignment: 16 }
+ - { id: 1, size: 64, alignment: 16 }
+machineFunctionInfo:
+ isEntryFunction: false
+ scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
+ frameOffsetReg: '$sgpr33'
+ stackPtrOffsetReg: '$sgpr32'
+ sgprForEXECCopy: '$sgpr100_sgpr101'
+ occupancy: 2
+body: |
+ ; CHECK-LABEL: name: scc_live_across_scalar_frame_index_nonzero_offset
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.1(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; CHECK-NEXT: S_BRANCH %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $sgpr32 = S_LSHR_B32 $sgpr32, 6, implicit-def $scc
+ ; CHECK-NEXT: $sgpr32 = S_ADD_I32 killed $sgpr32, 64, implicit-def $scc
+ ; CHECK-NEXT: renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, $sgpr32, implicit-def $scc
+ ; CHECK-NEXT: $sgpr32 = S_MUL_I32 $sgpr32, 64
+ ; CHECK-NEXT: $sgpr32 = S_ADDC_U32 $sgpr32, -4096, implicit-def $scc, implicit $scc
+ ; CHECK-NEXT: S_BITCMP1_B32 $sgpr32, 0, implicit-def $scc
+ ; CHECK-NEXT: $sgpr32 = S_BITSET0_B32 0, $sgpr32
+ ; CHECK-NEXT: renamable $vcc_hi = S_SUBB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc, implicit $scc
+ ; CHECK-NEXT: S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ ; CHECK-NEXT: S_BRANCH %bb.2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: liveins: $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: S_ENDPGM 0, implicit $vcc
+ bb.0:
+ S_BRANCH %bb.1
+
+ bb.1:
+ liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+
+ renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, %stack.1, implicit-def $scc
+ renamable $vcc_hi = S_SUBB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc, implicit $scc
+ S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ S_BRANCH %bb.2
+
+ bb.2:
+ liveins: $vcc
+
+ S_ENDPGM 0, implicit $vcc
+...
+
+# Same non-zero offset, but nothing uses SCC after the instruction, so the
+# offset can be folded back with a plain add.
+
+---
+name: scc_dead_after_scalar_frame_index_nonzero_offset
+alignment: 4
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 16
+stack:
+ - { id: 0, size: 64, alignment: 16 }
+ - { id: 1, size: 64, alignment: 16 }
+machineFunctionInfo:
+ isEntryFunction: false
+ scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
+ frameOffsetReg: '$sgpr33'
+ stackPtrOffsetReg: '$sgpr32'
+ sgprForEXECCopy: '$sgpr100_sgpr101'
+ occupancy: 2
+body: |
+ ; CHECK-LABEL: name: scc_dead_after_scalar_frame_index_nonzero_offset
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.1(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; CHECK-NEXT: S_BRANCH %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $sgpr32 = S_LSHR_B32 $sgpr32, 6, implicit-def $scc
+ ; CHECK-NEXT: $sgpr32 = S_ADD_I32 killed $sgpr32, 64, implicit-def $scc
+ ; CHECK-NEXT: renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, $sgpr32, implicit-def dead $scc
+ ; CHECK-NEXT: $sgpr32 = S_MUL_I32 $sgpr32, 64
+ ; CHECK-NEXT: $sgpr32 = S_ADD_I32 $sgpr32, -4096, implicit-def $scc
+ ; CHECK-NEXT: renamable $vcc_hi = S_SUB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc
+ ; CHECK-NEXT: S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ ; CHECK-NEXT: S_BRANCH %bb.2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: liveins: $vcc
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: S_ENDPGM 0, implicit $vcc
+ bb.0:
+ S_BRANCH %bb.1
+
+ bb.1:
+ liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, $sgpr96_sgpr97_sgpr98_sgpr99, $vcc
+
+ renamable $vcc_lo = S_SUB_U32 killed renamable $vcc_lo, %stack.1, implicit-def dead $scc
+ renamable $vcc_hi = S_SUB_U32 killed renamable $vcc_hi, renamable $sgpr97, implicit-def dead $scc
+ S_NOP 0, implicit killed $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19, implicit killed $sgpr20_sgpr21_sgpr22_sgpr23_sgpr24_sgpr25_sgpr26_sgpr27_sgpr28_sgpr29_sgpr30_sgpr31_sgpr32_sgpr33_sgpr34_sgpr35, implicit killed $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, implicit killed $sgpr52_sgpr53_sgpr54_sgpr55_sgpr56_sgpr57_sgpr58_sgpr59_sgpr60_sgpr61_sgpr62_sgpr63_sgpr64_sgpr65_sgpr66_sgpr67, implicit killed $sgpr68_sgpr69_sgpr70_sgpr71_sgpr72_sgpr73_sgpr74_sgpr75_sgpr76_sgpr77_sgpr78_sgpr79_sgpr80_sgpr81_sgpr82_sgpr83, implicit killed $sgpr84_sgpr85_sgpr86_sgpr87_sgpr88_sgpr89_sgpr90_sgpr91_sgpr92_sgpr93_sgpr94_sgpr95, implicit killed $sgpr96_sgpr97_sgpr98_sgpr99
+ S_BRANCH %bb.2
+
+ bb.2:
+ liveins: $vcc
+
+ S_ENDPGM 0, implicit $vcc
+...
More information about the llvm-commits
mailing list