[llvm] 9bf40ce - [AMDGPU] Fix s_buffer_load crash for illegal result types (#215483)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 13:57:55 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-09-13T22:57:50+02:00
New Revision: 9bf40ce33523745e19328924593134e4510bfa5f

URL: https://github.com/llvm/llvm-project/commit/9bf40ce33523745e19328924593134e4510bfa5f
DIFF: https://github.com/llvm/llvm-project/commit/9bf40ce33523745e19328924593134e4510bfa5f.diff

LOG: [AMDGPU] Fix s_buffer_load crash for illegal result types (#215483)

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

Added: 
    llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.s.buffer.load.illegal-types.ll
    llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll

Modified: 
    llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
    llvm/lib/Target/AMDGPU/SIISelLowering.cpp
    llvm/lib/Target/AMDGPU/SIISelLowering.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 397755a43854a..6ca65e6fa01af 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -7776,8 +7776,22 @@ bool AMDGPULegalizerInfo::legalizeSBufferLoad(LegalizerHelper &Helper,
   unsigned Size = Ty.getSizeInBits();
   MachineFunction &MF = B.getMF();
   bool HasMMO = !MI.memoperands_empty();
+
+  // S_BUFFER_LOAD only produces values that fill whole SGPRs, apart from the
+  // subword loads below. Those truncate from an s32 result, so they need a
+  // scalar destination.
+  bool IsSubwordLoad = Ty.isScalar() && Size < 32 && ST.hasScalarSubwordLoads();
+  if (Size % 32 != 0 && !IsSubwordLoad) {
+    const Function &Fn = MF.getFunction();
+    Fn.getContext().diagnose(DiagnosticInfoUnsupported(
+        Fn, "unsupported s_buffer_load result type", MI.getDebugLoc()));
+    B.buildUndef(OrigDst);
+    MI.eraseFromParent();
+    return true;
+  }
+
   unsigned Opc = 0;
-  if (Size < 32 && ST.hasScalarSubwordLoads()) {
+  if (IsSubwordLoad) {
     assert(Size == 8 || Size == 16);
     Opc = Size == 8 ? AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE
                     : AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT;

diff  --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 95c951c5cb2b1..3efb257091759 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -1070,6 +1070,22 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
                       MVT::i16, MVT::bf16, MVT::i8, MVT::i128},
                      Custom);
 
+  // The s_buffer_load intrinsics accept any result type in IR, but only a few
+  // of them can be selected. Mark the remaining illegal result types Custom so
+  // ReplaceNodeResults gets a chance to diagnose them instead of letting the
+  // type legalizer abort. Its INTRINSIC_WO_CHAIN case dispatches on the
+  // intrinsic ID, but INTRINSIC_W_CHAIN does not, so remember the types added
+  // here to keep other chained intrinsics on generic legalization.
+  for (MVT VT : MVT::all_valuetypes()) {
+    if (VT.isScalableVector() || isTypeLegal(VT))
+      continue;
+    setOperationAction(ISD::INTRINSIC_WO_CHAIN, VT, Custom);
+    if (getOperationAction(ISD::INTRINSIC_W_CHAIN, VT) != Custom) {
+      setOperationAction(ISD::INTRINSIC_W_CHAIN, VT, Custom);
+      SBufferLoadDiagnosticVTs.set(VT.SimpleTy);
+    }
+  }
+
   setOperationAction(ISD::INTRINSIC_VOID,
                      {MVT::Other, MVT::v2i16, MVT::v2f16, MVT::v2bf16,
                       MVT::v3i16, MVT::v3f16, MVT::v4f16, MVT::v4i16,
@@ -8499,53 +8515,11 @@ 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;
       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, SDLoc(Op), DAG.getEntryNode(),
+                                     Op.getOperand(1), Op.getOperand(2),
+                                     Op.getOperand(3), DAG));
       return;
     }
     case Intrinsic::amdgcn_dead: {
@@ -8557,6 +8531,10 @@ void SITargetLowering::ReplaceNodeResults(SDNode *N,
     break;
   }
   case ISD::INTRINSIC_W_CHAIN: {
+    if (N->getConstantOperandVal(1) != Intrinsic::amdgcn_ptr_s_buffer_load &&
+        N->getValueType(0).isSimple() &&
+        SBufferLoadDiagnosticVTs[N->getSimpleValueType(0).SimpleTy])
+      break;
     if (SDValue Res = LowerINTRINSIC_W_CHAIN(SDValue(N, 0), DAG)) {
       if (Res.getOpcode() == ISD::MERGE_VALUES) {
         // FIXME: Hacky
@@ -10896,6 +10874,19 @@ SDValue SITargetLowering::lowerSBuffer(EVT VT, EVT MemVT, SDLoc DL,
   MachineFunction &MF = DAG.getMachineFunction();
   bool HasChainResult = MMO != nullptr;
 
+  // SBUFFER_LOAD only produces values that fill whole SGPRs, apart from the
+  // subword loads below.
+  bool IsSubwordLoad = (MemVT == MVT::i8 || MemVT == MVT::i16) &&
+                       Subtarget->hasScalarSubwordLoads();
+  if ((!isTypeLegal(VT) || VT.getSizeInBits() % 32 != 0) && !IsSubwordLoad) {
+    DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
+        MF.getFunction(), "unsupported s_buffer_load result type",
+        DL.getDebugLoc()));
+    EVT ResultTypes[] = {VT, MVT::Other};
+    return DAG.getErrorMergeValues(
+        ArrayRef(ResultTypes, HasChainResult ? 2 : 1), Chain, DL);
+  }
+
   if (!HasChainResult) {
     const DataLayout &DataLayout = DAG.getDataLayout();
     Align Alignment =
@@ -10931,8 +10922,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);

diff  --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 421954ebf3363..fc52aa4eeb5a4 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -19,6 +19,7 @@
 #include "SIDefines.h"
 #include "llvm/ADT/FloatingPointMode.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include <bitset>
 
 namespace llvm {
 
@@ -34,6 +35,11 @@ class SITargetLowering final : public AMDGPUTargetLowering {
 private:
   const GCNSubtarget *Subtarget;
 
+  /// Result types made Custom for ISD::INTRINSIC_W_CHAIN only so that
+  /// unsupported s_buffer_load result types can be diagnosed. Any other
+  /// intrinsic returning one of these must keep using generic legalization.
+  std::bitset<MVT::VALUETYPE_SIZE> SBufferLoadDiagnosticVTs;
+
 public:
   MVT getRegisterTypeForCallingConv(LLVMContext &Context,
                                     CallingConv::ID CC,

diff  --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.s.buffer.load.illegal-types.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.s.buffer.load.illegal-types.ll
new file mode 100644
index 0000000000000..64430382ec1bf
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ptr.s.buffer.load.illegal-types.ll
@@ -0,0 +1,101 @@
+; RUN: not llc -mtriple=amdgpu9.00-amd-amdhsa -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: not llc -global-isel=1 -mtriple=amdgpu9.00-amd-amdhsa -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GISEL
+; RUN: not llc -mtriple=amdgpu11.00-amd-amdhsa -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: not llc -global-isel=1 -mtriple=amdgpu11.00-amd-amdhsa -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GISEL
+
+; There is no s_buffer_load for these result types.
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i1 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i1(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i1 @llvm.amdgcn.ptr.s.buffer.load.i1(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i1 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i4 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i4(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i4 @llvm.amdgcn.ptr.s.buffer.load.i4(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i4 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i2 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i2(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i2 @llvm.amdgcn.ptr.s.buffer.load.i2(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i2 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v3i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v3i8(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call <3 x i8> @llvm.amdgcn.ptr.s.buffer.load.v3i8(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <3 x i8> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v2i1 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v2i1(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call <2 x i1> @llvm.amdgcn.ptr.s.buffer.load.v2i1(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <2 x i1> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v3i16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v3i16(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call <3 x i16> @llvm.amdgcn.ptr.s.buffer.load.v3i16(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <3 x i16> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v3f16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v3f16(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call <3 x half> @llvm.amdgcn.ptr.s.buffer.load.v3f16(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <3 x half> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v6i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v6i8(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call <6 x i8> @llvm.amdgcn.ptr.s.buffer.load.v6i8(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <6 x i8> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; i128 is illegal for SelectionDAG, but GlobalISel selects s_buffer_load_b128.
+; GISEL-NOT: in function {{.*}}_i128
+; SDAG: error: {{.*}} in function ptr_s_buffer_load_i128 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i128(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i128 @llvm.amdgcn.ptr.s.buffer.load.i128(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i128 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i8(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i8 @llvm.amdgcn.ptr.s.buffer.load.i8(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i8 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i16(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc, i32 inreg %offset) {
+  %load = call i16 @llvm.amdgcn.ptr.s.buffer.load.i16(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i16 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_i1_divergent {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_i1_divergent(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc) {
+  %offset = call i32 @llvm.amdgcn.workitem.id.x()
+  %load = call i1 @llvm.amdgcn.ptr.s.buffer.load.i1(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store i1 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function ptr_s_buffer_load_v6i8_divergent {{.*}}: unsupported s_buffer_load result type
+define amdgpu_kernel void @ptr_s_buffer_load_v6i8_divergent(ptr addrspace(1) %out, ptr addrspace(8) inreg %rsrc) {
+  %offset = call i32 @llvm.amdgcn.workitem.id.x()
+  %load = call <6 x i8> @llvm.amdgcn.ptr.s.buffer.load.v6i8(ptr addrspace(8) %rsrc, i32 %offset, i32 0)
+  store <6 x i8> %load, ptr addrspace(1) %out
+  ret void
+}

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..0cc2a1f5fc5d9
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.buffer.load.illegal-types.ll
@@ -0,0 +1,101 @@
+; RUN: not llc -mtriple=amdgpu9.00 -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: not llc -global-isel=1 -mtriple=amdgpu9.00 -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GISEL
+; RUN: not llc -mtriple=amdgpu11.00 -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,SDAG
+; RUN: not llc -global-isel=1 -mtriple=amdgpu11.00 -filetype=null %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GISEL
+
+; There is no s_buffer_load for these result types.
+
+; CHECK: error: {{.*}} in function s_buffer_load_i1 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i1(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %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
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_i4 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i4(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %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
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_i2 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i2(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call i2 @llvm.amdgcn.s.buffer.load.i2(<4 x i32> %desc, i32 0, i32 0)
+  store i2 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v3i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v3i8(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call <3 x i8> @llvm.amdgcn.s.buffer.load.v3i8(<4 x i32> %desc, i32 0, i32 0)
+  store <3 x i8> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v2i1 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v2i1(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %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
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v3i16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v3i16(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %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
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v3f16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v3f16(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call <3 x half> @llvm.amdgcn.s.buffer.load.v3f16(<4 x i32> %desc, i32 0, i32 0)
+  store <3 x half> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v6i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v6i8(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call <6 x i8> @llvm.amdgcn.s.buffer.load.v6i8(<4 x i32> %desc, i32 0, i32 0)
+  store <6 x i8> %load, ptr addrspace(1) %out
+  ret void
+}
+
+; i128 is illegal for SelectionDAG, but GlobalISel selects s_buffer_load_b128.
+; GISEL-NOT: in function {{.*}}_i128
+; SDAG: error: {{.*}} in function s_buffer_load_i128 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i128(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call i128 @llvm.amdgcn.s.buffer.load.i128(<4 x i32> %desc, i32 0, i32 0)
+  store i128 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_i8 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i8(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call i8 @llvm.amdgcn.s.buffer.load.i8(<4 x i32> %desc, i32 0, i32 0)
+  store i8 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_i16 {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i16(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %load = call i16 @llvm.amdgcn.s.buffer.load.i16(<4 x i32> %desc, i32 0, i32 0)
+  store i16 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_i1_divergent {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_i1_divergent(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %offset = call i32 @llvm.amdgcn.workitem.id.x()
+  %load = call i1 @llvm.amdgcn.s.buffer.load.i1(<4 x i32> %desc, i32 %offset, i32 0)
+  store i1 %load, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: {{.*}} in function s_buffer_load_v6i8_divergent {{.*}}: unsupported s_buffer_load result type
+define amdgpu_ps void @s_buffer_load_v6i8_divergent(<4 x i32> inreg %desc, ptr addrspace(1) %out) {
+  %offset = call i32 @llvm.amdgcn.workitem.id.x()
+  %load = call <6 x i8> @llvm.amdgcn.s.buffer.load.v6i8(<4 x i32> %desc, i32 %offset, i32 0)
+  store <6 x i8> %load, ptr addrspace(1) %out
+  ret void
+}


        


More information about the llvm-commits mailing list