Author: Steven Perron
Date: 2025-04-01T16:59:46-04:00
New Revision: 16603d838c0dfa6881f9b8118c5a0b5ac2789752

URL: 
https://github.com/llvm/llvm-project/commit/16603d838c0dfa6881f9b8118c5a0b5ac2789752
DIFF: 
https://github.com/llvm/llvm-project/commit/16603d838c0dfa6881f9b8118c5a0b5ac2789752.diff

LOG: [HLSL] Add SPIR-V target type for RWStructuredBuffers (#133468)

This PR adds the target type for main storage for HLSL raw buffer types.
It does not handle the counter variables that are associated with those
buffers.

This is implementing part of
https://github.com/llvm/wg-hlsl/blob/main/proposals/0018-spirv-resource-representation.md.
We do not handle other HLSL raw buffer types.

Added: 
    

Modified: 
    clang/lib/CodeGen/Targets/SPIR.cpp
    clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/Targets/SPIR.cpp 
b/clang/lib/CodeGen/Targets/SPIR.cpp
index 43f511e572d37..225d9dfbd980b 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -386,14 +386,21 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
     if (ContainedTy.isNull())
       return nullptr;
 
-    assert(!ResAttrs.RawBuffer &&
-           "Raw buffers handles are not implemented for SPIR-V yet");
     assert(!ResAttrs.IsROV &&
            "Rasterizer order views not implemented for SPIR-V yet");
 
-    // convert element type
     llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
-    return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);
+    if (!ResAttrs.RawBuffer) {
+      // convert element type
+      return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);
+    }
+
+    llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0);
+    uint32_t StorageClass = /* StorageBuffer storage class */ 12;
+    bool IsWritable = ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV;
+    return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer",
+                                    {RuntimeArrayType},
+                                    {StorageClass, IsWritable});
   }
   case llvm::dxil::ResourceClass::CBuffer:
     llvm_unreachable("CBuffer handles are not implemented for SPIR-V yet");

diff  --git 
a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl 
b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl
index 04534c5550252..8a1429fd1a6fc 100644
--- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl
@@ -1,59 +1,70 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
-// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm 
-disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -DSPIRV 
-disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
 
-// NOTE: SPIRV codegen for resource types is not yet implemented
 
 StructuredBuffer<float> Buf : register(t10);
 RWStructuredBuffer<float> Buf2 : register(u5, space1);
+
+#ifndef SPIRV
+// NOTE: SPIRV codegen for these resource types is not implemented yet.
 AppendStructuredBuffer<float> Buf3 : register(u3);
 ConsumeStructuredBuffer<float> Buf4 : register(u4);
 RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
+#endif
+
+// CHECK-DXIL: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", 
float, 0, 0) }
+// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 0) }
+// CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 0) }
+// CHECK-DXIL: %"class.hlsl::ConsumeStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 0) }
+// CHECK-DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 1) }
+
+// CHECK-SPIRV: %"class.hlsl::StructuredBuffer" = type { 
target("spirv.VulkanBuffer", [0 x float], 12, 0) }
+// CHECK-SPIRV: %"class.hlsl::RWStructuredBuffer" = type { 
target("spirv.VulkanBuffer", [0 x float], 12, 1) }
 
-// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", 
float, 0, 0) }
-// CHECK: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", 
float, 1, 0) }
-// CHECK: %"class.hlsl::AppendStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 0) }
-// CHECK: %"class.hlsl::ConsumeStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 0) }
-// CHECK: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { 
target("dx.RawBuffer", float, 1, 1) }
 
-// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison, 
align 4
-// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" 
poison, align 4
-// CHECK: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" 
poison, align 4
-// CHECK: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" 
poison, align 4
-// CHECK: @_ZL4Buf5 = internal global 
%"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4
+// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison
+// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison
+// CHECK-DXIL: @_ZL4Buf3 = internal global 
%"class.hlsl::AppendStructuredBuffer" poison, align 4
+// CHECK-DXIL: @_ZL4Buf4 = internal global 
%"class.hlsl::ConsumeStructuredBuffer" poison, align 4
+// CHECK-DXIL: @_ZL4Buf5 = internal global 
%"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4
 
 // CHECK: define internal void @_init_resource__ZL3Buf()
 // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 0, 0) 
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(i32 0, i32 10, i32 
1, i32 0, i1 false)
 // CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) [[H]], ptr @_ZL3Buf, 
align 4
+// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 
0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_0t(i32 0, 
i32 10, i32 1, i32 0, i1 false)
+// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 0) [[H]], 
ptr @_ZL3Buf, align 8
 
 // CHECK: define internal void @_init_resource__ZL4Buf2()
 // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) 
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, 
i32 0, i1 false)
 // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf2, 
align 4
+// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 
1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_1t(i32 1, 
i32 5, i32 1, i32 0, i1 false)
+// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 1) [[H]], 
ptr @_ZL4Buf2, align 8
 
-// CHECK: define internal void @_init_resource__ZL4Buf3()
+// CHECK-DXIL: define internal void @_init_resource__ZL4Buf3()
 // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) 
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, 
i32 0, i1 false)
 // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf3, 
align 4
 
-// CHECK: define internal void @_init_resource__ZL4Buf4()
+// CHECK-DXIL: define internal void @_init_resource__ZL4Buf4()
 // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) 
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 4, i32 1, 
i32 0, i1 false)
 // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf4, 
align 4
 
-// CHECK: define internal void @_init_resource__ZL4Buf5()
+// CHECK-DXIL: define internal void @_init_resource__ZL4Buf5()
 // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 1) 
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_1t(i32 2, i32 1, i32 1, 
i32 0, i1 false)
 // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 1) [[H]], ptr @_ZL4Buf5, 
align 4
 
-// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr 
noundef nonnull align 4 dereferenceable(4) %this)
-// CHECK-NEXT: entry:
-// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr 
noundef nonnull align 4 dereferenceable(4) %this)
-// CHECK-NEXT: entry:
-// CHECK: define linkonce_odr void 
@_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
-// CHECK-NEXT: entry:
-// CHECK: define linkonce_odr void 
@_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
-// CHECK: define linkonce_odr void 
@_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
+// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr 
noundef nonnull align {{[48]}} dereferenceable({{[48]}}) %this)
 // CHECK-NEXT: entry:
+// CHECK-DXIL: define linkonce_odr void 
@_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
+// CHECK-DXIL-NEXT: entry:
+// CHECK-DXIL: define linkonce_odr void 
@_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
+// CHECK-DXIL-NEXT: entry:
+// CHECK-DXIL: define linkonce_odr void 
@_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
+// CHECK-DXIL: define linkonce_odr void 
@_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 
dereferenceable(4) %this)
+// CHECK-DXIL-NEXT: entry:
 
-// CHECK: define internal void 
@_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
-// CHECK: call void @_init_resource__ZL3Buf()
-// CHECK: call void @_init_resource__ZL4Buf2()
-// CHECK: call void @_init_resource__ZL4Buf3()
-// CHECK: call void @_init_resource__ZL4Buf4()
-// CHECK: call void @_init_resource__ZL4Buf5()
+// CHECK: define {{.*}} void 
@_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
+// CHECK: call {{.*}} @_init_resource__ZL3Buf()
+// CHECK: call {{.*}} @_init_resource__ZL4Buf2()
+// CHECK-DXIL: call void @_init_resource__ZL4Buf3()
+// CHECK-DXIL: call void @_init_resource__ZL4Buf4()
+// CHECK-DXIL: call void @_init_resource__ZL4Buf5()


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to