Skip to content

Commit a65ccd0

Browse files
committed
[HLSL] Fix resrouce wrapper declaration
The resource wrapper should have internal linkage because it cotains a handle to the global resource, and it not the actual global. Makeing this changed exposed that we were zeroinitializing the resouce, which is a problem. The handle cannot be zeroinitialized. Fixes #122767.
1 parent e75e617 commit a65ccd0

File tree

7 files changed

+29
-27
lines changed

7 files changed

+29
-27
lines changed

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,6 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() {
528528
}
529529
}
530530

531-
// Returns true if the type is an HLSL resource class
532-
static bool isResourceRecordType(const clang::Type *Ty) {
533-
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
534-
}
535-
536531
static void createResourceInitFn(CodeGenModule &CGM, const VarDecl *VD,
537532
llvm::GlobalVariable *GV, unsigned Slot,
538533
unsigned Space) {
@@ -599,7 +594,7 @@ void CGHLSLRuntime::handleGlobalVarDefinition(const VarDecl *VD,
599594
// on?
600595
return;
601596

602-
if (!isResourceRecordType(VD->getType().getTypePtr()))
597+
if (!isResource(VD))
603598
// FIXME: Only simple declarations of resources are supported for now.
604599
// Arrays of resources or resources in user defined classes are
605600
// not implemented yet.
@@ -623,3 +618,8 @@ llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) {
623618
llvm_unreachable("Convergence token should have been emitted.");
624619
return nullptr;
625620
}
621+
622+
bool CGHLSLRuntime::isResource(const VarDecl *D) {
623+
const clang::Type *ty = D->getType().getTypePtr();
624+
return HLSLAttributedResourceType::findHandleTypeOnResource(ty) != nullptr;
625+
}

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class CGHLSLRuntime {
135135
llvm::StructType *LayoutStruct = nullptr;
136136
};
137137

138+
bool isResource(const VarDecl *D);
139+
138140
protected:
139141
CodeGenModule &CGM;
140142

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5589,7 +5589,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
55895589
if (D->getType()->isReferenceType())
55905590
T = D->getType();
55915591

5592-
if (getLangOpts().CPlusPlus) {
5592+
if (getLangOpts().HLSL && getHLSLRuntime().isResource(D)) {
5593+
Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy));
5594+
NeedsGlobalCtor = true;
5595+
} else if (getLangOpts().CPlusPlus) {
55935596
Init = EmitNullConstant(T);
55945597
if (!IsDefinitionAvailableExternally)
55955598
NeedsGlobalCtor = true;
@@ -5735,6 +5738,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
57355738
!D->hasAttr<ConstInitAttr>())
57365739
Linkage = llvm::GlobalValue::InternalLinkage;
57375740

5741+
// For HLSL resources, the GV is an internal wrapper containing a handle to
5742+
// external resource.
5743+
if (getLangOpts().HLSL && getHLSLRuntime().isResource(D))
5744+
Linkage = llvm::GlobalValue::InternalLinkage;
5745+
57385746
GV->setLinkage(Linkage);
57395747
if (D->hasAttr<DLLImportAttr>())
57405748
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);

clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4);
1111
// CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
1212
// CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
1313

14-
// CHECK: @Buffer0 = global %"class.hlsl::ByteAddressBuffer" zeroinitializer, align 4
15-
// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4
16-
// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4
14+
// CHECK: @Buffer0 = internal global %"class.hlsl::ByteAddressBuffer" undef, align 4
15+
// CHECK: @Buffer1 = internal global %"class.hlsl::RWByteAddressBuffer" undef, align 4
16+
// CHECK: @Buffer2 = internal global %"class.hlsl::RasterizerOrderedByteAddressBuffer" undef, align 4
1717

1818
// CHECK; define internal void @_init_resource_Buffer0()
1919
// CHECK-DXIL: %Buffer0_h = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false)
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
2-
// RUN: %clang_cc1 -triple spirv-vulkan-compute -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple spirv-vulkan-compute -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s
33

4-
// CHECK-SPIRV: %"class.hlsl::RWBuffer" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0) }
5-
// CHECK-DXIL: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
4+
// All referenced to an unused resource should be removed by optimizations.
65
RWBuffer<float> Buf : register(u5, space3);
76

87
[shader("compute")]
98
[numthreads(1, 1, 1)]
109
void main() {
1110
// CHECK: define void @main()
1211
// CHECK-NEXT: entry:
13-
14-
// CHECK-SPIRV-NEXT: %[[HANDLE:.*]] = tail call target("spirv.Image", float, 5, 2, 0, 0, 2, 0) @llvm.spv.resource.handlefrombinding.tspirv.Image_f32_5_2_0_0_2_0t(i32 3, i32 5, i32 1, i32 0, i1 false)
15-
// CHECK-SPIRV-NEXT: store target("spirv.Image", float, 5, 2, 0, 0, 2, 0) %[[HANDLE:.*]], ptr @Buf, align 8
16-
17-
// CHECK-DXIL-NEXT: %[[HANDLE:.*]] = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 3, i32 5, i32 1, i32 0, i1 false)
18-
// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %[[HANDLE]], ptr @Buf, align 4
19-
2012
// CHECK-NEXT: ret void
2113
}

clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
RWBuffer<float> Buf : register(u5, space3);
88

99
// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
10-
// CHECK: @Buf = global %"class.hlsl::RWBuffer" zeroinitializer, align 4
10+
// CHECK: @Buf = internal global %"class.hlsl::RWBuffer" undef, align 4
1111

1212
// CHECK: define internal void @_init_resource_Buf()
1313
// CHECK-DXIL: %Buf_h = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 3, i32 5, i32 1, i32 0, i1 false)

clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
1515
// CHECK: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
1616
// CHECK: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) }
1717

18-
// CHECK: @Buf = global %"class.hlsl::StructuredBuffer" zeroinitializer, align 4
19-
// CHECK: @Buf2 = global %"class.hlsl::RWStructuredBuffer" zeroinitializer, align 4
20-
// CHECK: @Buf3 = global %"class.hlsl::AppendStructuredBuffer" zeroinitializer, align 4
21-
// CHECK: @Buf4 = global %"class.hlsl::ConsumeStructuredBuffer" zeroinitializer, align 4
22-
// CHECK: @Buf5 = global %"class.hlsl::RasterizerOrderedStructuredBuffer" zeroinitializer, align 4
18+
// CHECK: @Buf = internal global %"class.hlsl::StructuredBuffer" undef, align 4
19+
// CHECK: @Buf2 = internal global %"class.hlsl::RWStructuredBuffer" undef, align 4
20+
// CHECK: @Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" undef, align 4
21+
// CHECK: @Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" undef, align 4
22+
// CHECK: @Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" undef, align 4
2323

2424
// CHECK: define internal void @_init_resource_Buf()
2525
// CHECK-DXIL: %Buf_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)

0 commit comments

Comments
 (0)