[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