[AMDGPU] Fix eliminateFrameIndex clobbering a scavenged register - #217470
Merged
aobolensk merged 3 commits intoAug 20, 2026
Conversation
Writing the offset into an undefined scavenged register let the scavenger alias it with another temp and corrupt the address
|
@llvm/pr-subscribers-backend-amdgpu Author: Arseniy Obolenskiy (aobolensk) ChangesWriting the offset into an undefined scavenged register let the scavenger alias it with another temp and corrupt the address Patch is 23.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217470.diff 4 Files Affected:
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 971dedd0878f1..ea43c0c2fb56e 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -3372,6 +3372,20 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
: RS->scavengeRegisterBackwards(*RC, MI, false, 0);
int64_t Offset = FrameInfo.getObjectOffset(Index);
+
+ // The carry-out lane of Add is unused, so it is safe to write with
+ // S_MOV_B32 even into a VGPR.
+ auto MaterializeCarryOutOffset = [&](MachineInstrBuilder &Add) {
+ Register ConstOffsetReg;
+ if (!isWave32)
+ ConstOffsetReg = getSubReg(Add.getReg(1), AMDGPU::sub0);
+ else
+ ConstOffsetReg = Add.getReg(1);
+ BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::S_MOV_B32), ConstOffsetReg)
+ .addImm(Offset);
+ return ConstOffsetReg;
+ };
+
if (Offset == 0) {
unsigned OpCode =
IsSALU && !LiveSCC ? AMDGPU::S_LSHR_B32 : AMDGPU::V_LSHRREV_B32_e64;
@@ -3430,17 +3444,7 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
assert(MIB->getOpcode() == AMDGPU::V_ADD_CO_U32_e64 &&
"Need to reuse carry out register");
- // Use scavenged unused carry out as offset register.
- Register ConstOffsetReg;
- if (!isWave32)
- ConstOffsetReg = getSubReg(MIB.getReg(1), AMDGPU::sub0);
- else
- ConstOffsetReg = MIB.getReg(1);
-
- BuildMI(*MBB, *MIB, DL, TII->get(AMDGPU::S_MOV_B32),
- ConstOffsetReg)
- .addImm(Offset);
- MIB.addReg(ConstOffsetReg, RegState::Kill);
+ MIB.addReg(MaterializeCarryOutOffset(MIB), RegState::Kill);
MIB.addReg(ScaledReg, RegState::Kill);
MIB.addImm(0); // clamp bit
}
@@ -3479,9 +3483,7 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
.addImm(ST.getWavefrontSizeLog2())
.addReg(FrameReg);
if (Add->getOpcode() == AMDGPU::V_ADD_CO_U32_e64) {
- BuildMI(*MBB, *Add, DL, TII->get(AMDGPU::S_MOV_B32), ResultReg)
- .addImm(Offset);
- Add.addReg(ResultReg, RegState::Kill)
+ Add.addReg(MaterializeCarryOutOffset(Add), RegState::Kill)
.addReg(TmpResultReg, RegState::Kill)
.addImm(0);
} else
diff --git a/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-s-mov-b32.mir b/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-s-mov-b32.mir
index 6cfa3a8e4d4e2..d87d93998ef74 100644
--- a/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-s-mov-b32.mir
+++ b/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-s-mov-b32.mir
@@ -1502,8 +1502,8 @@ body: |
; GFX8-NEXT: V_CMP_EQ_U32_e32 0, killed $vgpr0, implicit-def $vcc, implicit $exec
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 64
- ; GFX8-NEXT: $vgpr0, dead $sgpr0_sgpr1 = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr0 = S_MOV_B32 64
+ ; GFX8-NEXT: $vgpr0, dead $sgpr0_sgpr1 = V_ADD_CO_U32_e64 killed $sgpr0, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: S_ENDPGM 0, implicit $sgpr4, implicit $scc, implicit killed $vcc
;
@@ -1693,8 +1693,8 @@ body: |
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: BUFFER_STORE_DWORD_OFFSET killed $vgpr1, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr32, 132, 0, 0, implicit $exec :: ("amdgpu-thread-private" store (s32) into %stack.18, addrspace 5)
; GFX8-NEXT: $vgpr1 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 128
- ; GFX8-NEXT: $vgpr1, dead $sgpr6_sgpr7 = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr1, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr6 = S_MOV_B32 128
+ ; GFX8-NEXT: $vgpr1, dead $sgpr6_sgpr7 = V_ADD_CO_U32_e64 killed $sgpr6, killed $vgpr1, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr1, implicit $exec
; GFX8-NEXT: $vgpr1 = BUFFER_LOAD_DWORD_OFFSET $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr32, 132, 0, 0, implicit $exec :: ("amdgpu-thread-private" load (s32) from %stack.18, addrspace 5)
; GFX8-NEXT: S_NOP 0, implicit $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7
@@ -2469,8 +2469,8 @@ body: |
; GFX8-NEXT: V_CMP_EQ_U32_e32 0, killed $vgpr0, implicit-def $vcc, implicit $exec
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 24
- ; GFX8-NEXT: $vgpr0, dead $sgpr72_sgpr73 = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr72 = S_MOV_B32 24
+ ; GFX8-NEXT: $vgpr0, dead $sgpr72_sgpr73 = V_ADD_CO_U32_e64 killed $sgpr72, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: S_NOP 0, implicit $sgpr0_sgpr1_sgpr2_sgpr3_sgpr4_sgpr5_sgpr6_sgpr7
; GFX8-NEXT: S_NOP 0, implicit $sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15
@@ -2952,8 +2952,8 @@ body: |
; GFX8-NEXT: V_CMP_EQ_U32_e32 0, killed $vgpr0, implicit-def $vcc, implicit $exec
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 68
- ; GFX8-NEXT: $vgpr0, dead $sgpr72_sgpr73 = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr72 = S_MOV_B32 68
+ ; GFX8-NEXT: $vgpr0, dead $sgpr72_sgpr73 = V_ADD_CO_U32_e64 killed $sgpr72, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: S_NOP 0, implicit $sgpr0_sgpr1_sgpr2_sgpr3_sgpr4_sgpr5_sgpr6_sgpr7
; GFX8-NEXT: S_NOP 0, implicit $sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15
@@ -3360,3 +3360,195 @@ body: |
S_ENDPGM 0, implicit $sgpr4, implicit $scc, implicit killed $vcc
...
+
+# On gfx8 and older, materializing the offset with S_MOV_B32 into the
+# scavenged ResultReg (a VGPR, still undefined) let the scavenger alias it
+# with the shifted frame base, computing offset+offset instead of
+# base+offset. Use the add's unused carry-out register instead.
+
+---
+name: s_cselect_b32_fi_offset_scc_live
+tracksRegLiveness: true
+stack:
+ - { id: 0, size: 8, alignment: 8 }
+ - { id: 1, size: 4, alignment: 4 }
+machineFunctionInfo:
+ scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
+ frameOffsetReg: '$sgpr33'
+ stackPtrOffsetReg: '$sgpr32'
+body: |
+ bb.0:
+ ; GFX8-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX8: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX8-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX8-NEXT: $vcc_lo = S_MOV_B32 8
+ ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $vcc_lo, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr5 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX8-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX8-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX8-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX900-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX900: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX900-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX900-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX900-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX900-NEXT: $sgpr5 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX900-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX900-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX900-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX90A-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX90A: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX90A-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX90A-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX90A-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX90A-NEXT: $sgpr5 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX90A-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX90A-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX90A-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1010-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX1010: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1010-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1010-NEXT: $vgpr0 = V_LSHRREV_B32_e64 5, $sgpr32, implicit $exec
+ ; GFX1010-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX1010-NEXT: $sgpr5 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX1010-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX1010-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1010-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1100-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX1100: frame-setup CFI_INSTRUCTION escape 0x0f, 0x09, 0x90, 0x40, 0x94, 0x04, 0x35, 0x24, 0x36, 0xe9, 0x02
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1100-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1100-NEXT: $sgpr5 = S_ADDC_U32 $sgpr32, 8, implicit-def $scc, implicit $scc
+ ; GFX1100-NEXT: S_BITCMP1_B32 $sgpr5, 0, implicit-def $scc
+ ; GFX1100-NEXT: $sgpr5 = S_BITSET0_B32 0, $sgpr5
+ ; GFX1100-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX1100-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1100-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1200-LABEL: name: s_cselect_b32_fi_offset_scc_live
+ ; GFX1200: frame-setup CFI_INSTRUCTION escape 0x0f, 0x09, 0x90, 0x40, 0x94, 0x04, 0x35, 0x24, 0x36, 0xe9, 0x02
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1200-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1200-NEXT: $sgpr5 = S_ADDC_U32 $sgpr32, 8, implicit-def $scc, implicit $scc
+ ; GFX1200-NEXT: S_BITCMP1_B32 $sgpr5, 0, implicit-def $scc
+ ; GFX1200-NEXT: $sgpr5 = S_BITSET0_B32 0, $sgpr5
+ ; GFX1200-NEXT: renamable $sgpr4 = S_CSELECT_B32 killed $sgpr5, 0, implicit $scc
+ ; GFX1200-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1200-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ S_CMP_EQ_U32 0, 0, implicit-def $scc
+ renamable $sgpr4 = S_CSELECT_B32 %stack.1, 0, implicit $scc
+ renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ SI_RETURN implicit $sgpr4, implicit $sgpr5
+...
+---
+name: s_mov_b32_fi_offset_scc_live
+tracksRegLiveness: true
+stack:
+ - { id: 0, size: 8, alignment: 8 }
+ - { id: 1, size: 4, alignment: 4 }
+machineFunctionInfo:
+ scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
+ frameOffsetReg: '$sgpr33'
+ stackPtrOffsetReg: '$sgpr32'
+body: |
+ bb.0:
+ ; GFX8-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX8: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX8-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX8-NEXT: $vcc_lo = S_MOV_B32 8
+ ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $vcc_lo, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX8-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX8-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX900-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX900: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX900-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX900-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX900-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX900-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX900-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX900-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX900-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX90A-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX90A: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX90A-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX90A-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX90A-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
+ ; GFX90A-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX90A-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX90A-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX90A-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1010-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX1010: frame-setup CFI_INSTRUCTION llvm_def_aspace_cfa $sgpr32, 0, 6
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1010-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1010-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1010-NEXT: $vgpr0 = V_LSHRREV_B32_e64 5, $sgpr32, implicit $exec
+ ; GFX1010-NEXT: $vgpr0 = V_ADD_U32_e32 8, killed $vgpr0, implicit $exec
+ ; GFX1010-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; GFX1010-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1010-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1100-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX1100: frame-setup CFI_INSTRUCTION escape 0x0f, 0x09, 0x90, 0x40, 0x94, 0x04, 0x35, 0x24, 0x36, 0xe9, 0x02
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1100-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1100-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1100-NEXT: $sgpr5 = S_ADDC_U32 $sgpr32, 8, implicit-def $scc, implicit $scc
+ ; GFX1100-NEXT: S_BITCMP1_B32 $sgpr5, 0, implicit-def $scc
+ ; GFX1100-NEXT: $sgpr5 = S_BITSET0_B32 0, $sgpr5
+ ; GFX1100-NEXT: renamable $sgpr4 = S_MOV_B32 killed $sgpr5
+ ; GFX1100-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1100-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ ;
+ ; GFX1200-LABEL: name: s_mov_b32_fi_offset_scc_live
+ ; GFX1200: frame-setup CFI_INSTRUCTION escape 0x0f, 0x09, 0x90, 0x40, 0x94, 0x04, 0x35, 0x24, 0x36, 0xe9, 0x02
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION llvm_register_pair $pc_reg, $sgpr30, 32, $sgpr31, 32
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
+ ; GFX1200-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr5
+ ; GFX1200-NEXT: S_CMP_EQ_U32 0, 0, implicit-def $scc
+ ; GFX1200-NEXT: $sgpr5 = S_ADDC_U32 $sgpr32, 8, implicit-def $scc, implicit $scc
+ ; GFX1200-NEXT: S_BITCMP1_B32 $sgpr5, 0, implicit-def $scc
+ ; GFX1200-NEXT: $sgpr5 = S_BITSET0_B32 0, $sgpr5
+ ; GFX1200-NEXT: renamable $sgpr4 = S_MOV_B32 killed $sgpr5
+ ; GFX1200-NEXT: renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ ; GFX1200-NEXT: SI_RETURN implicit $sgpr4, implicit $sgpr5
+ S_CMP_EQ_U32 0, 0, implicit-def $scc
+ renamable $sgpr4 = S_MOV_B32 %stack.1
+ renamable $sgpr5 = S_CSELECT_B32 1, 2, implicit killed $scc
+ SI_RETURN implicit $sgpr4, implicit $sgpr5
+...
diff --git a/llvm/test/CodeGen/AMDGPU/frame-index.mir b/llvm/test/CodeGen/AMDGPU/frame-index.mir
index dbac27e35cf84..73c49d769fbd1 100644
--- a/llvm/test/CodeGen/AMDGPU/frame-index.mir
+++ b/llvm/test/CodeGen/AMDGPU/frame-index.mir
@@ -351,8 +351,8 @@ body: |
; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 64
- ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $vcc_lo = S_MOV_B32 64
+ ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $vcc_lo, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: S_ENDPGM 0, implicit $sgpr4, implicit $scc
;
@@ -405,8 +405,8 @@ body: |
; GFX8-NEXT: frame-setup CFI_INSTRUCTION undefined $sgpr4
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 68
- ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $vcc_lo = S_MOV_B32 68
+ ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $vcc_lo, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: S_ENDPGM 0, implicit $sgpr4, implicit $scc
;
@@ -543,8 +543,8 @@ body: |
; GFX8-NEXT: S_CMP_EQ_I32 $sgpr4, $sgpr5, implicit-def $scc
; GFX8-NEXT: BUFFER_STORE_DWORD_OFFSET killed $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr32, 68, 0, 0, implicit $exec :: ("amdgpu-thread-private" store (s32) into %stack.17, addrspace 5)
; GFX8-NEXT: $vgpr0 = V_LSHRREV_B32_e64 6, $sgpr32, implicit $exec
- ; GFX8-NEXT: $sgpr4 = S_MOV_B32 64
- ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $sgpr4, killed $vgpr0, 0, implicit $exec
+ ; GFX8-NEXT: $vcc_lo = S_MOV_B32 64
+ ; GFX8-NEXT: $vgpr0, dead $vcc = V_ADD_CO_U32_e64 killed $vcc_lo, killed $vgpr0, 0, implicit $exec
; GFX8-NEXT: $sgpr4 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
; GFX8-NEXT: $vgpr0 = BUFFER_LOAD_DWORD...
[truncated]
|
arsenm
reviewed
Aug 20, 2026
Comment on lines
+3379
to
+3383
| Register ConstOffsetReg; | ||
| if (!isWave32) | ||
| ConstOffsetReg = getSubReg(Add.getReg(1), AMDGPU::sub0); | ||
| else | ||
| ConstOffsetReg = Add.getReg(1); |
Contributor
There was a problem hiding this comment.
Assign from ternary operator
arsenm
approved these changes
Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Writing the offset into an undefined scavenged register let the scavenger alias it with another temp and corrupt the address