Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7a0d3ca
[HLSL] Reorder the arguments of handle initialization builtins
hekota Aug 28, 2025
dcbbda4
[HLSL] Add static methods for resource initialization and a construct…
hekota Aug 28, 2025
02342c9
[HLSL] Use static create methods to initialize individual resources
hekota Sep 2, 2025
b13a530
cleanup
hekota Sep 3, 2025
a0cfc72
Merge branch 'main' of https://github.com/llvm/llvm-project into res-…
hekota Sep 3, 2025
1e6f4de
Merge branch 'users/hekota/pr155861-res-create-0-reorder-builtin-args…
hekota Sep 3, 2025
dfc07bd
Remove handle constructor, update create methods body and expected AS…
hekota Sep 4, 2025
a41cf8a
Merge branch 'main' of https://github.com/llvm/llvm-project into res-…
hekota Sep 4, 2025
e7641e1
cleanup
hekota Sep 4, 2025
6028194
clang-format
hekota Sep 4, 2025
ea93f39
Merge branch 'users/hekota/pr155866-res-create-1-add-methods' into re…
hekota Sep 4, 2025
e7d6ee6
Update tests after create methods body change
hekota Sep 4, 2025
84883bc
Merge branch 'main' of https://github.com/llvm/llvm-project into res-…
hekota Sep 4, 2025
7782eea
Update tests to use llvm-cxxfilt to have unmangled names in the basel…
hekota Sep 4, 2025
f64525e
Merge branch 'users/hekota/pr155866-res-create-1-add-methods' of http…
hekota Sep 4, 2025
dfa4144
Merge branch 'main' of https://github.com/llvm/llvm-project into res-…
hekota Sep 10, 2025
c7b35b9
update PR after merge from main that introduced explicit copy constru…
hekota Sep 11, 2025
b487a54
more cleanup after merge
hekota Sep 12, 2025
cdc85ca
clang-format
hekota Sep 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
Expand Down Expand Up @@ -48,6 +49,14 @@ static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
"Since this is a builtin it should always resolve!");
return cast<FunctionDecl>(R.getFoundDecl());
}

CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
assert(ResTy->isRecordType() && "not a CXXRecord type");
for (auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
if (CD->isCopyConstructor())
return CD;
return nullptr;
}
} // namespace

// Builder for template arguments of builtin types. Used internally
Expand Down Expand Up @@ -580,6 +589,20 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) {

Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();

QualType Ty = ReturnValueExpr->getType();
if (Ty->isRecordType()) {
// For record types, create a call to copy constructor to ensure proper copy
// semantics.
auto *ICE =
ImplicitCastExpr::Create(AST, Ty.withConst(), CK_NoOp, ReturnValueExpr,
nullptr, VK_XValue, FPOptionsOverride());
CXXConstructorDecl *CD = lookupCopyConstructor(Ty);
assert(CD && "no copy constructor found");
ReturnValueExpr = CXXConstructExpr::Create(
AST, Ty, SourceLocation(), CD, false, {ICE}, false, false, false, false,
CXXConstructionKind::Complete, SourceRange());
}
StmtsList.push_back(
ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr));
return *this;
Expand Down
128 changes: 103 additions & 25 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,14 @@ struct PerVisibilityBindingChecker {
}
};

static CXXMethodDecl *lookupMethod(CXXRecordDecl *Record, StringRef Name,
StorageClass SC = SC_None) {
for (auto *Method : Record->methods())
if (Method->getStorageClass() == SC && Method->getName() == Name)
return Method;
return nullptr;
}

} // end anonymous namespace

bool SemaHLSL::handleRootSignatureElements(
Expand Down Expand Up @@ -3738,26 +3746,6 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
deduceAddressSpace(VD);
}

static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
MutableArrayRef<Expr *> Args) {
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
InitializationKind Kind = InitializationKind::CreateDirect(
VD->getLocation(), SourceLocation(), SourceLocation());

InitializationSequence InitSeq(S, Entity, Kind, Args);
if (InitSeq.Failed())
return false;

ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args);
if (!Init.get())
return false;

VD->setInit(S.MaybeCreateExprWithCleanups(Init.get()));
VD->setInitStyle(VarDecl::CallInit);
S.CheckCompleteVariableDeclaration(VD);
return true;
}

