[llvm] [AMDGPU] Fix s_buffer_load crash for illegal result types (PR #215483)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 00:24:18 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

i1, i4, v2i1, v3i16, v6i8, and i128 had no SBUFFER_LOAD selection pattern and crashed

Load a legal i32/vNi32 carrier instead and narrow/bitcast down to the requested type

---

Patch is 25.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215483.diff


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+33-43) 
- (added) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll (+507) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index fb5c4279af4b7..ad19049f39d0c 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -1017,7 +1017,8 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::INTRINSIC_WO_CHAIN,
                      {MVT::Other, MVT::f32, MVT::v4f32, MVT::i16, MVT::f16,
                       MVT::bf16, MVT::v2i16, MVT::v2f16, MVT::v2bf16, MVT::i128,
-                      MVT::i8},
+                      MVT::i8, MVT::i1, MVT::i4, MVT::v2i1, MVT::v3i16,
+                      MVT::v6i8},
                      Custom);
 
   setOperationAction(ISD::INTRINSIC_W_CHAIN,
@@ -8404,53 +8405,15 @@ void SITargetLowering::ReplaceNodeResults(SDNode *N,
       return;
     }
     case Intrinsic::amdgcn_s_buffer_load: {
-      // Lower llvm.amdgcn.s.buffer.load.(i8, u8) intrinsics. First, we generate
-      // s_buffer_load_u8 for signed and unsigned load instructions. Next, DAG
-      // combiner tries to merge the s_buffer_load_u8 with a sext instruction
-      // (performSignExtendInRegCombine()) and it replaces s_buffer_load_u8 with
-      // s_buffer_load_i8.
-      if (!Subtarget->hasScalarSubwordLoads())
-        return;
+      // lowerSBuffer already handles every illegal result type.
       SDValue Op = SDValue(N, 0);
       SDValue Rsrc = Op.getOperand(1);
       SDValue Offset = Op.getOperand(2);
       SDValue CachePolicy = Op.getOperand(3);
       EVT VT = Op.getValueType();
-      assert(VT == MVT::i8 && "Expected 8-bit s_buffer_load intrinsics.\n");
       SDLoc DL(Op);
-      MachineFunction &MF = DAG.getMachineFunction();
-      const DataLayout &DataLayout = DAG.getDataLayout();
-      Align Alignment =
-          DataLayout.getABITypeAlign(VT.getTypeForEVT(*DAG.getContext()));
-      MachineMemOperand *MMO = MF.getMachineMemOperand(
-          MachinePointerInfo(),
-          MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
-              MachineMemOperand::MOInvariant,
-          VT.getStoreSize(), Alignment);
-      SDValue LoadVal;
-      if (!Offset->isDivergent()) {
-        SDValue Ops[] = {DAG.getEntryNode(), // Chain
-                         Rsrc,               // source register
-                         Offset, CachePolicy};
-        SDValue BufferLoad = DAG.getMemIntrinsicNode(
-            AMDGPUISD::SBUFFER_LOAD_UBYTE, DL,
-            DAG.getVTList(MVT::i32, MVT::Other), Ops, VT, MMO);
-        LoadVal = DAG.getNode(ISD::TRUNCATE, DL, VT, BufferLoad);
-      } else {
-        SDValue Ops[] = {
-            DAG.getEntryNode(),                    // Chain
-            Rsrc,                                  // rsrc
-            DAG.getConstant(0, DL, MVT::i32),      // vindex
-            {},                                    // voffset
-            {},                                    // soffset
-            {},                                    // offset
-            CachePolicy,                           // cachepolicy
-            DAG.getTargetConstant(0, DL, MVT::i1), // idxen
-        };
-        setBufferOffsets(Offset, DAG, &Ops[3], Align(4));
-        LoadVal = handleByteShortBufferLoads(DAG, VT, DL, Ops, MMO);
-      }
-      Results.push_back(LoadVal);
+      Results.push_back(lowerSBuffer(VT, VT, DL, DAG.getEntryNode(), Rsrc,
+                                     Offset, CachePolicy, DAG));
       return;
     }
     case Intrinsic::amdgcn_dead: {
@@ -10884,8 +10847,9 @@ SDValue SITargetLowering::lowerSBuffer(EVT VT, EVT MemVT, SDLoc DL,
     if (MemVT == MVT::i16 && Subtarget->hasScalarSubwordLoads())
       return HandleScalarSubwordLoads(AMDGPUISD::SBUFFER_LOAD_USHORT);
 
-    // Widen vec3 load to vec4.
+    // Widen vec3 load to vec4. Only 32-bit elements have a vec4 pattern.
     if (VT.isVector() && VT.getVectorNumElements() == 3 &&
+        VT.getVectorElementType().getSizeInBits() == 32 &&
         !Subtarget->hasScalarDwordx3Loads()) {
       EVT WidenedVT =
           EVT::getVectorVT(*DAG.getContext(), VT.getVectorElementType(), 4);
@@ -10900,6 +10864,32 @@ SDValue SITargetLowering::lowerSBuffer(EVT VT, EVT MemVT, SDLoc DL,
       return Subvector;
     }
 
+    // No SBUFFER_LOAD pattern for this width (i1 is a legal type but still
+    // has none). Load a legal i32/vNi32 carrier and narrow/bitcast down.
+    if ((!isTypeLegal(VT) || VT == MVT::i1) && MemVT == VT) {
+      unsigned Bits = VT.getSizeInBits();
+      EVT CarrierVT = Bits <= 32 ? EVT(MVT::i32)
+                                 : EVT::getVectorVT(*DAG.getContext(), MVT::i32,
+                                                    divideCeil(Bits, 32));
+      SDValue CarrierLoad = DAG.getMemIntrinsicNode(
+          AMDGPUISD::SBUFFER_LOAD, DL, DAG.getVTList(CarrierVT, MVT::Other),
+          Ops, CarrierVT,
+          MF.getMachineMemOperand(MMO, 0, CarrierVT.getStoreSize()));
+      EVT CarrierIntVT =
+          EVT::getIntegerVT(*DAG.getContext(), CarrierVT.getSizeInBits());
+      SDValue AsInt = DAG.getNode(ISD::BITCAST, DL, CarrierIntVT, CarrierLoad);
+      EVT NarrowIntVT = EVT::getIntegerVT(*DAG.getContext(), Bits);
+      SDValue Narrow = NarrowIntVT == CarrierIntVT
+                           ? AsInt
+                           : DAG.getNode(ISD::TRUNCATE, DL, NarrowIntVT, AsInt);
+      SDValue Result = VT == NarrowIntVT
+                           ? Narrow
+                           : DAG.getNode(ISD::BITCAST, DL, VT, Narrow);
+      if (HasChainResult)
+        return DAG.getMergeValues({Result, CarrierLoad.getValue(1)}, DL);
+      return Result;
+    }
+
     return DAG.getMemIntrinsicNode(AMDGPUISD::SBUFFER_LOAD, DL,
                                    DAG.getVTList(VT, MVT::Other), Ops, MemVT,
                                    MMO);
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll
new file mode 100644
index 0000000000000..91ee72335474d
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll
@@ -0,0 +1,507 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=amdgpu6.00 | FileCheck %s -check-prefixes=GFX67,GFX6
+; RUN: llc < %s -mtriple=amdgpu7.01 | FileCheck %s -check-prefixes=GFX67,GFX7
+; RUN: llc < %s -mtriple=amdgpu8.02 | FileCheck %s -check-prefixes=GFX8
+; RUN: llc < %s -mtriple=amdgpu9.00 | FileCheck %s -check-prefixes=GFX910,GFX9
+; RUN: llc < %s -mtriple=amdgpu10.10 | FileCheck %s -check-prefixes=GFX910,GFX10
+; RUN: llc < %s -mtriple=amdgpu11.00 -amdgpu-enable-vopd=0 | FileCheck %s -check-prefixes=GFX11
+; RUN: llc < %s -mtriple=amdgpu12.00 -amdgpu-enable-vopd=0 | FileCheck %s -check-prefixes=GFX1200
+; RUN: llc < %s -mtriple=amdgpu12.50 -amdgpu-enable-vopd=0 -mattr=-wait-xcnt | FileCheck %s -check-prefixes=GFX1250
+
+; Result types with no direct SBUFFER_LOAD pattern used to ICE in the type
+; legalizer. GlobalISel is not covered: it hits a separate, pre-existing
+; assertion in AMDGPULegalizerInfo::legalizeSBufferLoad for these widths.
+
+define amdgpu_ps void @s_buffer_load_i1(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+; GFX67-LABEL: s_buffer_load_i1:
+; GFX67:       ; %bb.0: ; %main_body
+; GFX67-NEXT:    s_buffer_load_dword s4, s[0:3], 0x0
+; GFX67-NEXT:    s_mov_b32 s2, 0
+; GFX67-NEXT:    s_mov_b32 s3, 0xf000
+; GFX67-NEXT:    s_mov_b32 s0, s2
+; GFX67-NEXT:    s_mov_b32 s1, s2
+; GFX67-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX67-NEXT:    s_and_b32 s4, s4, 1
+; GFX67-NEXT:    v_mov_b32_e32 v2, s4
+; GFX67-NEXT:    buffer_store_byte v2, v[0:1], s[0:3], 0 addr64
+; GFX67-NEXT:    s_endpgm
+;
+; GFX8-LABEL: s_buffer_load_i1:
+; GFX8:       ; %bb.0: ; %main_body
+; GFX8-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_and_b32 s0, s0, 1
+; GFX8-NEXT:    v_mov_b32_e32 v2, s0
+; GFX8-NEXT:    flat_store_byte v[0:1], v2
+; GFX8-NEXT:    s_endpgm
+;
+; GFX910-LABEL: s_buffer_load_i1:
+; GFX910:       ; %bb.0: ; %main_body
+; GFX910-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX910-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX910-NEXT:    s_and_b32 s0, s0, 1
+; GFX910-NEXT:    v_mov_b32_e32 v2, s0
+; GFX910-NEXT:    global_store_byte v[0:1], v2, off
+; GFX910-NEXT:    s_endpgm
+;
+; GFX11-LABEL: s_buffer_load_i1:
+; GFX11:       ; %bb.0: ; %main_body
+; GFX11-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX11-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX11-NEXT:    s_and_b32 s0, s0, 1
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT:    v_mov_b32_e32 v2, s0
+; GFX11-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX11-NEXT:    s_endpgm
+;
+; GFX1200-LABEL: s_buffer_load_i1:
+; GFX1200:       ; %bb.0: ; %main_body
+; GFX1200-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX1200-NEXT:    s_wait_kmcnt 0x0
+; GFX1200-NEXT:    s_and_b32 s0, s0, 1
+; GFX1200-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1200-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1200-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1200-NEXT:    s_endpgm
+;
+; GFX1250-LABEL: s_buffer_load_i1:
+; GFX1250:       ; %bb.0: ; %main_body
+; GFX1250-NEXT:    global_prefetch_b8 v0, null scope:SCOPE_SE
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0 nv
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    s_and_b32 s0, s0, 1
+; GFX1250-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1250-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1250-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1250-NEXT:    s_endpgm
+main_body:
+  %load = call i1 @llvm.amdgcn.s.buffer.load.i1(<4 x i32> %desc, i32 0, i32 0)
+  store i1 %load, ptr addrspace(1) %out
+  ret void
+}
+
+define amdgpu_ps void @s_buffer_load_i4(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+; GFX67-LABEL: s_buffer_load_i4:
+; GFX67:       ; %bb.0: ; %main_body
+; GFX67-NEXT:    s_buffer_load_dword s4, s[0:3], 0x0
+; GFX67-NEXT:    s_mov_b32 s2, 0
+; GFX67-NEXT:    s_mov_b32 s3, 0xf000
+; GFX67-NEXT:    s_mov_b32 s0, s2
+; GFX67-NEXT:    s_mov_b32 s1, s2
+; GFX67-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX67-NEXT:    s_and_b32 s4, s4, 15
+; GFX67-NEXT:    v_mov_b32_e32 v2, s4
+; GFX67-NEXT:    buffer_store_byte v2, v[0:1], s[0:3], 0 addr64
+; GFX67-NEXT:    s_endpgm
+;
+; GFX8-LABEL: s_buffer_load_i4:
+; GFX8:       ; %bb.0: ; %main_body
+; GFX8-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_and_b32 s0, s0, 15
+; GFX8-NEXT:    v_mov_b32_e32 v2, s0
+; GFX8-NEXT:    flat_store_byte v[0:1], v2
+; GFX8-NEXT:    s_endpgm
+;
+; GFX910-LABEL: s_buffer_load_i4:
+; GFX910:       ; %bb.0: ; %main_body
+; GFX910-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX910-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX910-NEXT:    s_and_b32 s0, s0, 15
+; GFX910-NEXT:    v_mov_b32_e32 v2, s0
+; GFX910-NEXT:    global_store_byte v[0:1], v2, off
+; GFX910-NEXT:    s_endpgm
+;
+; GFX11-LABEL: s_buffer_load_i4:
+; GFX11:       ; %bb.0: ; %main_body
+; GFX11-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX11-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX11-NEXT:    s_and_b32 s0, s0, 15
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT:    v_mov_b32_e32 v2, s0
+; GFX11-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX11-NEXT:    s_endpgm
+;
+; GFX1200-LABEL: s_buffer_load_i4:
+; GFX1200:       ; %bb.0: ; %main_body
+; GFX1200-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX1200-NEXT:    s_wait_kmcnt 0x0
+; GFX1200-NEXT:    s_and_b32 s0, s0, 15
+; GFX1200-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1200-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1200-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1200-NEXT:    s_endpgm
+;
+; GFX1250-LABEL: s_buffer_load_i4:
+; GFX1250:       ; %bb.0: ; %main_body
+; GFX1250-NEXT:    global_prefetch_b8 v0, null scope:SCOPE_SE
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0 nv
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    s_and_b32 s0, s0, 15
+; GFX1250-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1250-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1250-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1250-NEXT:    s_endpgm
+main_body:
+  %load = call i4 @llvm.amdgcn.s.buffer.load.i4(<4 x i32> %desc, i32 0, i32 0)
+  store i4 %load, ptr addrspace(1) %out
+  ret void
+}
+
+define amdgpu_ps void @s_buffer_load_v2i1(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+; GFX67-LABEL: s_buffer_load_v2i1:
+; GFX67:       ; %bb.0: ; %main_body
+; GFX67-NEXT:    s_buffer_load_dword s4, s[0:3], 0x0
+; GFX67-NEXT:    s_mov_b32 s2, 0
+; GFX67-NEXT:    s_mov_b32 s3, 0xf000
+; GFX67-NEXT:    s_mov_b32 s0, s2
+; GFX67-NEXT:    s_mov_b32 s1, s2
+; GFX67-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX67-NEXT:    s_and_b32 s4, s4, 3
+; GFX67-NEXT:    v_mov_b32_e32 v2, s4
+; GFX67-NEXT:    buffer_store_byte v2, v[0:1], s[0:3], 0 addr64
+; GFX67-NEXT:    s_endpgm
+;
+; GFX8-LABEL: s_buffer_load_v2i1:
+; GFX8:       ; %bb.0: ; %main_body
+; GFX8-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    s_and_b32 s0, s0, 3
+; GFX8-NEXT:    v_mov_b32_e32 v2, s0
+; GFX8-NEXT:    flat_store_byte v[0:1], v2
+; GFX8-NEXT:    s_endpgm
+;
+; GFX910-LABEL: s_buffer_load_v2i1:
+; GFX910:       ; %bb.0: ; %main_body
+; GFX910-NEXT:    s_buffer_load_dword s0, s[0:3], 0x0
+; GFX910-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX910-NEXT:    s_and_b32 s0, s0, 3
+; GFX910-NEXT:    v_mov_b32_e32 v2, s0
+; GFX910-NEXT:    global_store_byte v[0:1], v2, off
+; GFX910-NEXT:    s_endpgm
+;
+; GFX11-LABEL: s_buffer_load_v2i1:
+; GFX11:       ; %bb.0: ; %main_body
+; GFX11-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX11-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX11-NEXT:    s_and_b32 s0, s0, 3
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT:    v_mov_b32_e32 v2, s0
+; GFX11-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX11-NEXT:    s_endpgm
+;
+; GFX1200-LABEL: s_buffer_load_v2i1:
+; GFX1200:       ; %bb.0: ; %main_body
+; GFX1200-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0
+; GFX1200-NEXT:    s_wait_kmcnt 0x0
+; GFX1200-NEXT:    s_and_b32 s0, s0, 3
+; GFX1200-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1200-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1200-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1200-NEXT:    s_endpgm
+;
+; GFX1250-LABEL: s_buffer_load_v2i1:
+; GFX1250:       ; %bb.0: ; %main_body
+; GFX1250-NEXT:    global_prefetch_b8 v0, null scope:SCOPE_SE
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    s_buffer_load_b32 s0, s[0:3], 0x0 nv
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    s_and_b32 s0, s0, 3
+; GFX1250-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX1250-NEXT:    v_mov_b32_e32 v2, s0
+; GFX1250-NEXT:    global_store_b8 v[0:1], v2, off
+; GFX1250-NEXT:    s_endpgm
+main_body:
+  %load = call <2 x i1> @llvm.amdgcn.s.buffer.load.v2i1(<4 x i32> %desc, i32 0, i32 0)
+  store <2 x i1> %load, ptr addrspace(1) %out
+  ret void
+}
+
+define amdgpu_ps void @s_buffer_load_v3i16(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+; GFX6-LABEL: s_buffer_load_v3i16:
+; GFX6:       ; %bb.0: ; %main_body
+; GFX6-NEXT:    s_buffer_load_dwordx2 s[4:5], s[0:3], 0x0
+; GFX6-NEXT:    s_mov_b32 s2, 0
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s0, s2
+; GFX6-NEXT:    s_mov_b32 s1, s2
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    v_mov_b32_e32 v2, s5
+; GFX6-NEXT:    buffer_store_short v2, v[0:1], s[0:3], 0 addr64 offset:4
+; GFX6-NEXT:    s_waitcnt expcnt(0)
+; GFX6-NEXT:    v_mov_b32_e32 v2, s4
+; GFX6-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
+; GFX6-NEXT:    s_endpgm
+;
+; GFX7-LABEL: s_buffer_load_v3i16:
+; GFX7:       ; %bb.0: ; %main_body
+; GFX7-NEXT:    s_buffer_load_dwordx2 s[4:5], s[0:3], 0x0
+; GFX7-NEXT:    s_mov_b32 s2, 0
+; GFX7-NEXT:    s_mov_b32 s3, 0xf000
+; GFX7-NEXT:    s_mov_b32 s0, s2
+; GFX7-NEXT:    s_mov_b32 s1, s2
+; GFX7-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX7-NEXT:    v_mov_b32_e32 v2, s5
+; GFX7-NEXT:    buffer_store_short v2, v[0:1], s[0:3], 0 addr64 offset:4
+; GFX7-NEXT:    v_mov_b32_e32 v2, s4
+; GFX7-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
+; GFX7-NEXT:    s_endpgm
+;
+; GFX8-LABEL: s_buffer_load_v3i16:
+; GFX8:       ; %bb.0: ; %main_body
+; GFX8-NEXT:    s_buffer_load_dwordx2 s[0:1], s[0:3], 0x0
+; GFX8-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; GFX8-NEXT:    v_addc_u32_e32 v3, vcc, 0, v1, vcc
+; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX8-NEXT:    v_mov_b32_e32 v4, s1
+; GFX8-NEXT:    flat_store_short v[2:3], v4
+; GFX8-NEXT:    v_mov_b32_e32 v2, s0
+; GFX8-NEXT:    flat_store_dword v[0:1], v2
+; GFX8-NEXT:    s_endpgm
+;
+; GFX9-LABEL: s_buffer_load_v3i16:
+; GFX9:       ; %bb.0: ; %main_body
+; GFX9-NEXT:    s_buffer_load_dwordx2 s[0:1], s[0:3], 0x0
+; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX9-NEXT:    v_mov_b32_e32 v2, s1
+; GFX9-NEXT:    global_store_short v[0:1], v2, off offset:4
+; GFX9-NEXT:    v_mov_b32_e32 v2, s0
+; GFX9-NEXT:    global_store_dword v[0:1], v2, off
+; GFX9-NEXT:    s_endpgm
+;
+; GFX10-LABEL: s_buffer_load_v3i16:
+; GFX10:       ; %bb.0: ; %main_body
+; GFX10-NEXT:    s_buffer_load_dwordx2 s[0:1], s[0:3], 0x0
+; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX10-NEXT:    v_mov_b32_e32 v2, s1
+; GFX10-NEXT:    v_mov_b32_e32 v3, s0
+; GFX10-NEXT:    global_store_short v[0:1], v2, off offset:4
+; GFX10-NEXT:    global_store_dword v[0:1], v3, off
+; GFX10-NEXT:    s_endpgm
+;
+; GFX11-LABEL: s_buffer_load_v3i16:
+; GFX11:       ; %bb.0: ; %main_body
+; GFX11-NEXT:    s_buffer_load_b64 s[0:1], s[0:3], 0x0
+; GFX11-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX11-NEXT:    v_mov_b32_e32 v2, s1
+; GFX11-NEXT:    v_mov_b32_e32 v3, s0
+; GFX11-NEXT:    s_clause 0x1
+; GFX11-NEXT:    global_store_b16 v[0:1], v2, off offset:4
+; GFX11-NEXT:    global_store_b32 v[0:1], v3, off
+; GFX11-NEXT:    s_endpgm
+;
+; GFX1200-LABEL: s_buffer_load_v3i16:
+; GFX1200:       ; %bb.0: ; %main_body
+; GFX1200-NEXT:    s_buffer_load_b64 s[0:1], s[0:3], 0x0
+; GFX1200-NEXT:    s_wait_kmcnt 0x0
+; GFX1200-NEXT:    v_mov_b32_e32 v2, s1
+; GFX1200-NEXT:    v_mov_b32_e32 v3, s0
+; GFX1200-NEXT:    s_clause 0x1
+; GFX1200-NEXT:    global_store_b16 v[0:1], v2, off offset:4
+; GFX1200-NEXT:    global_store_b32 v[0:1], v3, off
+; GFX1200-NEXT:    s_endpgm
+;
+; GFX1250-LABEL: s_buffer_load_v3i16:
+; GFX1250:       ; %bb.0: ; %main_body
+; GFX1250-NEXT:    global_prefetch_b8 v0, null scope:SCOPE_SE
+; GFX1250-NEXT:    v_nop
+; GFX1250-NEXT:    s_buffer_load_b64 s[0:1], s[0:3], 0x0 nv
+; GFX1250-NEXT:    s_wait_kmcnt 0x0
+; GFX1250-NEXT:    v_mov_b32_e32 v2, s1
+; GFX1250-NEXT:    v_mov_b32_e32 v3, s0
+; GFX1250-NEXT:    s_clause 0x1
+; GFX1250-NEXT:    global_store_b16 v[0:1], v2, off offset:4
+; GFX1250-NEXT:    global_store_b32 v[0:1], v3, off
+; GFX1250-NEXT:    s_endpgm
+main_body:
+  %load = call <3 x i16> @llvm.amdgcn.s.buffer.load.v3i16(<4 x i32> %desc, i32 0, i32 0)
+  store <3 x i16> %load, ptr addrspace(1) %out
+  ret void
+}
+
+define amdgpu_ps void @s_buffer_load_v6i8(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+; GFX6-LABEL: s_buffer_load_v6i8:
+; GFX6:       ; %bb.0: ; %main_body
+; GFX6-NEXT:    s_buffer_load_dwordx2 s[4:5], s[0:3], 0x0
+; GFX6-NEXT:    s_mov_b32 s2, 0
+; GFX6-NEXT:    s_mov_b32 s3, 0xf000
+; GFX6-NEXT:    s_mov_b32 s0, s2
+; GFX6-NEXT:    s_mov_b32 s1, s2
+; GFX6-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX6-NEXT:    v_mov_b32_e32 v2, s5
+; GFX6-NEXT:    buffer_store_short v2, v[0:1], s[0:3], 0 addr64 offset:4
+; GFX6-NEXT:    s_waitcnt expcnt(0)
+; GFX6-NEXT:    v_mov_b32_e32 v2, s4
+; GFX6-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
+; GFX6-NEXT:    s_endpgm
+;
+; GFX7-LABEL: s_buffer_load_v6i8:
+; GFX7:       ; %bb.0: ; %main_body
+; GFX7-NEXT:    s_buffer_load_dwordx2 s[4:5], s[0:3], 0x0
+; GFX7-NEXT:    s_mov_b32 s2, 0
+; GFX7-NEXT:    s_mov_b32 s3, 0xf000
+; GFX7-NEXT:    s_mov_b32 s0, s2
+; GFX7-NEXT:    s_mov_b32 s1, s2
+; GFX7-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX7-NEXT:    v_mov_b32_e32 v2, s5
+; GFX7-NEXT:    buffer_store_short v2, v[0:1], s[0:3], 0 addr64 offset:4
+; GFX7-NEXT:    v_mov_b32_e32 v2, s4
+; GFX7-NEXT:    buffer_store_dword v2, v[0:1], s[0:3], 0 addr64
+; GFX7-NEXT:    s_endpgm
+;
+; GFX8-LABEL: s_buffer_load_v6i8:
+; GFX8:       ; %bb.0: ; %main_body
+; GFX8-NEXT:    s_buffer_load_dwordx2 s[0:1], s[0:3], 0x0
+; GFX8-NEXT:    v_add_u32_e32 v2, vcc, 4, v0
+; GFX8-NEXT:    v_addc_u32_e32 v3, vcc, 0,...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list