Skip to content

Commit 719f0d9

Browse files
authored
[HLSL] Fix global resource initialization (#123394)
Create separate resource initialization function for each resource and add them to CodeGenModule's `CXXGlobalInits` list. Fixes #120636 and addresses this [comment ](https://github.com/llvm/llvm-project/pull/119755/files#r1894093603).
1 parent 7e622b6 commit 719f0d9

9 files changed

+128
-133
lines changed

clang/lib/CodeGen/CGDeclCXX.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,14 +1131,6 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
11311131
if (Decls[i])
11321132
EmitRuntimeCall(Decls[i]);
11331133

1134-
if (getLangOpts().HLSL) {
1135-
CGHLSLRuntime &CGHLSL = CGM.getHLSLRuntime();
1136-
if (CGHLSL.needsResourceBindingInitFn()) {
1137-
llvm::Function *ResInitFn = CGHLSL.createResourceBindingInitFn();
1138-
Builder.CreateCall(llvm::FunctionCallee(ResInitFn), {});
1139-
}
1140-
}
1141-
11421134
Scope.ForceCleanup();
11431135

11441136
if (ExitBlock) {

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -536,89 +536,85 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() {
536536
}
537537
}
538538

539-
void CGHLSLRuntime::handleGlobalVarDefinition(const VarDecl *VD,
540-
llvm::GlobalVariable *GV) {
541-
// If the global variable has resource binding, add it to the list of globals
542-
// that need resource binding initialization.
543-
const HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
544-
if (!RBA)
545-
return;
546-
547-
if (!HLSLAttributedResourceType::findHandleTypeOnResource(
548-
VD->getType().getTypePtr()))
549-
// FIXME: Only simple declarations of resources are supported for now.
550-
// Arrays of resources or resources in user defined classes are
551-
// not implemented yet.
552-
return;
553-
554-
ResourcesToBind.emplace_back(VD, GV);
555-
}
556-
557-
bool CGHLSLRuntime::needsResourceBindingInitFn() {
558-
return !ResourcesToBind.empty();
539+
// Returns true if the type is an HLSL resource class
540+
static bool isResourceRecordType(const clang::Type *Ty) {
541+
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
559542
}
560543

561-
llvm::Function *CGHLSLRuntime::createResourceBindingInitFn() {
562-
// No resources to bind
563-
assert(needsResourceBindingInitFn() && "no resources to bind");
564-
544+
static void createResourceInitFn(CodeGenModule &CGM, const VarDecl *VD,
545+
llvm::GlobalVariable *GV, unsigned Slot,
546+
unsigned Space) {
565547
LLVMContext &Ctx = CGM.getLLVMContext();
566548
llvm::Type *Int1Ty = llvm::Type::getInt1Ty(Ctx);
567549

568-
llvm::Function *InitResBindingsFunc =
569-
llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, false),
570-
llvm::GlobalValue::InternalLinkage,
571-
"_init_resource_bindings", CGM.getModule());
550+
llvm::Function *InitResFunc = llvm::Function::Create(
551+
llvm::FunctionType::get(CGM.VoidTy, false),
552+
llvm::GlobalValue::InternalLinkage,
553+
("_init_resource_" + VD->getName()).str(), CGM.getModule());
554+
InitResFunc->addFnAttr(llvm::Attribute::AlwaysInline);
572555

573556
llvm::BasicBlock *EntryBB =
574-
llvm::BasicBlock::Create(Ctx, "entry", InitResBindingsFunc);
557+
llvm::BasicBlock::Create(Ctx, "entry", InitResFunc);
575558
CGBuilderTy Builder(CGM, Ctx);
576559
const DataLayout &DL = CGM.getModule().getDataLayout();
577560
Builder.SetInsertPoint(EntryBB);
578561

579-
for (const auto &[VD, GV] : ResourcesToBind) {
580-
for (Attr *A : VD->getAttrs()) {
581-
HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
582-
if (!RBA)
583-
continue;
584-
585-
const HLSLAttributedResourceType *AttrResType =
586-
HLSLAttributedResourceType::findHandleTypeOnResource(
587-
VD->getType().getTypePtr());
588-
589-
// FIXME: Only simple declarations of resources are supported for now.
590-
// Arrays of resources or resources in user defined classes are
591-
// not implemented yet.
592-
assert(AttrResType != nullptr &&
593-
"Resource class must have a handle of HLSLAttributedResourceType");
594-
595-
llvm::Type *TargetTy =
596-
CGM.getTargetCodeGenInfo().getHLSLType(CGM, AttrResType);
597-
assert(TargetTy != nullptr &&
598-
"Failed to convert resource handle to target type");
599-
600-
auto *Space = llvm::ConstantInt::get(CGM.IntTy, RBA->getSpaceNumber());
601-
auto *Slot = llvm::ConstantInt::get(CGM.IntTy, RBA->getSlotNumber());
562+
const HLSLAttributedResourceType *AttrResType =
563+
HLSLAttributedResourceType::findHandleTypeOnResource(
564+
VD->getType().getTypePtr());
565+
566+
// FIXME: Only simple declarations of resources are supported for now.
567+
// Arrays of resources or resources in user defined classes are
568+
// not implemented yet.
569+
assert(AttrResType != nullptr &&
570+
"Resource class must have a handle of HLSLAttributedResourceType");
571+
572+
llvm::Type *TargetTy =
573+
CGM.getTargetCodeGenInfo().getHLSLType(CGM, AttrResType);
574+
assert(TargetTy != nullptr &&
575+
"Failed to convert resource handle to target type");
576+
577+
llvm::Value *Args[] = {
578+
llvm::ConstantInt::get(CGM.IntTy, Space), /* reg_space */
579+
llvm::ConstantInt::get(CGM.IntTy, Slot), /* lower_bound */
602580
// FIXME: resource arrays are not yet implemented
603-
auto *Range = llvm::ConstantInt::get(CGM.IntTy, 1);
604-
auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
581+
llvm::ConstantInt::get(CGM.IntTy, 1), /* range_size */
582+
llvm::ConstantInt::get(CGM.IntTy, 0), /* index */
605583
// FIXME: NonUniformResourceIndex bit is not yet implemented
606-
auto *NonUniform = llvm::ConstantInt::get(Int1Ty, false);
607-
llvm::Value *Args[] = {Space, Slot, Range, Index, NonUniform};
584+
llvm::ConstantInt::get(Int1Ty, false) /* non-uniform */
585+
};
586+
llvm::Value *CreateHandle = Builder.CreateIntrinsic(
587+
/*ReturnType=*/TargetTy,
588+
CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(), Args, nullptr,
589+
Twine(VD->getName()).concat("_h"));
590+
591+
llvm::Value *HandleRef = Builder.CreateStructGEP(GV->getValueType(), GV, 0);
592+
Builder.CreateAlignedStore(CreateHandle, HandleRef,
593+
HandleRef->getPointerAlignment(DL));
594+
Builder.CreateRetVoid();
608595

609-
llvm::Value *CreateHandle = Builder.CreateIntrinsic(
610-
/*ReturnType=*/TargetTy, getCreateHandleFromBindingIntrinsic(), Args,
611-
nullptr, Twine(VD->getName()).concat("_h"));
596+
CGM.AddCXXGlobalInit(InitResFunc);
597+
}
612598

613-
llvm::Value *HandleRef =
614-
Builder.CreateStructGEP(GV->getValueType(), GV, 0);
615-
Builder.CreateAlignedStore(CreateHandle, HandleRef,
616-
HandleRef->getPointerAlignment(DL));
617-
}
618-
}
599+
void CGHLSLRuntime::handleGlobalVarDefinition(const VarDecl *VD,
600+
llvm::GlobalVariable *GV) {
619601

620-
Builder.CreateRetVoid();
621-
return InitResBindingsFunc;
602+
// If the global variable has resource binding, create an init function
603+
// for the resource
604+
const HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
605+
if (!RBA)
606+
// FIXME: collect unbound resources for implicit binding resolution later
607+
// on?
608+
return;
609+
610+
if (!isResourceRecordType(VD->getType().getTypePtr()))
611+
// FIXME: Only simple declarations of resources are supported for now.
612+
// Arrays of resources or resources in user defined classes are
613+
// not implemented yet.
614+
return;
615+
616+
createResourceInitFn(CGM, VD, GV, RBA->getSlotNumber(),
617+
RBA->getSpaceNumber());
622618
}
623619

624620
llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) {

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ class CGHLSLRuntime {
159159
void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn);
160160
void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var);
161161

162-
bool needsResourceBindingInitFn();
163-
llvm::Function *createResourceBindingInitFn();
164162
llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB);
165163

166164
private:
@@ -173,9 +171,6 @@ class CGHLSLRuntime {
173171
void addBufferDecls(const DeclContext *DC, Buffer &CB);
174172
llvm::Triple::ArchType getArch();
175173
llvm::SmallVector<Buffer> Buffers;
176-
177-
llvm::SmallVector<std::pair<const VarDecl *, llvm::GlobalVariable *>>
178-
ResourcesToBind;
179174
};
180175

181176
} // namespace CodeGen

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,8 @@ class CodeGenModule : public CodeGenTypeCache {
12261226

12271227
llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type *> Tys = {});
12281228

1229+
void AddCXXGlobalInit(llvm::Function *F) { CXXGlobalInits.push_back(F); }
1230+
12291231
/// Emit code for a single top level declaration.
12301232
void EmitTopLevelDecl(Decl *D);
12311233

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

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@ RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4);
1515
// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4
1616
// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4
1717

18+
// CHECK; define internal void @_init_resource_Buffer0()
19+
// 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)
20+
// CHECK-DXIL: store target("dx.RawBuffer", i8, 0, 0) %Buffer0_h, ptr @Buffer0, align 4
21+
22+
// CHECK; define internal void @_init_resource_Buffer1()
23+
// CHECK-DXIL: %Buffer1_h = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 2, i32 1, i32 1, i32 0, i1 false)
24+
// CHECK-DXIL: store target("dx.RawBuffer", i8, 1, 0) %Buffer1_h, ptr @Buffer1, align 4
25+
26+
// CHECK; define internal void @_init_resource_Buffer2()
27+
// CHECK-DXIL: %Buffer2_h = call target("dx.RawBuffer", i8, 1, 1) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_1t(i32 4, i32 3, i32 1, i32 0, i1 false)
28+
// CHECK-DXIL: store target("dx.RawBuffer", i8, 1, 1) %Buffer2_h, ptr @Buffer2, align 4
29+
1830
// CHECK: define internal void @_GLOBAL__sub_I_ByteAddressBuffers_constructors.hlsl()
1931
// CHECK: entry:
20-
// CHECK: call void @_init_resource_bindings()
21-
22-
// CHECK: define internal void @_init_resource_bindings() {
23-
// CHECK-NEXT: entry:
24-
// CHECK-DXIL-NEXT: %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)
25-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %Buffer0_h, ptr @Buffer0, align 4
26-
// CHECK-DXIL-NEXT: %Buffer1_h = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 2, i32 1, i32 1, i32 0, i1 false)
27-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %Buffer1_h, ptr @Buffer1, align 4
28-
// CHECK-DXIL-NEXT: %Buffer2_h = call target("dx.RawBuffer", i8, 1, 1) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_1t(i32 4, i32 3, i32 1, i32 0, i1 false)
29-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 1) %Buffer2_h, ptr @Buffer2, align 4
32+
// CHECK: call void @_init_resource_Buffer0()
33+
// CHECK: call void @_init_resource_Buffer1()
34+
// CHECK: call void @_init_resource_Buffer2()

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ void main() {
1111
// CHECK: define void @main()
1212
// CHECK-NEXT: entry:
1313

14-
// CHECK-SPIRV-NEXT: %Buf_h.i = 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) %Buf_h.i, ptr @Buf, align 8
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
1616

17-
// CHECK-DXIL-NEXT: %Buf_h.i = 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) %Buf_h.i, ptr @Buf, align 4
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
1919

2020
// CHECK-NEXT: ret void
2121
}

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,12 @@ RWBuffer<float> Buf : register(u5, space3);
99
// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
1010
// CHECK: @Buf = global %"class.hlsl::RWBuffer" zeroinitializer, align 4
1111

12+
// CHECK: define internal void @_init_resource_Buf()
13+
// 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)
14+
// CHECK-DXIL: store target("dx.TypedBuffer", float, 1, 0, 0) %Buf_h, ptr @Buf, align 4
15+
1216
// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
1317
// CHECK-NEXT: entry:
1418

1519
// CHECK: define internal void @_GLOBAL__sub_I_RWBuffer_constructor.hlsl()
16-
// CHECK-NEXT: entry:
17-
// CHECK-NEXT: call void @__cxx_global_var_init()
18-
// CHECK-NEXT: call void @_init_resource_bindings()
19-
20-
// CHECK: define internal void @_init_resource_bindings() {
21-
// CHECK-NEXT: entry:
22-
// CHECK-DXIL-NEXT: %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)
23-
// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %Buf_h, ptr @Buf, align 4
24-
// CHECK-SPIRV-NEXT: %Buf_h = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.spv.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 3, i32 5, i32 1, i32 0, i1 false)
25-
// CHECK-SPIRV-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %Buf_h, ptr @Buf, align 4
20+
// CHECK: call void @_init_resource_Buf()

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

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@ RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
2121
// CHECK: @Buf4 = global %"class.hlsl::ConsumeStructuredBuffer" zeroinitializer, align 4
2222
// CHECK: @Buf5 = global %"class.hlsl::RasterizerOrderedStructuredBuffer" zeroinitializer, align 4
2323

24+
// CHECK: define internal void @_init_resource_Buf()
25+
// 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)
26+
// CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) %Buf_h, ptr @Buf, align 4
27+
28+
// CHECK: define internal void @_init_resource_Buf2()
29+
// CHECK-DXIL: %Buf2_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, i32 0, i1 false)
30+
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) %Buf2_h, ptr @Buf2, align 4
31+
32+
// CHECK: define internal void @_init_resource_Buf3()
33+
// CHECK-DXIL: %Buf3_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false)
34+
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) %Buf3_h, ptr @Buf3, align 4
35+
36+
// CHECK: define internal void @_init_resource_Buf4()
37+
// CHECK-DXIL: %Buf4_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 4, i32 1, i32 0, i1 false)
38+
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) %Buf4_h, ptr @Buf4, align 4
39+
40+
// CHECK: define internal void @_init_resource_Buf5()
41+
// CHECK-DXIL: %Buf5_h = call target("dx.RawBuffer", float, 1, 1) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_1t(i32 2, i32 1, i32 1, i32 0, i1 false)
42+
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 1) %Buf5_h, ptr @Buf5, align 4
43+
2444
// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
2545
// CHECK-NEXT: entry:
2646
// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
@@ -32,29 +52,8 @@ RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
3252
// CHECK-NEXT: entry:
3353

