Skip to content

[AMDGPU] Fix eliminateFrameIndex clobbering a scavenged register - #217470

Merged
aobolensk merged 3 commits into
llvm:mainfrom
aobolensk:llvm-amdgpu-fix-frame-index-scavenge-alias
Aug 20, 2026
Merged

[AMDGPU] Fix eliminateFrameIndex clobbering a scavenged register#217470
aobolensk merged 3 commits into
llvm:mainfrom
aobolensk:llvm-amdgpu-fix-frame-index-scavenge-alias

Conversation

@aobolensk

Copy link
Copy Markdown
Contributor

Writing the offset into an undefined scavenged register let the scavenger alias it with another temp and corrupt the address

Writing the offset into an undefined scavenged register let the scavenger alias it with another temp and corrupt the address
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

Changes

Writing 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:

  • (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp (+16-14)
  • (modified) llvm/test/CodeGen/AMDGPU/eliminate-frame-index-s-mov-b32.mir (+200-8)
  • (modified) llvm/test/CodeGen/AMDGPU/frame-index.mir (+8-8)
  • (modified) llvm/test/CodeGen/AMDGPU/materialize-frame-index-sgpr.gfx10.ll (+8-8)
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]

Comment on lines +3379 to +3383
Register ConstOffsetReg;
if (!isWave32)
ConstOffsetReg = getSubReg(Add.getReg(1), AMDGPU::sub0);
else
ConstOffsetReg = Add.getReg(1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assign from ternary operator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@aobolensk
aobolensk merged commit 1171007 into llvm:main Aug 20, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants