[llvm] [AMDGPU/GISEL] Legalizing sub-dword scalar load for pre-gfx12 arch (PR #195800)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 23:51:34 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Abhinav Garg (abhigargrepo)
<details>
<summary>Changes</summary>
Pre-GFX12 sub targets lack native 8-bit and 16-bit scalar buffer load instructions. This patch extends legalizeSBufferLoad() to handle s8/s16 loads on these targets by widening the load to 32 bits (G_AMDGPU_S_BUFFER_LOAD) and inserting a G_TRUNC to recover the original narrow type, since sub-dword SGPR register types are not valid.
---
Full diff: https://github.com/llvm/llvm-project/pull/195800.diff
2 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp (+7)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.s.buffer.load.mir (+60)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index be5bc4da93b7d..842f746d99c56 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -7515,6 +7515,13 @@ bool AMDGPULegalizerInfo::legalizeSBufferLoad(LegalizerHelper &Helper,
// The 8-bit and 16-bit scalar buffer load instructions have 32-bit
// destination register.
Dst = B.getMRI()->createGenericVirtualRegister(LLT::scalar(32));
+ } else if (Size < 32) {
+ // No native sub-dword scalar buffer load on this subtarget.
+ // Widen to a 32-bit load; a G_TRUNC is inserted after to recover the
+ // original narrow type. s8/s16 are not valid SGPR register types.
+ assert(Size == 8 || Size == 16);
+ Opc = AMDGPU::G_AMDGPU_S_BUFFER_LOAD;
+ Dst = B.getMRI()->createGenericVirtualRegister(LLT::scalar(32));
} else {
Opc = AMDGPU::G_AMDGPU_S_BUFFER_LOAD;
Dst = OrigDst;
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.s.buffer.load.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.s.buffer.load.mir
index cbd9c2173b7e3..92f0b3eb695cc 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.s.buffer.load.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-llvm.amdgcn.s.buffer.load.mir
@@ -291,3 +291,63 @@ body: |
S_ENDPGM 0, implicit %2
...
+
+---
+name: s_buffer_load_s16
+body: |
+ bb.0:
+ liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+
+ ; GFX67-LABEL: name: s_buffer_load_s16
+ ; GFX67: liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX67-NEXT: {{ $}}
+ ; GFX67-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX67-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX67-NEXT: [[AMDGPU_S_BUFFER_LOAD:%[0-9]+]]:_(s32) = G_AMDGPU_S_BUFFER_LOAD [[COPY]](<4 x s32>), [[C]](s32), 0 :: (dereferenceable invariant load (s16))
+ ; GFX67-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[AMDGPU_S_BUFFER_LOAD]](s32)
+ ; GFX67-NEXT: S_ENDPGM 0, implicit [[TRUNC]](s16)
+ ;
+ ; GFX12-LABEL: name: s_buffer_load_s16
+ ; GFX12: liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX12-NEXT: {{ $}}
+ ; GFX12-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX12-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX12-NEXT: [[AMDGPU_S_BUFFER_LOAD_USHORT:%[0-9]+]]:_(s32) = G_AMDGPU_S_BUFFER_LOAD_USHORT [[COPY]](<4 x s32>), [[C]](s32), 0 :: (dereferenceable invariant load (s16))
+ ; GFX12-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[AMDGPU_S_BUFFER_LOAD_USHORT]](s32)
+ ; GFX12-NEXT: S_ENDPGM 0, implicit [[TRUNC]](s16)
+ %0:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ %1:_(s32) = G_CONSTANT i32 0
+ %2:_(s16) = G_INTRINSIC intrinsic(@llvm.amdgcn.s.buffer.load), %0, %1, 0
+ S_ENDPGM 0, implicit %2
+
+...
+
+---
+name: s_buffer_load_s8
+body: |
+ bb.0:
+ liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+
+ ; GFX67-LABEL: name: s_buffer_load_s8
+ ; GFX67: liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX67-NEXT: {{ $}}
+ ; GFX67-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX67-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX67-NEXT: [[AMDGPU_S_BUFFER_LOAD:%[0-9]+]]:_(s32) = G_AMDGPU_S_BUFFER_LOAD [[COPY]](<4 x s32>), [[C]](s32), 0 :: (dereferenceable invariant load (s8))
+ ; GFX67-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[AMDGPU_S_BUFFER_LOAD]](s32)
+ ; GFX67-NEXT: S_ENDPGM 0, implicit [[TRUNC]](s8)
+ ;
+ ; GFX12-LABEL: name: s_buffer_load_s8
+ ; GFX12: liveins: $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX12-NEXT: {{ $}}
+ ; GFX12-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ ; GFX12-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX12-NEXT: [[AMDGPU_S_BUFFER_LOAD_UBYTE:%[0-9]+]]:_(s32) = G_AMDGPU_S_BUFFER_LOAD_UBYTE [[COPY]](<4 x s32>), [[C]](s32), 0 :: (dereferenceable invariant load (s8))
+ ; GFX12-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[AMDGPU_S_BUFFER_LOAD_UBYTE]](s32)
+ ; GFX12-NEXT: S_ENDPGM 0, implicit [[TRUNC]](s8)
+ %0:_(<4 x s32>) = COPY $sgpr0_sgpr1_sgpr2_sgpr3
+ %1:_(s32) = G_CONSTANT i32 0
+ %2:_(s8) = G_INTRINSIC intrinsic(@llvm.amdgcn.s.buffer.load), %0, %1, 0
+ S_ENDPGM 0, implicit %2
+
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/195800
More information about the llvm-commits
mailing list