llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Steven Perron (s-perron) <details> <summary>Changes</summary> This commit partially implements SPIRTargetCodeGenInfo::getHLSLType. It can now generate the spirv type for the following HLSL types: 1. RWBuffer 2. Buffer 3. Sampler --- Full diff: https://github.com/llvm/llvm-project/pull/114273.diff 2 Files Affected: - (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+81) - (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl (+44-27) ``````````diff diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 7dd5c518e7149a..e6921d65084701 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -52,6 +52,10 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo { unsigned getOpenCLKernelCallingConv() const override; llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override; + llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *Ty) const override; + llvm::Type *getSPIRVImageTypeFromHLSLResource( + const HLSLAttributedResourceType::Attributes &attributes, + llvm::Type *ElementType, llvm::LLVMContext &Ctx) const; }; class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo { public: @@ -323,6 +327,83 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getOpenCLType(CodeGenModule &CGM, return nullptr; } +llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM, + const Type *Ty) const { + auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty); + if (!ResType) + return nullptr; + + llvm::LLVMContext &Ctx = CGM.getLLVMContext(); + const HLSLAttributedResourceType::Attributes &ResAttrs = ResType->getAttrs(); + switch (ResAttrs.ResourceClass) { + case llvm::dxil::ResourceClass::UAV: + case llvm::dxil::ResourceClass::SRV: { + // TypedBuffer and RawBuffer both need element type + QualType ContainedTy = ResType->getContainedType(); + 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); + } + case llvm::dxil::ResourceClass::CBuffer: + llvm_unreachable("CBuffer handles are not implemented for SPIR-V yet"); + break; + case llvm::dxil::ResourceClass::Sampler: + return llvm::TargetExtType::get(Ctx, "spirv.Sampler"); + } + return nullptr; +} + +llvm::Type *CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource( + const HLSLAttributedResourceType::Attributes &attributes, + llvm::Type *ElementType, llvm::LLVMContext &Ctx) const { + + if (ElementType->isVectorTy()) { + ElementType = ElementType->getScalarType(); + } + + if (!ElementType->isIntegerTy() && !ElementType->isFloatingPointTy()) { + // TODO: Should there be an error message? + ElementType->dump(); + assert(false && "Bad element type"); + return nullptr; + } + + // For HLSL types, the depth is always 2. + SmallVector<unsigned, 6> IntParams = {0, 2, 0, 0, 1, 0}; + + // Dim + // For now we assume everything is a buffer. + IntParams[0] = 5; + + // Depth + // HLSL does not indicate if it is a depth texture or not, so we use unknown. + IntParams[1] = 2; + + // Arrayed + IntParams[2] = 0; + + // MS + IntParams[3] = 0; + + // Sampled + IntParams[4] = + attributes.ResourceClass == llvm::dxil::ResourceClass::UAV ? 2 : 1; + + // Image format. + // Setting to unknown for now. + IntParams[5] = 0; + + return llvm::TargetExtType::get(Ctx, "spirv.Image", {ElementType}, IntParams); +} + std::unique_ptr<TargetCodeGenInfo> CodeGen::createCommonSPIRTargetCodeGenInfo(CodeGenModule &CGM) { return std::make_unique<CommonSPIRTargetCodeGenInfo>(CGM.getTypes()); diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl index fa81b53fd9bddc..374f600c75534b 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl @@ -1,22 +1,39 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s -check-prefixes=DXIL,COMMON +// RUN: %clang_cc1 -triple spirv-pc-vulkan-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s -check-prefixes=SPIRV,COMMON // NOTE: The type name number and whether the struct is packed or not will mostly // likely change once subscript operators are properly implemented (llvm/llvm-project#95956) // and theinterim field of the contained type is removed. -// CHECK: %"class.hlsl::RWBuffer" = type <{ target("dx.TypedBuffer", i16, 1, 0, 1) -// CHECK: %"class.hlsl::RWBuffer.0" = type <{ target("dx.TypedBuffer", i16, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.2" = type { target("dx.TypedBuffer", i32, 1, 0, 1) -// CHECK: %"class.hlsl::RWBuffer.3" = type { target("dx.TypedBuffer", i32, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.4" = type { target("dx.TypedBuffer", i64, 1, 0, 1) -// CHECK: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", i64, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.6" = type <{ target("dx.TypedBuffer", half, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", float, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", double, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0) -// CHECK: %"class.hlsl::RWBuffer.13" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer" = type <{ target("dx.TypedBuffer", i16, 1, 0, 1) +// DXIL: %"class.hlsl::RWBuffer.0" = type <{ target("dx.TypedBuffer", i16, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.2" = type { target("dx.TypedBuffer", i32, 1, 0, 1) +// DXIL: %"class.hlsl::RWBuffer.3" = type { target("dx.TypedBuffer", i32, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.4" = type { target("dx.TypedBuffer", i64, 1, 0, 1) +// DXIL: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", i64, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.6" = type <{ target("dx.TypedBuffer", half, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", float, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", double, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0) +// DXIL: %"class.hlsl::RWBuffer.13" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0) + +// SPIRV: %"class.hlsl::RWBuffer" = type <{ target("spirv.Image", i16, 5, 2, 0, 0, 2, 0), i16, [6 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.0" = type <{ target("spirv.Image", i16, 5, 2, 0, 0, 2, 0), i16, [6 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.2" = type <{ target("spirv.Image", i32, 5, 2, 0, 0, 2, 0), i32, [4 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.4" = type <{ target("spirv.Image", i32, 5, 2, 0, 0, 2, 0), i32, [4 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.6" = type { target("spirv.Image", i64, 5, 2, 0, 0, 2, 0), i64 } +// SPIRV: %"class.hlsl::RWBuffer.7" = type { target("spirv.Image", i64, 5, 2, 0, 0, 2, 0), i64 } +// SPIRV: %"class.hlsl::RWBuffer.8" = type <{ target("spirv.Image", half, 5, 2, 0, 0, 2, 0), half, [6 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.10" = type <{ target("spirv.Image", float, 5, 2, 0, 0, 2, 0), float, [4 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.12" = type { target("spirv.Image", double, 5, 2, 0, 0, 2, 0), double } +// SPIRV: %"class.hlsl::RWBuffer.13" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0), <4 x i16> } +// SPIRV: %"class.hlsl::RWBuffer.14" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0), <3 x i32> } +// SPIRV: %"class.hlsl::RWBuffer.15" = type <{ target("spirv.Image", half, 5, 2, 0, 0, 2, 0), <2 x half>, [4 x i8] }> +// SPIRV: %"class.hlsl::RWBuffer.17" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0), <3 x float> } + + RWBuffer<int16_t> BufI16; RWBuffer<uint16_t> BufU16; @@ -55,16 +72,16 @@ void main(int GI : SV_GroupIndex) { BufF32x3[GI] = 0; } -// CHECK: !{{[0-9]+}} = !{ptr @BufI16, i32 10, i32 2, -// CHECK: !{{[0-9]+}} = !{ptr @BufU16, i32 10, i32 3, -// CHECK: !{{[0-9]+}} = !{ptr @BufI32, i32 10, i32 4, -// CHECK: !{{[0-9]+}} = !{ptr @BufU32, i32 10, i32 5, -// CHECK: !{{[0-9]+}} = !{ptr @BufI64, i32 10, i32 6, -// CHECK: !{{[0-9]+}} = !{ptr @BufU64, i32 10, i32 7, -// CHECK: !{{[0-9]+}} = !{ptr @BufF16, i32 10, i32 8, -// CHECK: !{{[0-9]+}} = !{ptr @BufF32, i32 10, i32 9, -// CHECK: !{{[0-9]+}} = !{ptr @BufF64, i32 10, i32 10, -// CHECK: !{{[0-9]+}} = !{ptr @BufI16x4, i32 10, i32 2, -// CHECK: !{{[0-9]+}} = !{ptr @BufU32x3, i32 10, i32 5, -// CHECK: !{{[0-9]+}} = !{ptr @BufF16x2, i32 10, i32 8, -// CHECK: !{{[0-9]+}} = !{ptr @BufF32x3, i32 10, i32 9, +// COMMON: !{{[0-9]+}} = !{ptr @BufI16, i32 10, i32 2, +// COMMON: !{{[0-9]+}} = !{ptr @BufU16, i32 10, i32 3, +// COMMON: !{{[0-9]+}} = !{ptr @BufI32, i32 10, i32 4, +// COMMON: !{{[0-9]+}} = !{ptr @BufU32, i32 10, i32 5, +// COMMON: !{{[0-9]+}} = !{ptr @BufI64, i32 10, i32 6, +// COMMON: !{{[0-9]+}} = !{ptr @BufU64, i32 10, i32 7, +// COMMON: !{{[0-9]+}} = !{ptr @BufF16, i32 10, i32 8, +// COMMON: !{{[0-9]+}} = !{ptr @BufF32, i32 10, i32 9, +// COMMON: !{{[0-9]+}} = !{ptr @BufF64, i32 10, i32 10, +// COMMON: !{{[0-9]+}} = !{ptr @BufI16x4, i32 10, i32 2, +// COMMON: !{{[0-9]+}} = !{ptr @BufU32x3, i32 10, i32 5, +// COMMON: !{{[0-9]+}} = !{ptr @BufF16x2, i32 10, i32 8, +// COMMON: !{{[0-9]+}} = !{ptr @BufF32x3, i32 10, i32 9, `````````` </details> https://github.com/llvm/llvm-project/pull/114273 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits