diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 8767a2ddceb96..0563d98b7dc59 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -137,6 +137,8 @@ class CGHLSLRuntime { llvm::StructType *LayoutStruct = nullptr; }; + bool isResource(const VarDecl *D); + protected: CodeGenModule &CGM; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7924c32fcf633..1f4ead3ba23c3 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5589,7 +5589,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, if (D->getType()->isReferenceType()) T = D->getType(); - if (getLangOpts().CPlusPlus) { + if (getLangOpts().HLSL && getHLSLRuntime().isResource(D)) { + Init = llvm::PoisonValue::get(getTypes().ConvertType(ASTTy)); + NeedsGlobalCtor = true; + } else if (getLangOpts().CPlusPlus) { Init = EmitNullConstant(T); if (!IsDefinitionAvailableExternally) NeedsGlobalCtor = true; @@ -5735,6 +5738,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, !D->hasAttr()) Linkage = llvm::GlobalValue::InternalLinkage; + // For HLSL resources, the GV is an internal wrapper containing a handle to + // external resource. + if (getLangOpts().HLSL && getHLSLRuntime().isResource(D)) + Linkage = llvm::GlobalValue::InternalLinkage; + GV->setLinkage(Linkage); if (D->hasAttr()) GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); diff --git a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl index 7fc6f4bb05745..5f71358109e68 100644 --- a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl @@ -11,9 +11,9 @@ RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4); // CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) } // CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) } -// CHECK: @Buffer0 = global %"class.hlsl::ByteAddressBuffer" zeroinitializer, align 4 -// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4 -// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4 +// CHECK: @Buffer0 = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4 +// CHECK: @Buffer1 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4 +// CHECK: @Buffer2 = internal global %"class.hlsl::RasterizerOrderedByteAddressBuffer" poison, align 4 // CHECK; define internal void @_init_resource_Buffer0() // 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) diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor-opt.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor-opt.hlsl index 03f22620a097d..239fb6d556999 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor-opt.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor-opt.hlsl @@ -1,8 +1,7 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-compute -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv-vulkan-compute -x hlsl -emit-llvm -O3 -o - %s | FileCheck %s -// CHECK-SPIRV: %"class.hlsl::RWBuffer" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0) } -// CHECK-DXIL: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) } +// All referenced to an unused resource should be removed by optimizations. RWBuffer Buf : register(u5, space3); [shader("compute")] @@ -10,12 +9,5 @@ RWBuffer Buf : register(u5, space3); void main() { // CHECK: define void @main() // CHECK-NEXT: entry: - -// 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) -// CHECK-SPIRV-NEXT: store target("spirv.Image", float, 5, 2, 0, 0, 2, 0) %[[HANDLE:.*]], ptr @Buf, align 8 - -// 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) -// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %[[HANDLE]], ptr @Buf, align 4 - // CHECK-NEXT: ret void } diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl index d7cc3892a404b..9df5d2a7f2624 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl @@ -7,7 +7,7 @@ RWBuffer Buf : register(u5, space3); // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) } -// CHECK: @Buf = global %"class.hlsl::RWBuffer" zeroinitializer, align 4 +// CHECK: @Buf = internal global %"class.hlsl::RWBuffer" poison, align 4 // CHECK: define internal void @_init_resource_Buf() // 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) diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl index bd931181045ba..4b64c3e28fb9b 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl @@ -15,11 +15,11 @@ RasterizerOrderedStructuredBuffer Buf5 : register(u1, space2); // CHECK: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } // CHECK: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) } -// CHECK: @Buf = global %"class.hlsl::StructuredBuffer" zeroinitializer, align 4 -// CHECK: @Buf2 = global %"class.hlsl::RWStructuredBuffer" zeroinitializer, align 4 -// CHECK: @Buf3 = global %"class.hlsl::AppendStructuredBuffer" zeroinitializer, align 4 -// CHECK: @Buf4 = global %"class.hlsl::ConsumeStructuredBuffer" zeroinitializer, align 4 -// CHECK: @Buf5 = global %"class.hlsl::RasterizerOrderedStructuredBuffer" zeroinitializer, align 4 +// CHECK: @Buf = internal global %"class.hlsl::StructuredBuffer" poison, align 4 +// CHECK: @Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4 +// CHECK: @Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4 +// CHECK: @Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4 +// CHECK: @Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4 // CHECK: define internal void @_init_resource_Buf() // 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)