https://github.com/Keenuts created https://github.com/llvm/llvm-project/pull/122103
In SPIR-V, private global variables have the `Private` storage class. This PR adds a new address space which allows frontend to emit variable with this storage class. Before this change, global variable were emitted with the 'Function' storage class, which was wrong. From 4336e42e84d40a010639dabac8cefca19123a164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= <brio...@google.com> Date: Thu, 28 Nov 2024 15:00:56 +0100 Subject: [PATCH] [SPIR-V] Add hlsl_private address space for SPIR-V MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In SPIR-V, private global variables have the `Private` storage class. This PR adds a new address space which allows frontend to emit variable with this storage class. Before this change, global variable were emitted with the 'Function' storage class, which was wrong. Signed-off-by: Nathan Gauër <brio...@google.com> --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/TargetInfo.cpp | 1 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp | 2 + clang/lib/Basic/Targets/DirectX.h | 19 +++++---- clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h | 42 ++++++++++--------- clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 17 ++++++++ clang/test/CodeGenHLSL/GlobalDestructors.hlsl | 2 +- .../test/CodeGenHLSL/out-of-line-static.hlsl | 27 ++++++++++++ .../static_global_and_function_in_cb.hlsl | 9 ++-- .../SemaTemplate/address_space-dependent.cpp | 2 +- 17 files changed, 95 insertions(+), 35 deletions(-) create mode 100644 clang/test/CodeGenHLSL/out-of-line-static.hlsl diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff17..8563d373d87367 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_private, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 7caebfb061a50b..1a273c76f71c41 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2553,6 +2553,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_private: + return "hlsl_private"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 86befb1cbc74fc..80aa212afc5c91 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -47,6 +47,7 @@ static const LangASMap FakeAddrSpaceMap = { 11, // ptr32_uptr 12, // ptr64 13, // hlsl_groupshared + 14, // hlsl_private 20, // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 68a8b1ebad8cde..6ef38fac6da280 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast<unsigned>(AArch64AddrSpace::ptr32_uptr), static_cast<unsigned>(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared + 0, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e2796..83aac92e2ea3ca 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -59,6 +59,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_private }; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { @@ -83,6 +84,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_private }; } // namespace targets diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df7..2cbb724386870e 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -33,15 +33,16 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // cuda_constant 0, // cuda_shared // SYCL address space values for this map are dummy - 0, // sycl_global - 0, // sycl_global_device - 0, // sycl_global_host - 0, // sycl_local - 0, // sycl_private - 0, // ptr32_sptr - 0, // ptr32_uptr - 0, // ptr64 - 3, // hlsl_groupshared + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 3, // hlsl_groupshared + 10, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac0..c6f4e1938a04df 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 5a328b9ceeb1d1..b3fdc055822b1b 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -38,15 +38,16 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // cuda_constant 0, // cuda_shared // SYCL address space values for this map are dummy - 0, // sycl_global - 0, // sycl_global_device - 0, // sycl_global_host - 0, // sycl_local - 0, // sycl_private - 0, // ptr32_sptr - 0, // ptr32_uptr - 0, // ptr64 - 0, // hlsl_groupshared + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 0, // hlsl_groupshared + 10, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -69,17 +70,18 @@ static const unsigned SPIRDefIsGenMap[] = { // cuda_constant pointer can be casted to default/"flat" pointer, but in // SPIR-V casts between constant and generic pointers are not allowed. For // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup. - 1, // cuda_constant - 3, // cuda_shared - 1, // sycl_global - 5, // sycl_global_device - 6, // sycl_global_host - 3, // sycl_local - 0, // sycl_private - 0, // ptr32_sptr - 0, // ptr32_uptr - 0, // ptr64 - 0, // hlsl_groupshared + 1, // cuda_constant + 3, // cuda_shared + 1, // sycl_global + 5, // sycl_global_device + 6, // sycl_global_host + 3, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 0, // hlsl_groupshared + 10, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index e6405f174f660f..6d9b168fea8580 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -42,6 +42,7 @@ static const unsigned ZOSAddressMap[] = { 1, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_private 0 // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h index d6280b02f07b25..c2e9b9681f0a89 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -51,6 +51,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 0a14da6a277b8e..a5c6d5c3778423 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -42,6 +42,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_private 20, // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 553c452d4ba3c2..f00722be6a0c74 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -46,6 +46,7 @@ static const unsigned X86AddrSpaceMap[] = { 271, // ptr32_uptr 272, // ptr64 0, // hlsl_groupshared + 0, // hlsl_private // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 5f15f0f48c54e4..d4318b9c7abc9a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5362,6 +5362,23 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { if (OpenMPRuntime->hasAllocateAttributeForGlobalVar(D, AS)) return AS; } + + if (LangOpts.HLSL) { + if (D == nullptr) + return LangAS::hlsl_private; + + // Except resources (Uniform, UniformConstant) & instanglble (handles) + if (D->getType()->isHLSLResourceType() || + D->getType()->isHLSLIntangibleType()) + return D->getType().getAddressSpace(); + + if (D->getStorageClass() != SC_Static) + return D->getType().getAddressSpace(); + + LangAS AS = D->getType().getAddressSpace(); + return AS == LangAS::Default ? LangAS::hlsl_private : AS; + } + return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D); } diff --git a/clang/test/CodeGenHLSL/GlobalDestructors.hlsl b/clang/test/CodeGenHLSL/GlobalDestructors.hlsl index f98318601134bb..62489457ff0868 100644 --- a/clang/test/CodeGenHLSL/GlobalDestructors.hlsl +++ b/clang/test/CodeGenHLSL/GlobalDestructors.hlsl @@ -71,7 +71,7 @@ void main(unsigned GI : SV_GroupIndex) { // NOINLINE: define internal void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]] // NOINLINE-NEXT: entry: -// NOINLINE-NEXT: call void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T) +// NOINLINE-NEXT: call void @_ZN4TailD1Ev(ptr addrspacecast (ptr addrspace(10) @_ZZ3WagvE1T to ptr)) // NOINLINE-NEXT: call void @_ZN6PupperD1Ev(ptr @GlobalPup) // NOINLINE-NEXT: ret void diff --git a/clang/test/CodeGenHLSL/out-of-line-static.hlsl b/clang/test/CodeGenHLSL/out-of-line-static.hlsl new file mode 100644 index 00000000000000..98666560dabd43 --- /dev/null +++ b/clang/test/CodeGenHLSL/out-of-line-static.hlsl @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -std=hlsl202x -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-compute -std=hlsl202x -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK + +struct S { + static int Value; +}; + +int S::Value = 1; +// CHECK: @_ZN1S5ValueE = global i32 1, align 4 + +[shader("compute")] +[numthreads(1,1,1)] +void main() { + S s; + int value1, value2; +// CHECK: %s = alloca %struct.S, align 1 +// CHECK: %value1 = alloca i32, align 4 +// CHECK: %value2 = alloca i32, align 4 + +// CHECK: [[tmp:%.*]] = load i32, ptr @_ZN1S5ValueE, align 4 +// CHECK: store i32 [[tmp]], ptr %value1, align 4 + value1 = S::Value; + +// CHECK: [[tmp:%.*]] = load i32, ptr @_ZN1S5ValueE, align 4 +// CHECK: store i32 [[tmp]], ptr %value2, align 4 + value2 = s.Value; +} diff --git a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl index f85bab2113170b..c78a5aa6881e2a 100644 --- a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl +++ b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl @@ -3,12 +3,13 @@ // CHECK-DAG: @[[CB:.+]] = external constant { float } +// CHECK-DAG:@_ZL1b = internal addrspace(10) global float 3.000000e+00, align 4 +static float b = 3; + cbuffer A { - float a; - // CHECK-DAG:@_ZL1b = internal global float 3.000000e+00, align 4 - static float b = 3; + float a; // CHECK:load float, ptr @[[CB]], align 4 - // CHECK:load float, ptr @_ZL1b, align 4 + // CHECK:load float, ptr addrspacecast (ptr addrspace(10) @_ZL1b to ptr), align 4 float foo() { return a + b; } } diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp index 2ca9b8007ab418..eb8dbc69a945e2 100644 --- a/clang/test/SemaTemplate/address_space-dependent.cpp +++ b/clang/test/SemaTemplate/address_space-dependent.cpp @@ -43,7 +43,7 @@ void neg() { template <long int I> void tooBig() { - __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}} + __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388585)}} } template <long int I> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits