[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