Skip to content

Commit e9a8048

Browse files
committed
Implement resource constructors
Adds resource constructor that initializes resource handle based on resource binding Updated default constructor to set the handle value to poison WIP
1 parent 4301a06 commit e9a8048

14 files changed

+404
-96
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,6 +4783,18 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
47834783
let Prototype = "void(...)";
47844784
}
47854785

4786+
def HLSLResourceCreatePoisonHandle : LangBuiltin<"HLSL_LANG"> {
4787+
let Spellings = ["__builtin_hlsl_resource_createpoisonhandle"];
4788+
let Attributes = [NoThrow];
4789+
let Prototype = "void(...)";
4790+
}
4791+
4792+
def HLSLResourceCreateHandleFromBinding : LangBuiltin<"HLSL_LANG"> {
4793+
let Spellings = ["__builtin_hlsl_resource_createhandlefrombinding"];
4794+
let Attributes = [NoThrow];
4795+
let Prototype = "void(...)";
4796+
}
4797+
47864798
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
47874799
let Spellings = ["__builtin_hlsl_all"];
47884800
let Attributes = [NoThrow, Const];

clang/include/clang/Sema/SemaHLSL.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class SemaHLSL : public SemaBase {
105105
HLSLParamModifierAttr::Spelling Spelling);
106106
void ActOnTopLevelFunction(FunctionDecl *FD);
107107
void ActOnVariableDeclarator(VarDecl *VD);
108+
bool ActOnUninitializedVarDecl(VarDecl *D);
108109
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
109110
void CheckEntryPoint(FunctionDecl *FD);
110111
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
@@ -179,6 +180,9 @@ class SemaHLSL : public SemaBase {
179180
void processExplicitBindingsOnDecl(VarDecl *D);
180181

181182
void diagnoseAvailabilityViolations(TranslationUnitDecl *TU);
183+
bool initResourceVarFromBinding(VarDecl *VD, unsigned SpaceNo,
184+
unsigned RegisterNo, int32_t Range,
185+
unsigned Index);
182186
};
183187

184188
} // namespace clang

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19579,6 +19579,24 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1957919579
RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
1958019580
ArrayRef<Value *>{HandleOp, IndexOp});
1958119581
}
19582+
case Builtin::BI__builtin_hlsl_resource_createpoisonhandle: {
19583+
llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
19584+
return llvm::PoisonValue::get(HandleTy);
19585+
}
19586+
case Builtin::BI__builtin_hlsl_resource_createhandlefrombinding: {
19587+
llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
19588+
Value *SpaceNoOp = EmitScalarExpr(E->getArg(1));
19589+
Value *RegisterNoOp = EmitScalarExpr(E->getArg(2));
19590+
Value *RangeOp = EmitScalarExpr(E->getArg(3));
19591+
Value *IndexOp = EmitScalarExpr(E->getArg(4));
19592+
// FIXME: NonUniformResourceIndex bit is not yet implemented
19593+
Value *NonUniform =
19594+
llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()), false);
19595+
return Builder.CreateIntrinsic(
19596+
HandleTy, CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(),
19597+
ArrayRef<Value *>{SpaceNoOp, RegisterNoOp, RangeOp, IndexOp,
19598+
NonUniform});
19599+
}
1958219600
case Builtin::BI__builtin_hlsl_all: {
1958319601
Value *Op0 = EmitScalarExpr(E->getArg(0));
1958419602
return Builder.CreateIntrinsic(

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ void CGHLSLRuntime::handleGlobalVarDefinition(const VarDecl *VD,
659659
// not implemented yet.
660660
return;
661661

662-
createResourceInitFn(CGM, GV, RBA->getSlotNumber(), RBA->getSpaceNumber());
662+
// createResourceInitFn(CGM, GV, RBA->getSlotNumber(), RBA->getSpaceNumber());
663663
}
664664

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

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
399399

400400
// create params & set them to the function prototype
401401
SmallVector<ParmVarDecl *> ParmDecls;
402+
unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
402403
auto FnProtoLoc =
403404
Method->getTypeSourceInfo()->getTypeLoc().getAs<FunctionProtoTypeLoc>();
404405
for (int I = 0, E = Params.size(); I != E; I++) {
@@ -413,6 +414,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
413414
HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
414415
Parm->addAttr(Mod);
415416
}
417+
Parm->setScopeInfo(CurScopeDepth, I);
416418
ParmDecls.push_back(Parm);
417419
FnProtoLoc.setParam(I, Parm);
418420
}
@@ -446,10 +448,14 @@ BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName,
446448
AST, NestedNameSpecifierLoc(), SourceLocation(), FD, false,
447449
FD->getNameInfo(), AST.BuiltinFnTy, VK_PRValue);
448450

451+
auto *ImpCast = ImplicitCastExpr::Create(
452+
AST, AST.getPointerType(FD->getType()), CK_BuiltinFnToFnPtr, DRE, nullptr,
453+
VK_PRValue, FPOptionsOverride());
454+
449455
if (ReturnType.isNull())
450456
ReturnType = FD->getReturnType();
451457

452-
Expr *Call = CallExpr::Create(AST, DRE, Args, ReturnType, VK_PRValue,
458+
Expr *Call = CallExpr::Create(AST, ImpCast, Args, ReturnType, VK_PRValue,
453459
SourceLocation(), FPOptionsOverride());
454460
StmtsList.push_back(Call);
455461
return *this;
@@ -634,11 +640,32 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() {
634640
if (Record->isCompleteDefinition())
635641
return *this;
636642

637-
// FIXME: initialize handle to poison value; this can be added after
638-
// resource constructor from binding is implemented, otherwise the handle
639-
// value will get overwritten.
643+
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
640644
return BuiltinTypeMethodBuilder(*this, "", SemaRef.getASTContext().VoidTy,
641645
false, true)
646+
.callBuiltin("__builtin_hlsl_resource_createpoisonhandle", QualType(),
647+
PH::Handle)
648+
.assign(PH::Handle, PH::LastStmt)
649+
.finalize();
650+
}
651+
652+
BuiltinTypeDeclBuilder &
653+
BuiltinTypeDeclBuilder::addHandleConstructorFromBinding() {
654+
if (Record->isCompleteDefinition())
655+
return *this;
656+
657+
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
658+
ASTContext &AST = SemaRef.getASTContext();
659+
QualType HandleType = getResourceHandleField()->getType();
660+
661+
return BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true)
662+
.addParam("spaceNo", AST.UnsignedIntTy)
663+
.addParam("registerNo", AST.UnsignedIntTy)
664+
.addParam("range", AST.IntTy)
665+
.addParam("index", AST.UnsignedIntTy)
666+
.callBuiltin("__builtin_hlsl_resource_createhandlefrombinding",
667+
HandleType, PH::Handle, PH::_0, PH::_1, PH::_2, PH::_3)
668+
.assign(PH::Handle, PH::LastStmt)
642669
.finalize();
643670
}
644671

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class BuiltinTypeDeclBuilder {
7474

7575
// Builtin types methods
7676
BuiltinTypeDeclBuilder &addDefaultHandleConstructor();
77+
BuiltinTypeDeclBuilder &addHandleConstructorFromBinding();
7778

7879
// Builtin types methods
7980
BuiltinTypeDeclBuilder &addLoadMethods();

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
131131
bool IsROV, bool RawBuffer) {
132132
return BuiltinTypeDeclBuilder(S, Decl)
133133
.addHandleMember(RC, RK, IsROV, RawBuffer)
134-
.addDefaultHandleConstructor();
134+
.addDefaultHandleConstructor()
135+
.addHandleConstructorFromBinding();
135136
}
136137

137138
// This function is responsible for constructing the constraint expression for

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14340,10 +14340,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1434014340
Var->getType().getAddressSpace() == LangAS::opencl_local)
1434114341
return;
1434214342

14343-
// In HLSL, objects in the hlsl_constant address space are initialized
14344-
// externally, so don't synthesize an implicit initializer.
14345-
if (getLangOpts().HLSL &&
14346-
Var->getType().getAddressSpace() == LangAS::hlsl_constant)
14343+
// Handle HLSL uninitialized decls
14344+
if (getLangOpts().HLSL && HLSL().ActOnUninitializedVarDecl(Var))
1434714345
return;
1434814346

1434914347
// C++03 [dcl.init]p9:

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "clang/AST/DeclarationName.h"
2020
#include "clang/AST/DynamicRecursiveASTVisitor.h"
2121
#include "clang/AST/Expr.h"
22+
#include "clang/AST/ExprCXX.h"
2223
#include "clang/AST/Type.h"
2324
#include "clang/AST/TypeLoc.h"
2425
#include "clang/Basic/Builtins.h"
@@ -308,6 +309,10 @@ static bool isResourceRecordTypeOrArrayOf(const Type *Ty) {
308309
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
309310
}
310311

312+
static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
313+
return isResourceRecordTypeOrArrayOf(VD->getType().getTypePtr());
314+
}
315+
311316
// Returns true if the type is a leaf element type that is not valid to be
312317
// included in HLSL Buffer, such as a resource class, empty struct, zero-sized
313318
// array, or a builtin intangible type. Returns false it is a valid leaf element
@@ -2359,6 +2364,29 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
23592364

23602365
break;
23612366
}
2367+
case Builtin::BI__builtin_hlsl_resource_createpoisonhandle: {
2368+
if (SemaRef.checkArgCount(TheCall, 1) ||
2369+
CheckResourceHandle(&SemaRef, TheCall, 0))
2370+
return true;
2371+
// use the type of the handle (arg0) as a return type
2372+
QualType ResourceTy = TheCall->getArg(0)->getType();
2373+
TheCall->setType(ResourceTy);
2374+
break;
2375+
}
2376+
case Builtin::BI__builtin_hlsl_resource_createhandlefrombinding: {
2377+
ASTContext &AST = SemaRef.getASTContext();
2378+
if (SemaRef.checkArgCount(TheCall, 5) ||
2379+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
2380+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
2381+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy) ||
2382+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.IntTy) ||
2383+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy))
2384+
return true;
2385+
// use the type of the handle (arg0) as a return type
2386+
QualType ResourceTy = TheCall->getArg(0)->getType();
2387+
TheCall->setType(ResourceTy);
2388+
break;
2389+
}
23622390
case Builtin::BI__builtin_hlsl_and:
23632391
case Builtin::BI__builtin_hlsl_or: {
23642392
if (SemaRef.checkArgCount(TheCall, 2))
@@ -3147,6 +3175,65 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
31473175
}
31483176
}
31493177

3178+
bool SemaHLSL::initResourceVarFromBinding(VarDecl *VD, unsigned SpaceNo,
3179+
unsigned RegisterNo, int32_t Range,
3180+
unsigned Index) {
3181+
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
3182+
InitializationKind Kind = InitializationKind::CreateDirect(
3183+
VD->getLocation(), SourceLocation(), SourceLocation());
3184+
3185+
ASTContext &AST = SemaRef.getASTContext();
3186+
uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
3187+
uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
3188+
Expr *Args[] = {IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
3189+
AST.UnsignedIntTy, SourceLocation()),
3190+
IntegerLiteral::Create(AST,
3191+
llvm::APInt(UIntTySize, RegisterNo),
3192+
AST.UnsignedIntTy, SourceLocation()),
3193+
IntegerLiteral::Create(AST, llvm::APInt(IntTySize, Range),
3194+
AST.IntTy, SourceLocation()),
3195+
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Index),
3196+
AST.UnsignedIntTy, SourceLocation())};
3197+
3198+
InitializationSequence InitSeq(SemaRef, Entity, Kind, Args);
3199+
ExprResult Init = InitSeq.Perform(SemaRef, Entity, Kind, Args);
3200+
3201+
if (!Init.get())
3202+
return false;
3203+
3204+
VD->setInit(SemaRef.MaybeCreateExprWithCleanups(Init.get()));
3205+
VD->setInitStyle(VarDecl::CallInit);
3206+
SemaRef.CheckCompleteVariableDeclaration(VD);
3207+
return true;
3208+
}
3209+
3210+
// Returns true in the initialization has been handled;
3211+
// Return false to let Clang handle the default initializaton.
3212+
bool SemaHLSL::ActOnUninitializedVarDecl(VarDecl *VD) {
3213+
// Objects in the hlsl_constant address space are initialized
3214+
// externally, so don't synthesize an implicit initializer.
3215+
if (VD->getType().getAddressSpace() == LangAS::hlsl_constant)
3216+
return true;
3217+
3218+
// Initialize resources (explicit binding)
3219+
// NOTE: it would probably be best to do this for all resources at the end
3220+
// of the translation unit after implicit bindings are assigned.
3221+
if (!isResourceRecordTypeOrArrayOf(VD))
3222+
return false;
3223+
3224+
// FIXME: We currectly support only simple resources - no arrays of resources
3225+
// or resources in user defined structs).
3226+
if (!VD->getType()->isHLSLResourceRecord())
3227+
return false;
3228+
3229+
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
3230+
if (!RBA)
3231+
return false;
3232+
3233+
return initResourceVarFromBinding(VD, RBA->getSpaceNumber(),
3234+
RBA->getSlotNumber(), 1, 0);
3235+
}
3236+
31503237
// Walks though the global variable declaration, collects all resource binding
31513238
// requirements and adds them to Bindings
31523239
void SemaHLSL::collectResourceBindingsOnVarDecl(VarDecl *VD) {

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

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,85 @@
33

44
// NOTE: SPIRV codegen for resource types is not yet implemented
55

6-
ByteAddressBuffer Buffer0: register(t0);
7-
RWByteAddressBuffer Buffer1: register(u1, space2);
8-
RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4);
6+
ByteAddressBuffer Buf1: register(t1, space2);
7+
RWByteAddressBuffer Buf2;
98

10-
// CHECK: "class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) }
11-
// CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
12-
// CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
9+
export void foo() {
10+
RasterizerOrderedByteAddressBuffer Buf3;
11+
}
1312