3454
// CHECK: define internal void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
35-
// CHECK: entry:
36-
// CHECK: call void @_init_resource_bindings()
37-
38-
// CHECK: define internal void @_init_resource_bindings() {
39-
// CHECK-NEXT: entry:
40-
// CHECK-DXIL-NEXT: %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)
41-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 0, 0) %Buf_h, ptr @Buf, align 4
42-
// CHECK-DXIL-NEXT: %Buf2_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, i32 0, i1 false)
43-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %Buf2_h, ptr @Buf2, align 4
44-
// CHECK-DXIL-NEXT: %Buf3_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false)
45-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %Buf3_h, ptr @Buf3, align 4
46-
// CHECK-DXIL-NEXT: %Buf4_h = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 4, i32 1, i32 0, i1 false)
47-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %Buf4_h, ptr @Buf4, align 4
48-
// CHECK-DXIL-NEXT: %Buf5_h = call target("dx.RawBuffer", float, 1, 1) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_1t(i32 2, i32 1, i32 1, i32 0, i1 false)
49-
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 1) %Buf5_h, ptr @Buf5, align 4
50-
51-
// CHECK-SPIRV-NEXT: %Buf_h = call target("dx.RawBuffer", float, 0, 0) @llvm.spv.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(i32 0, i32 10, i32 1, i32 0, i1 false)
52-
// CHECK-SPIRV-NEXT: store target("dx.RawBuffer", float, 0, 0) %Buf_h, ptr @Buf", align 4
53-
// CHECK-SPIRV-NEXT: %Buf2_h = call target("dx.RawBuffer", float, 1, 0) @llvm.spv.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, i32 0, i1 false)
54-
// CHECK-SPIRV-NEXT: store target("dx.RawBuffer", float, 1, 0) %Buf2_h, ptr @Buf2", align 4
55-
// CHECK-SPIRV-NEXT: %Buf3_h = call target("dx.RawBuffer", float, 0, 0) @llvm.spv.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false)
56-
// CHECK-SPIRV-NEXT: store target("dx.RawBuffer", float, 0, 0) %Buf3_h, ptr @Buf3, align 4
57-
// CHECK-SPIRV-NEXT: %Buf4_h = call target("dx.RawBuffer", float, 1, 0) @llvm.spv.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 4, i32 1, i32 0, i1 false)
58-
// CHECK-SPIRV-NEXT: store target("dx.RawBuffer", float, 1, 0) %Buf4_h, ptr @Buf4, align 4
59-
// CHECK-SPIRV-NEXT: %Buf5_h = call target("dx.RawBuffer", float, 1, 1) @llvm.spv.resource.handlefrombinding.tdx.RawBuffer_f32_1_1t(i32 2, i32 1, i32 1, i32 0, i1 false)
60-
// CHECK-SPIRV-NEXT: store target("dx.RawBuffer", float, 1, 1) %Buf5_h, ptr @Buf5, align 4
55+
// CHECK: call void @_init_resource_Buf()
56+
// CHECK: call void @_init_resource_Buf2()
57+
// CHECK: call void @_init_resource_Buf3()
58+
// CHECK: call void @_init_resource_Buf4()
59+
// CHECK: call void @_init_resource_Buf5()
Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
1-
// RUN: %clang_cc1 -triple dxil--shadermodel6.6-compute -x hlsl -finclude-default-header -emit-llvm -o - %s | FileCheck %s
2-
3-
// CHECK: define internal void @_init_resource_bindings() {
1+
// RUN: %clang_cc1 -triple dxil--shadermodel6.6-compute -x hlsl -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
42

3+
// CHECK: define internal void @_init_resource_U0S0()
54
// CHECK: %U0S0_h = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false)
65
RWBuffer<float4> U0S0 : register(u0);
76

7+
// CHECK: define internal void @_init_resource_U5S3()
88
// CHECK: %U5S3_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)
99
RWBuffer<float> U5S3 : register(u5, space3);
1010

11+
// CHECK: define internal void @_init_resource_T2S2()
1112
// CHECK: %T2S2_h = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 2, i32 2, i32 1, i32 0, i1 false)
1213
StructuredBuffer<int> T2S2 : register(t2, space2);
1314
struct S {
1415
float4 f;
1516
int i;
1617
};
1718

19+
// CHECK: define internal void @_init_resource_T3S0()
1820
// CHECK: %T3S0_h = call target("dx.RawBuffer", %struct.S, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_s_struct.Ss_0_0t(i32 0, i32 3, i32 1, i32 0, i1 false)
1921
StructuredBuffer<S> T3S0 : register(t3);
22+
23+
// CHECK: define void @main()
24+
// CHECK: call void @_init_resource_U0S0()
25+
// CHECK: call void @_init_resource_U5S3()
26+
// CHECK: call void @_init_resource_T2S2()
27+
// CHECK: call void @_init_resource_T3S0()
28+
29+
[numthreads(4,1,1)]
30+
void main() {}

0 commit comments

Comments
 (0)