void SemaHLSL::createResourceRecordCtorArgs(
const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA,
HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex,
Expand Down Expand Up @@ -3808,11 +3796,101 @@ void SemaHLSL::createResourceRecordCtorArgs(
}

bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
SmallVector<Expr *> Args;
createResourceRecordCtorArgs(VD->getType().getTypePtr(), VD->getName(),
VD->getAttr<HLSLResourceBindingAttr>(),
VD->getAttr<HLSLVkBindingAttr>(), 0, Args);
return initVarDeclWithCtor(SemaRef, VD, Args);
assert(VD->getType()->isHLSLResourceRecord() &&
"expected resource record type");

ASTContext &AST = SemaRef.getASTContext();
uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
uint64_t IntTySize = AST.getTypeSize(AST.IntTy);

// Gather resource binding information from attributes.
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
std::optional<uint32_t> RegisterSlot;
uint32_t SpaceNo = 0;
if (VkBinding) {
RegisterSlot = VkBinding->getBinding();
SpaceNo = VkBinding->getSet();
} else if (RBA) {
if (RBA->hasRegisterSlot())
RegisterSlot = RBA->getSlotNumber();
SpaceNo = RBA->getSpaceNumber();
}

// Find correct initialization method and create its arguments.
QualType ResourceTy = VD->getType();
CXXRecordDecl *ResourceDecl = ResourceTy->getAsCXXRecordDecl();
CXXMethodDecl *CreateMethod = nullptr;
llvm::SmallVector<Expr *> Args;

if (RegisterSlot.has_value()) {
// The resource has explicit binding.
CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
IntegerLiteral *RegSlot = IntegerLiteral::Create(
AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy,
SourceLocation());
Args.push_back(RegSlot);
} else {
// The resource has implicit binding.
CreateMethod =
lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
? RBA->getImplicitBindingOrderID()
: getNextImplicitBindingOrderID();
IntegerLiteral *OrderId =
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID),
AST.UnsignedIntTy, SourceLocation());
Args.push_back(OrderId);
}

if (!CreateMethod)
return false;

IntegerLiteral *Space =
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
AST.UnsignedIntTy, SourceLocation());
Args.push_back(Space);

IntegerLiteral *RangeSize = IntegerLiteral::Create(
AST, llvm::APInt(IntTySize, 1), AST.IntTy, SourceLocation());
Args.push_back(RangeSize);

IntegerLiteral *Index = IntegerLiteral::Create(
AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy, SourceLocation());
Args.push_back(Index);

StringRef VarName = VD->getName();
StringLiteral *Name = StringLiteral::Create(
AST, VarName, StringLiteralKind::Ordinary, false,
AST.getStringLiteralArrayType(AST.CharTy.withConst(), VarName.size()),
SourceLocation());
ImplicitCastExpr *NameCast = ImplicitCastExpr::Create(
AST, AST.getPointerType(AST.CharTy.withConst()), CK_ArrayToPointerDecay,
Name, nullptr, VK_PRValue, FPOptionsOverride());
Args.push_back(NameCast);

// Make sure the create method template is instantiated and emitted.
if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation())
SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod,
true);

// Create CallExpr with a call to the static method and set it as the decl
// initialization.
DeclRefExpr *DRE = DeclRefExpr::Create(
AST, NestedNameSpecifierLoc(), SourceLocation(), CreateMethod, false,
CreateMethod->getNameInfo(), CreateMethod->getType(), VK_PRValue);

auto *ImpCast = ImplicitCastExpr::Create(
AST, AST.getPointerType(CreateMethod->getType()),
CK_FunctionToPointerDecay, DRE, nullptr, VK_PRValue, FPOptionsOverride());

CallExpr *InitExpr =
CallExpr::Create(AST, ImpCast, Args, ResourceTy, VK_PRValue,
SourceLocation(), FPOptionsOverride());
VD->setInit(InitExpr);
VD->setInitStyle(VarDecl::CallInit);
SemaRef.CheckCompleteVariableDeclaration(VD);
return true;
}

bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) {
Expand Down
6 changes: 5 additions & 1 deletion clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RESOURCE Buffer;

#endif

// CHECK: CXXRecordDecl {{.*}} implicit referenced <undeserialized declarations> class [[RESOURCE]] definition
// CHECK: CXXRecordDecl {{.*}} implicit referenced class [[RESOURCE]] definition
// CHECK: FinalAttr {{.*}} Implicit final
// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
Expand Down Expand Up @@ -107,6 +107,8 @@ RESOURCE Buffer;
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *'
// CHECK-NEXT: ReturnStmt
// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (const hlsl::[[RESOURCE]] &)'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[RESOURCE]]' xvalue <NoOp>
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline

Expand Down Expand Up @@ -135,6 +137,8 @@ RESOURCE Buffer;
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *'
// CHECK-NEXT: ReturnStmt
// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (const hlsl::[[RESOURCE]] &)'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[RESOURCE]]' xvalue <NoOp>
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline

Expand Down
48 changes: 37 additions & 11 deletions clang/test/AST/HLSL/vk_binding_attr.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-library -finclude-default-header -ast-dump -o - %s | FileCheck %s -check-prefixes=DXIL,CHECK

// CHECK: VarDecl {{.*}} Buf 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// SPV-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 102
// DXIL-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// DXIL-NEXT: IntegerLiteral {{.*}} 'int' 1
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// SPV: HLSLVkBindingAttr {{.*}} 23 102
// DXIL-NOT: HLSLVkBindingAttr
[[vk::binding(23, 102)]] StructuredBuffer<float> Buf;

// CHECK: VarDecl {{.*}} Buf2 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// CHECK-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 14
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
Expand All @@ -24,7 +29,10 @@
[[vk::binding(14, 1)]] StructuredBuffer<float> Buf2 : register(t23, space102);

// CHECK: VarDecl {{.*}} Buf3 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// CHECK-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 14
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
Expand All @@ -43,28 +51,46 @@
}

// CHECK: VarDecl {{.*}} Buf4 'Buffer<int>':'hlsl::Buffer<int>'
// SPV-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::Buffer<int> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 24
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 103
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// SPV: HLSLVkBindingAttr {{.*}} 24 103
// DXIL-NOT: HLSLVkBindingAttr
[[vk::binding(24, 103)]] Buffer<int> Buf4;

// CHECK: VarDecl {{.*}} Buf5 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>'
// SPV-NEXT: CXXConstructExpr {{.*}} 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'Buffer<int2> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 25
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 104
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer<int2> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// SPV: HLSLVkBindingAttr {{.*}} 25 104
// DXIL-NOT: HLSLVkBindingAttr
[[vk::binding(25, 104)]] RWBuffer<int2> Buf5;

// CHECK: VarDecl {{.*}} Buf6 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>'
// SPV-NEXT: CXXConstructExpr {{.*}} 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
// CHECK-NEXT: CallExpr {{.*}} 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 26
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 105
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 4
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
// SPV: HLSLVkBindingAttr {{.*}} 26 105
// DXIL-NOT: HLSLVkBindingAttr
[[vk::binding(26, 105)]] RWStructuredBuffer<int> Buf6;
21 changes: 15 additions & 6 deletions clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -O0 %s -o - | FileCheck %s --check-prefixes=CHECK,INLINE
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes %s -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,NOINLINE
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -O0 %s -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,INLINE

// Make sure global variable for ctors exist for lib profile.
// CHECK:@llvm.global_ctors
Expand All @@ -13,7 +13,7 @@ void FirstEntry() {}
// CHECK: define void @FirstEntry()
// CHECK-NEXT: entry:
// NOINLINE-NEXT: call void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl()
// NOINLINE-NEXT: call void @_Z10FirstEntryv()
// NOINLINE-NEXT: call void @FirstEntry()
// Verify inlining leaves only calls to "llvm." intrinsics
// INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
// CHECK: ret void
Expand All @@ -25,15 +25,24 @@ void SecondEntry() {}
// CHECK: define void @SecondEntry()
// CHECK-NEXT: entry:
// NOINLINE-NEXT: call void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl()
// NOINLINE-NEXT: call void @_Z11SecondEntryv()
// NOINLINE-NEXT: call void @SecondEntry()
// Verify inlining leaves only calls to "llvm." intrinsics
// INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
// CHECK: ret void


// Verify the constructor is alwaysinline
// Verify the constructors are alwaysinline
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EjijjPKc({{.*}} [[CtorAttr:\#[0-9]+]]
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer()({{.*}}){{.*}} [[CtorAttr:\#[0-9]+]]

// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer(hlsl::RWBuffer<float> const&)({{.*}}){{.*}} [[CtorAttr]]

// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer()(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]

// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer(hlsl::RWBuffer<float> const&)({{.*}}){{.*}} [[CtorAttr]]

// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]]
Expand Down
Loading
Loading