14-
// CHECK: @_ZL7Buffer0 = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4
15-
// CHECK: @_ZL7Buffer1 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
16-
// CHECK: @_ZL7Buffer2 = internal global %"class.hlsl::RasterizerOrderedByteAddressBuffer" poison, align 4
13+
// CHECK: %"class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) }
14+
// CHECK: %"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
15+
// CHECK: %"class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
1716

18-
// CHECK; define internal void @_init_resource_Buffer0()
19-
// CHECK-DXIL: [[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) [[H]], ptr @_ZL7Buffer0, align 4
17+
// CHECK: @_ZL4Buf1 = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4
18+
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
2119

22-
// CHECK; define internal void @_init_resource_Buffer1()
23-
// CHECK-DXIL: [[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) [[H]], ptr @_ZL7Buffer1, align 4
20+
//
21+
// Buf1 initialization part 1 - constructor that creates handle from binding
22+
//
23+
// CHECK: define internal void @__cxx_global_var_init()
24+
// CHECK-NEXT: entry:
25+
// CHECK-NEXT: call void @_ZN4hlsl17ByteAddressBufferC1Ejjij(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf1,
26+
// CHECK-SAME: i32 noundef 2, i32 noundef 1, i32 noundef 1, i32 noundef 0)
2527

26-
// CHECK; define internal void @_init_resource_Buffer2()
27-
// CHECK-DXIL: [[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) [[H]], ptr @_ZL7Buffer2, align 4
28+
// CHECK: define linkonce_odr void @_ZN4hlsl17ByteAddressBufferC1Ejjij(ptr noundef nonnull align 4 dereferenceable(4) %this,
29+
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %registerNo, i32 noundef %range, i32 noundef %index)
30+
// CHECK: call void @_ZN4hlsl17ByteAddressBufferC2Ejjij(ptr noundef nonnull align 4 dereferenceable(4) %this1,
31+
// CHECK-SAME: i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3)
32+
33+
//
34+
// Buf2 initialization part 1 - default constructor that initializes handle to poison
35+
//
36+
37+
// CHECK: define internal void @__cxx_global_var_init.1()
38+
// CHECK-NEXT: entry:
39+
// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2)
40+
41+
// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
42+
// CHECK: call void @_ZN4hlsl19RWByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this1)
43+
44+
//
45+
// Buf3 initialization part 1 - local variable with default constructor that initializes handle to poison
46+
//
47+
48+
// CHECK: define void @_Z3foov() #2 {
49+
// CHECK-NEXT: entry:
50+
// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::RasterizerOrderedByteAddressBuffer", align 4
51+
// CHECK-NEXT: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3)
52+
53+
// CHECK: define linkonce_odr void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
54+
// CHECK: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this1)
55+
56+
//
57+
// Buf1 initialization part 2 - body of constructor that creates handle from binding
58+
//
59+
// CHECK: define linkonce_odr void @_ZN4hlsl17ByteAddressBufferC2Ejjij(ptr noundef nonnull align 4 dereferenceable(4) %this,
60+
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %registerNo, i32 noundef %range, i32 noundef %index)
61+
// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
62+
// CHECK-SAME: i32 %0, i32 %1, i32 %2, i32 %3, i1 false)
63+
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %this1, i32 0, i32 0
64+
// CHECK: store target("dx.RawBuffer", i8, 0, 0) %[[HANDLE]], ptr %[[HANDLE_PTR]], align 4
65+
66+
//
67+
// Buf2 initialization part 2 - body of default constructor that initializes handle to poison
68+
//
69+
// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
70+
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %this1, i32 0, i32 0
71+
// CHECK: store i8 poison, ptr %[[HANDLE_PTR]], align 4
72+
73+
//
74+
// Buf3 initialization part 2 - body of default constructor that initializes handle to poison
75+
//
76+
// CHECK: define linkonce_odr void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
77+
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedByteAddressBuffer", ptr %this1, i32 0, i32 0
78+
// CHECK: store i8 poison, ptr %[[HANDLE_PTR]], align 4
79+
80+
//
81+
// Module initialization
82+
//
2983

3084
// CHECK: define internal void @_GLOBAL__sub_I_ByteAddressBuffers_constructors.hlsl()
31-
// CHECK: entry:
32-
// CHECK: call void @_init_resource__ZL7Buffer0()
33-
// CHECK: call void @_init_resource__ZL7Buffer1()
34-
// CHECK: call void @_init_resource__ZL7Buffer2()
85+
// CHECK-NEXT: entry:
86+
// CHECK-NEXT: call void @__cxx_global_var_init()
87+
// CHECK-NEXT: call void @__cxx_global_var_init.1()

0 commit comments

Comments
 (0)