[clang] [llvm] [HLSL][SPIR-V] Add hlsl_private address space for SPIR-V (PR #133464)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 28 09:23:28 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: Nathan Gauër (Keenuts)
<details>
<summary>Changes</summary>
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 when targeting this backend.
This is covered in this proposal: llvm/wg-hlsl@<!-- -->4c9e11a
This PR will cause addrspacecast to show up in several cases, like class member functions or assignment. Those will have to be handled in the backend later on, particularly to fixup pointer storage classes in some functions.
Before this change, global variable were emitted with the 'Function' storage class, which was wrong.
---
Patch is 21.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133464.diff
24 Files Affected:
- (modified) clang/include/clang/Basic/AddressSpaces.h (+1)
- (modified) clang/include/clang/Sema/Sema.h (+1)
- (modified) clang/lib/AST/Type.cpp (+5)
- (modified) clang/lib/AST/TypePrinter.cpp (+2)
- (modified) clang/lib/Basic/TargetInfo.cpp (+2)
- (modified) clang/lib/Basic/Targets/AArch64.h (+1)
- (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+4)
- (modified) clang/lib/Basic/Targets/DirectX.h (+1)
- (modified) clang/lib/Basic/Targets/NVPTX.h (+1)
- (modified) clang/lib/Basic/Targets/SPIR.h (+25-23)
- (modified) clang/lib/Basic/Targets/SystemZ.h (+1)
- (modified) clang/lib/Basic/Targets/TCE.h (+1)
- (modified) clang/lib/Basic/Targets/WebAssembly.h (+1)
- (modified) clang/lib/Basic/Targets/X86.h (+1)
- (modified) clang/lib/CodeGen/CGDeclCXX.cpp (+15-1)
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+6-6)
- (modified) clang/lib/Sema/SemaDecl.cpp (+35)
- (modified) clang/test/AST/HLSL/cbuffer.hlsl (+1-1)
- (modified) clang/test/CodeGenHLSL/GlobalConstructors.hlsl (+11-4)
- (modified) clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl (+1)
- (added) clang/test/CodeGenHLSL/out-of-line-static.hlsl (+30)
- (added) clang/test/CodeGenHLSL/static-variable.hlsl (+18)
- (modified) clang/test/SemaTemplate/address_space-dependent.cpp (+2-2)
- (modified) llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp (+3)
``````````diff
diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h
index d18bfe54931f9..5787e6dac0e36 100644
--- a/clang/include/clang/Basic/AddressSpaces.h
+++ b/clang/include/clang/Basic/AddressSpaces.h
@@ -59,6 +59,7 @@ enum class LangAS : unsigned {
// HLSL specific address spaces.
hlsl_groupshared,
hlsl_constant,
+ hlsl_private,
// Wasm specific address spaces.
wasm_funcref,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 066bce61c74c1..b38db4fe59368 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4321,6 +4321,7 @@ class Sema final : public SemaBase {
NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name);
void deduceOpenCLAddressSpace(ValueDecl *decl);
+ void deduceHLSLAddressSpace(VarDecl *decl);
/// Adjust the \c DeclContext for a function or variable that might be a
/// function-local external declaration.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 08798219c0b83..72d72c17d2b37 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -94,6 +94,8 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
(A == LangAS::Default &&
(B == LangAS::cuda_constant || B == LangAS::cuda_device ||
B == LangAS::cuda_shared)) ||
+ // Default is a superset of HLSL private.
+ (A == LangAS::Default && B == LangAS::hlsl_private) ||
// Conversions from target specific address spaces may be legal
// depending on the target information.
Ctx.getTargetInfo().isAddressSpaceSupersetOf(A, B);
@@ -5150,6 +5152,9 @@ bool Type::isHLSLIntangibleType() const {
CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
assert(RD != nullptr &&
"all HLSL structs and classes should be CXXRecordDecl");
+
+ if (!RD->isCompleteDefinition())
+ return false;
assert(RD->isCompleteDefinition() && "expecting complete type");
return RD->isHLSLIntangible();
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 3982ca3b50604..d193e6ecc2351 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2579,6 +2579,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
return "groupshared";
case LangAS::hlsl_constant:
return "hlsl_constant";
+ case LangAS::hlsl_private:
+ return "hlsl_private";
case LangAS::wasm_funcref:
return "__funcref";
default:
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 0699ec686e4e6..ab13c32f6943e 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -47,6 +47,8 @@ static const LangASMap FakeAddrSpaceMap = {
11, // ptr32_uptr
12, // ptr64
13, // hlsl_groupshared
+ 14, // hlsl_constant
+ 15, // hlsl_private
20, // wasm_funcref
};
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 9b6451bd06316..58822e467ce39 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -45,6 +45,7 @@ static const unsigned ARM64AddrSpaceMap[] = {
static_cast<unsigned>(AArch64AddrSpace::ptr64),
0, // hlsl_groupshared
0, // hlsl_constant
+ 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 a42b4589fb5ac..4f628a8264459 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -60,6 +60,9 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared
llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant
+ // FIXME(pr/122103): hlsl_private -> PRIVATE is wrong, but at least this
+ // will break loudly.
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_private
};
const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
@@ -85,6 +88,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared
llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // hlsl_private
};
} // namespace targets
} // namespace clang
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 6e3ddad626341..e4c8cb6c7a20c 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -43,6 +43,7 @@ static const unsigned DirectXAddrSpaceMap[] = {
0, // ptr64
3, // hlsl_groupshared
2, // hlsl_constant
+ 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/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 6a868c42e1265..041596929ff5b 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -47,6 +47,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
0, // ptr64
0, // hlsl_groupshared
0, // hlsl_constant
+ 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 78505d66d6f2f..c71f046c8e180 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -38,16 +38,17 @@ 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
- 2, // hlsl_constant
+ 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
+ 2, // hlsl_constant
+ 10, // hlsl_private
// Wasm address space values for this target are dummy values,
// as it is only enabled for Wasm targets.
20, // wasm_funcref
@@ -70,18 +71,19 @@ 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
- 0, // hlsl_constant
+ 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
+ 0, // hlsl_constant
+ 10, // hlsl_private
// Wasm address space values for this target are dummy values,
// as it is only enabled for Wasm targets.
20, // wasm_funcref
@@ -315,7 +317,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
// SPIR-V IDs are represented with a single 32-bit word.
SizeType = TargetInfo::UnsignedInt;
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
- "v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
+ "v256:256-v512:512-v1024:1024-n8:16:32:64-G10");
}
llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 4ca3f53f83cba..4d1509b84e82b 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -43,6 +43,7 @@ static const unsigned ZOSAddressMap[] = {
0, // ptr64
0, // hlsl_groupshared
0, // hlsl_constant
+ 0, // hlsl_private
0 // wasm_funcref
};
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index 46c70de8f9ec1..44de8aae52a16 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -52,6 +52,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
0, // ptr64
0, // hlsl_groupshared
0, // hlsl_constant
+ 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 fb48c786a7edb..e786f9a3db68e 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -43,6 +43,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = {
0, // ptr64
0, // hlsl_groupshared
0, // hlsl_constant
+ 0, // hlsl_private
20, // wasm_funcref
};
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 205edcab9ccb3..d44561dd42997 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -47,6 +47,7 @@ static const unsigned X86AddrSpaceMap[] = {
272, // ptr64
0, // hlsl_groupshared
0, // hlsl_constant
+ 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/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 1ad34ae61f96a..7acb1dfb9e493 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -1158,8 +1158,22 @@ void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(
CGM.getCXXABI().useSinitAndSterm() &&
"Arg could not be nullptr unless using sinit and sterm functions.");
CI = Builder.CreateCall(CalleeTy, Callee);
- } else
+ } else {
+ // If the object lives in a different address space, the `this` pointer
+ // address space won't match the dtor `this` param. An addrspacecast is
+ // required.
+ assert(Arg->getType()->isPointerTy());
+ assert(CalleeTy->getParamType(0)->isPointerTy());
+ unsigned ActualAddrSpace = Arg->getType()->getPointerAddressSpace();
+ unsigned ExpectedAddrSpace =
+ CalleeTy->getParamType(0)->getPointerAddressSpace();
+ if (ActualAddrSpace != ExpectedAddrSpace) {
+ llvm::PointerType *PTy =
+ llvm::PointerType::get(getLLVMContext(), ExpectedAddrSpace);
+ Arg = llvm::ConstantExpr::getAddrSpaceCast(Arg, PTy);
+ }
CI = Builder.CreateCall(CalleeTy, Callee, Arg);
+ }
// Make sure the call and the callee agree on calling convention.
if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index dcf523f56bf1e..731dbbfa4ca58 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -371,12 +371,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
assert(DeferredDeactivationCleanupStack.empty() &&
"mismatched activate/deactivate of cleanups!");
- if (CGM.shouldEmitConvergenceTokens()) {
- ConvergenceTokenStack.pop_back();
- assert(ConvergenceTokenStack.empty() &&
- "mismatched push/pop in convergence stack!");
- }
-
bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
&& NumSimpleReturnExprs == NumReturnExprs
&& ReturnBlock.getBlock()->use_empty();
@@ -564,6 +558,12 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
ReturnValue = Address::invalid();
}
}
+
+ if (CGM.shouldEmitConvergenceTokens()) {
+ ConvergenceTokenStack.pop_back();
+ assert(ConvergenceTokenStack.empty() &&
+ "mismatched push/pop in convergence stack!");
+ }
}
/// ShouldInstrumentFunction - Return true if the current function should be
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 043e82414c052..5fd77b7e61c88 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6888,6 +6888,32 @@ static void SetNestedNameSpecifier(Sema &S, DeclaratorDecl *DD, Declarator &D) {
DD->setQualifierInfo(SS.getWithLocInContext(S.Context));
}
+void Sema::deduceHLSLAddressSpace(VarDecl *Decl) {
+ // The variable already has an address space (groupshared for ex).
+ if (Decl->getType().hasAddressSpace())
+ return;
+
+ if (Decl->getType()->isDependentType())
+ return;
+
+ QualType Type = Decl->getType();
+ if (Type->isSamplerT() || Type->isVoidType())
+ return;
+
+ // Resource handles.
+ if (Type->isHLSLIntangibleType())
+ return;
+
+ // Only static globals belong to the Private address space.
+ // Non-static globals belongs to the cbuffer.
+ if (Decl->getStorageClass() != SC_Static && !Decl->isStaticDataMember())
+ return;
+
+ LangAS ImplAS = LangAS::hlsl_private;
+ Type = Context.getAddrSpaceQualType(Type, ImplAS);
+ Decl->setType(Type);
+}
+
void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) {
if (Decl->getType().hasAddressSpace())
return;
@@ -7781,6 +7807,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
NewVD = VarDecl::Create(Context, DC, D.getBeginLoc(),
D.getIdentifierLoc(), II, R, TInfo, SC);
+ if (getLangOpts().HLSL)
+ deduceHLSLAddressSpace(NewVD);
+
// If this is supposed to be a variable template, create it as such.
if (IsVariableTemplate) {
NewTemplate =
@@ -7966,6 +7995,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
+ if (getLangOpts().HLSL)
+ deduceHLSLAddressSpace(NewVD);
+
// WebAssembly tables are always in address space 1 (wasm_var). Don't apply
// address space if the table has local storage (semantic checks elsewhere
// will produce an error anyway).
@@ -13138,6 +13170,9 @@ bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
if (getLangOpts().OpenCL)
deduceOpenCLAddressSpace(VDecl);
+ if (getLangOpts().HLSL)
+ deduceHLSLAddressSpace(VDecl);
+
// If this is a redeclaration, check that the type we just deduced matches
// the previously declared type.
if (VarDecl *Old = VDecl->getPreviousDecl()) {
diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl
index 6c573034a4f7b..5c5aa6fc5ab10 100644
--- a/clang/test/AST/HLSL/cbuffer.hlsl
+++ b/clang/test/AST/HLSL/cbuffer.hlsl
@@ -149,7 +149,7 @@ _Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblay
cbuffer CB {
// CHECK: FunctionDecl {{.*}} f 'void ()'
void f() {}
- // CHECK: VarDecl {{.*}} SV 'float' static
+ // CHECK: VarDecl {{.*}} SV 'hlsl_private float' static
static float SV;
// CHECK: VarDecl {{.*}} s7 'EmptyStruct' callinit
EmptyStruct s7;
diff --git a/clang/test/CodeGenHLSL/GlobalConstructors.hlsl b/clang/test/CodeGenHLSL/GlobalConstructors.hlsl
index 7b26dba0d1901..602234973c312 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructors.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructors.hlsl
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-compute -x hlsl -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,DXIL
RWBuffer<float> Buffer;
@@ -10,7 +11,13 @@ void main(unsigned GI : SV_GroupIndex) {}
// CHECK-NOT:@llvm.global_dtors
//CHECK: define void @main()
//CHECK-NEXT: entry:
-//CHECK-NEXT: call void @_GLOBAL__sub_I_GlobalConstructors.hlsl()
-//CHECK-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
-//CHECK-NEXT: call void @_Z4mainj(i32 %0)
+
+//SPIRV-NEXT: %0 = call token @llvm.experimental.convergence.entry()
+//SPIRV-NEXT: call spir_func void @_GLOBAL__sub_I_GlobalConstructors.hlsl() [ "convergencectrl"(token %0) ]
+//SPIRV-NEXT: %1 = call i32 @llvm.spv.flattened.thread.id.in.group()
+//SPIRV-NEXT: call spir_func void @_Z4mainj(i32 %1) [ "convergencectrl"(token %0) ]
+
+//DXIL-NEXT: call void @_GLOBAL__sub_I_GlobalConstructors.hlsl()
+//DXIL-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
+//DXIL-NEXT: call void @_Z4mainj(i32 %0)
//CHECK-NEXT: ret void
diff --git a/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl b/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl
index c9c3ee9c43f6e..5eecfc41579f2 100644
--- a/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl
+++ b/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl
@@ -20,6 +20,7 @@ cbuffer B {
// CHECK: define {{.*}} float @_Z3foov() #0 {
// CHECK: load float, ptr addrspace(2) @a, align 4
+// CHECK: load float, ptr @_ZL1b, align 4
extern float bar() {
return foo();
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 0000000000000..8127a6c2ec1e4
--- /dev/null
+++ b/clang/test/CodeGenHLSL/out-of-line-static.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -std=hlsl202x -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,DXIL
+// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-compute -std=hlsl202x -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK,SPIRV
+
+struct S {
+ static int Value;
+};
+
+int S::Value = 1;
+// DXIL: @_ZN1S5ValueE = global i32 1, align 4
+// SPIRV: @_ZN1S5ValueE = addrspace(10) 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
+
+// DXIL: [[tmp:%.*]] = load i32, ptr @_ZN1S5ValueE, align 4
+// SPIRV: [[tmp:%.*]] = load i32, ptr addrspace(10) @_ZN1S5ValueE, align 4
+// CHECK: store i32 [[tmp]], ptr %value1, align 4
+ value1 = S::Value;
+
+// DXIL: [[tmp:%.*]] = load i32, ptr @_ZN1S5ValueE, align 4
+// SPIRV: [[tmp:%.*]] = load i32, ptr addrspace(10) @_ZN1S5ValueE, align 4
+// CHECK: store i32 [[tmp]], ptr %value2, align 4
+ value2 = s.Value;
+}
diff --git a/clang/test/CodeGenHLSL/static-variable.hlsl b/clang/test/CodeGenHLSL/static-variable.hlsl
new file mode 100644
index 0000000000000..4be909d45bae4
--- /dev/null
+++ b/clang/test/CodeGenHLSL/static-variable.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN: spirv-unknown-vulkan1.3-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=SPIRV
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=DXIL
+
+// DXIL: @_ZL1g = internal global float 0.000000e+00, align 4
+// SPIRV: @_ZL1g = internal addrspace(10) global float 0.000000e+00, align 4
+
+static float g = 0;
+
+[numthreads(8,8,1)]
+void main() {
+// DXIL: {{.*}} = load float, ptr @_ZL1g, align 4
+// SPIRV: {{.*}} = load float, ptr addrspace(10) @_ZL1g, align 4
+ float l = g;
+}
diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp
index eb8dbc69a945e..3e73e909746a5 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 (8388585)}}
+ __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/133464
More information about the llvm-commits
mailing list