[llvm] [AMDGPU] Split negative global offsets into saddr and voffset on gfx1250 (PR #224527)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 23:22:50 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

gfx1250 sign extends the saddr vector offset, so a big negative constant fits in a VGPR and needs no 64-bit address add

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


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp (+5-3) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/flat-saddr-load.ll (+41-51) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 0d212f9dd39b2..6775ab4d0e104 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -2047,7 +2047,7 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N, SDValue Addr,
       Addr = LHS;
       ImmOffset = COffsetVal;
     } else if (!LHS->isDivergent()) {
-      if (COffsetVal > 0) {
+      if (COffsetVal != 0) {
         SDLoc SL(N);
         // saddr + large_offset -> saddr +
         //                         (voffset = large_offset & ~MaxOffset) +
@@ -2062,10 +2062,12 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N, SDValue Addr,
                                             : isUInt<32>(RemainderOffset)) {
           SDNode *VMov = CurDAG->getMachineNode(
               AMDGPU::V_MOV_B32_e32, SL, MVT::i32,
-              CurDAG->getTargetConstant(RemainderOffset, SDLoc(), MVT::i32));
+              CurDAG->getTargetConstant(Lo_32(RemainderOffset), SDLoc(),
+                                        MVT::i32));
           VOffset = SDValue(VMov, 0);
           SAddr = LHS;
-          Offset = CurDAG->getTargetConstant(SplitImmOffset, SDLoc(), MVT::i32);
+          Offset = CurDAG->getSignedTargetConstant(SplitImmOffset, SDLoc(),
+                                                   MVT::i32);
           return true;
         }
       }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index 140cf58e8fdd3..2bbd09497c774 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -6118,7 +6118,7 @@ AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root,
     } else {
       auto PtrBaseDef = getDefSrcRegIgnoringCopies(PtrBase, *MRI);
       if (isSGPR(PtrBaseDef->Reg)) {
-        if (ConstOffset > 0) {
+        if (ConstOffset != 0) {
           // Offset is too large.
           //
           // saddr + large_offset -> saddr +
diff --git a/llvm/test/CodeGen/AMDGPU/flat-saddr-load.ll b/llvm/test/CodeGen/AMDGPU/flat-saddr-load.ll
index 5fc001c848575..74b3935ae5cf9 100644
--- a/llvm/test/CodeGen/AMDGPU/flat-saddr-load.ll
+++ b/llvm/test/CodeGen/AMDGPU/flat-saddr-load.ll
@@ -90,45 +90,16 @@ define amdgpu_ps float @flat_load_saddr_i8_offset_neg8388608(ptr inreg %sbase) {
 
 ; SGPR base with maximum negative gfx1250 immediate offset -1
 define amdgpu_ps float @flat_load_saddr_i8_offset_neg8388609(ptr inreg %sbase) {
-; GFX1250-SDAG-LABEL: flat_load_saddr_i8_offset_neg8388609:
-; GFX1250-SDAG:       ; %bb.0:
-; GFX1250-SDAG-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; GFX1250-SDAG-NEXT:    s_mov_b64 s[64:65], 0
-; GFX1250-SDAG-NEXT:    v_nop
-; GFX1250-SDAG-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; GFX1250-SDAG-NEXT:    v_add_co_u32 v0, s0, 0xff800000, s2
-; GFX1250-SDAG-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX1250-SDAG-NEXT:    v_add_co_ci_u32_e64 v1, null, -1, s3, s0
-; GFX1250-SDAG-NEXT:    flat_load_u8 v0, v[0:1] offset:-1
-; GFX1250-SDAG-NEXT:    s_wait_loadcnt_dscnt 0x0
-; GFX1250-SDAG-NEXT:    ; return to shader part epilog
-;
-; GFX1250-GISEL-LABEL: flat_load_saddr_i8_offset_neg8388609:
-; GFX1250-GISEL:       ; %bb.0:
-; GFX1250-GISEL-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; GFX1250-GISEL-NEXT:    s_mov_b64 s[64:65], 0
-; GFX1250-GISEL-NEXT:    v_nop
-; GFX1250-GISEL-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; GFX1250-GISEL-NEXT:    s_add_co_u32 s0, s2, 0xff7fffff
-; GFX1250-GISEL-NEXT:    s_add_co_ci_u32 s1, s3, -1
-; GFX1250-GISEL-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
-; GFX1250-GISEL-NEXT:    v_mov_b64_e32 v[0:1], s[0:1]
-; GFX1250-GISEL-NEXT:    flat_load_u8 v0, v[0:1]
-; GFX1250-GISEL-NEXT:    s_wait_loadcnt_dscnt 0x0
-; GFX1250-GISEL-NEXT:    ; return to shader part epilog
-;
-; GFX1250-NOECC-LABEL: flat_load_saddr_i8_offset_neg8388609:
-; GFX1250-NOECC:       ; %bb.0:
-; GFX1250-NOECC-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
-; GFX1250-NOECC-NEXT:    s_mov_b64 s[64:65], 0
-; GFX1250-NOECC-NEXT:    v_nop
-; GFX1250-NOECC-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; GFX1250-NOECC-NEXT:    v_add_co_u32 v0, s0, 0xff800000, s2
-; GFX1250-NOECC-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX1250-NOECC-NEXT:    v_add_co_ci_u32_e64 v1, null, -1, s3, s0
-; GFX1250-NOECC-NEXT:    flat_load_u8 v0, v[0:1] offset:-1
-; GFX1250-NOECC-NEXT:    s_wait_loadcnt_dscnt 0x0
-; GFX1250-NOECC-NEXT:    ; return to shader part epilog
+; GFX1250-LABEL: flat_load_saddr_i8_offset_neg8388609:
+; GFX1250:       ; %bb.0:
+; GFX1250-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1250-NEXT:    s_mov_b64 s[64:65], 0
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; GFX1250-NEXT:    v_mov_b32_e32 v0, 0xff800000
+; GFX1250-NEXT:    flat_load_u8 v0, v0, s[2:3] offset:-1
+; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX1250-NEXT:    ; return to shader part epilog
   %gep0 = getelementptr inbounds i8, ptr %sbase, i64 -8388609
   %load = load i8, ptr %gep0
   %zext = zext i8 %load to i32
@@ -136,6 +107,25 @@ define amdgpu_ps float @flat_load_saddr_i8_offset_neg8388609(ptr inreg %sbase) {
   ret float %to.vgpr
 }
 
+; SGPR base with a negative offset needing more than one immediate range
+define amdgpu_ps float @flat_load_saddr_i8_offset_neg16777220(ptr inreg %sbase) {
+; GFX1250-LABEL: flat_load_saddr_i8_offset_neg16777220:
+; GFX1250:       ; %bb.0:
+; GFX1250-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1250-NEXT:    s_mov_b64 s[64:65], 0
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; GFX1250-NEXT:    v_mov_b32_e32 v0, 0xff000000
+; GFX1250-NEXT:    flat_load_u8 v0, v0, s[2:3] offset:-4
+; GFX1250-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX1250-NEXT:    ; return to shader part epilog
+  %gep0 = getelementptr inbounds i8, ptr %sbase, i64 -16777220
+  %load = load i8, ptr %gep0
+  %zext = zext i8 %load to i32
+  %to.vgpr = bitcast i32 %zext to float
+  ret float %to.vgpr
+}
+
 define amdgpu_ps float @flat_load_saddr_i8_offset_0xFFFFFFFF(ptr inreg %sbase) {
 ; GFX1250-SDAG-LABEL: flat_load_saddr_i8_offset_0xFFFFFFFF:
 ; GFX1250-SDAG:       ; %bb.0:
@@ -6099,7 +6089,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-SDAG-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-SDAG-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-SDAG-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-SDAG-NEXT:  .LBB116_1: ; %bb3
+; GFX1250-SDAG-NEXT:  .LBB117_1: ; %bb3
 ; GFX1250-SDAG-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-SDAG-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-SDAG-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6107,7 +6097,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-SDAG-NEXT:    s_add_co_i32 s0, s0, -1
 ; GFX1250-SDAG-NEXT:    s_add_nc_u64 s[2:3], s[2:3], 4
 ; GFX1250-SDAG-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-SDAG-NEXT:    s_cbranch_scc0 .LBB116_1
+; GFX1250-SDAG-NEXT:    s_cbranch_scc0 .LBB117_1
 ; GFX1250-SDAG-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-SDAG-NEXT:    s_endpgm
 ;
@@ -6119,7 +6109,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-GISEL-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-GISEL-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-GISEL-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-GISEL-NEXT:  .LBB116_1: ; %bb3
+; GFX1250-GISEL-NEXT:  .LBB117_1: ; %bb3
 ; GFX1250-GISEL-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-GISEL-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-GISEL-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6128,7 +6118,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-GISEL-NEXT:    s_add_co_u32 s2, s2, 4
 ; GFX1250-GISEL-NEXT:    s_add_co_ci_u32 s3, s3, 0
 ; GFX1250-GISEL-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-GISEL-NEXT:    s_cbranch_scc0 .LBB116_1
+; GFX1250-GISEL-NEXT:    s_cbranch_scc0 .LBB117_1
 ; GFX1250-GISEL-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-GISEL-NEXT:    s_endpgm
 ;
@@ -6140,7 +6130,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-NOECC-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-NOECC-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-NOECC-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-NOECC-NEXT:  .LBB116_1: ; %bb3
+; GFX1250-NOECC-NEXT:  .LBB117_1: ; %bb3
 ; GFX1250-NOECC-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-NOECC-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-NOECC-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6148,7 +6138,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv(ptr inreg %arg) {
 ; GFX1250-NOECC-NEXT:    s_add_co_i32 s0, s0, -1
 ; GFX1250-NOECC-NEXT:    s_add_nc_u64 s[2:3], s[2:3], 4
 ; GFX1250-NOECC-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-NOECC-NEXT:    s_cbranch_scc0 .LBB116_1
+; GFX1250-NOECC-NEXT:    s_cbranch_scc0 .LBB117_1
 ; GFX1250-NOECC-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-NOECC-NEXT:    s_endpgm
 bb:
@@ -6178,7 +6168,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-SDAG-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-SDAG-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-SDAG-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-SDAG-NEXT:  .LBB117_1: ; %bb3
+; GFX1250-SDAG-NEXT:  .LBB118_1: ; %bb3
 ; GFX1250-SDAG-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-SDAG-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-SDAG-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6188,7 +6178,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-SDAG-NEXT:    s_add_co_i32 s0, s0, -1
 ; GFX1250-SDAG-NEXT:    s_add_nc_u64 s[2:3], s[2:3], 4
 ; GFX1250-SDAG-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-SDAG-NEXT:    s_cbranch_scc0 .LBB117_1
+; GFX1250-SDAG-NEXT:    s_cbranch_scc0 .LBB118_1
 ; GFX1250-SDAG-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-SDAG-NEXT:    s_endpgm
 ;
@@ -6200,7 +6190,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-GISEL-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-GISEL-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-GISEL-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-GISEL-NEXT:  .LBB117_1: ; %bb3
+; GFX1250-GISEL-NEXT:  .LBB118_1: ; %bb3
 ; GFX1250-GISEL-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-GISEL-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-GISEL-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6211,7 +6201,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-GISEL-NEXT:    s_add_co_u32 s2, s2, 4
 ; GFX1250-GISEL-NEXT:    s_add_co_ci_u32 s3, s3, 0
 ; GFX1250-GISEL-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-GISEL-NEXT:    s_cbranch_scc0 .LBB117_1
+; GFX1250-GISEL-NEXT:    s_cbranch_scc0 .LBB118_1
 ; GFX1250-GISEL-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-GISEL-NEXT:    s_endpgm
 ;
@@ -6223,7 +6213,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-NOECC-NEXT:    global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
 ; GFX1250-NOECC-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX1250-NOECC-NEXT:    s_movk_i32 s0, 0x100
-; GFX1250-NOECC-NEXT:  .LBB117_1: ; %bb3
+; GFX1250-NOECC-NEXT:  .LBB118_1: ; %bb3
 ; GFX1250-NOECC-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GFX1250-NOECC-NEXT:    s_wait_dscnt 0x0
 ; GFX1250-NOECC-NEXT:    flat_load_b32 v1, v0, s[2:3] scope:SCOPE_SYS
@@ -6233,7 +6223,7 @@ define amdgpu_ps void @flat_addr_64bit_lsr_iv_multiload(ptr inreg %arg, ptr inre
 ; GFX1250-NOECC-NEXT:    s_add_co_i32 s0, s0, -1
 ; GFX1250-NOECC-NEXT:    s_add_nc_u64 s[2:3], s[2:3], 4
 ; GFX1250-NOECC-NEXT:    s_cmp_eq_u32 s0, 0
-; GFX1250-NOECC-NEXT:    s_cbranch_scc0 .LBB117_1
+; GFX1250-NOECC-NEXT:    s_cbranch_scc0 .LBB118_1
 ; GFX1250-NOECC-NEXT:  ; %bb.2: ; %bb2
 ; GFX1250-NOECC-NEXT:    s_endpgm
 bb:

``````````

</details>


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


More information about the llvm-commits mailing list