[llvm-branch-commits] [clang] [llvm] [HLSL] Use static create methods to initialize individual resources (PR #156544)
Helena Kotas via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Sep 4 15:46:37 PDT 2025
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/156544
>From 02342c922d0feec12b980528eb4a75e8d6676ebe Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Tue, 2 Sep 2025 15:03:11 -0700
Subject: [PATCH 1/4] [HLSL] Use static create methods to initialize individual
resources
---
clang/lib/Sema/SemaHLSL.cpp | 128 +++++++--
.../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 2 +-
clang/test/AST/HLSL/vk_binding_attr.hlsl | 48 +++-
.../CodeGenHLSL/GlobalConstructorLib.hlsl | 6 +-
.../debug/rwbuffer_debug_info.hlsl | 5 +-
.../ByteAddressBuffers-constructors.hlsl | 66 ++---
.../resources/RWBuffer-constructor.hlsl | 76 +++---
.../StructuredBuffers-constructors.hlsl | 69 +++--
.../resources/resource-bindings.hlsl | 20 +-
clang/test/CodeGenHLSL/static-local-ctor.hlsl | 2 +-
out.ll | 251 ++++++++++++++++++
11 files changed, 508 insertions(+), 165 deletions(-)
create mode 100644 out.ll
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index c12b35308e127..88334908073a0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -1201,6 +1201,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(
@@ -3689,26 +3697,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,
@@ -3759,11 +3747,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 argumentss.
+ 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) {
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 8336bf00ed4cb..dd861b4b07cf8 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -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)]]
diff --git a/clang/test/AST/HLSL/vk_binding_attr.hlsl b/clang/test/AST/HLSL/vk_binding_attr.hlsl
index 4cb2abdaef01a..d08165d7c593d 100644
--- a/clang/test/AST/HLSL/vk_binding_attr.hlsl
+++ b/clang/test/AST/HLSL/vk_binding_attr.hlsl
@@ -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
@@ -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
@@ -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;
diff --git a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
index afda714106fac..c3d4fbb12a6f4 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
@@ -31,9 +31,11 @@ void SecondEntry() {}
// 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 @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) {{.*}} [[CtorAttr:\#[0-9]+]]
+// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
+// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) {{.*}} [[CtorAttr]]
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]]
diff --git a/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl b/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl
index db0388e41eae9..941ab9b952685 100644
--- a/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl
+++ b/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl
@@ -1,11 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s -debug-info-kind=standalone -dwarf-version=4 | FileCheck %s
-
// CHECK: [[DWTag:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWBuffer<float>",
+// CHECK: [[thisType:![0-9]+]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[DWTag]], size: 32)
// CHECK: [[RWBuffer:![0-9]+]] = distinct !DISubprogram(name: "RWBuffer",
// CHECK-SAME: scope: [[DWTag]]
-// CHECK: [[FirstThis:![0-9]+]] = !DILocalVariable(name: "this", arg: 1, scope: [[RWBuffer]], type: [[thisType:![0-9]+]]
-// CHECK: [[thisType]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[DWTag]], size: 32)
+// CHECK: [[FirstThis:![0-9]+]] = !DILocalVariable(name: "this", arg: 1, scope: [[RWBuffer]], type: [[thisType]]
RWBuffer<float> Out : register(u7, space4);
[numthreads(8,1,1)]
diff --git a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
index 3a8d2c03e173c..35e1c14a0931f 100644
--- a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
@@ -28,29 +28,35 @@ export void foo() {
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
-// Buf1 initialization part 1 - global init function that calls ByteAddressBuffer C1 constructor with explicit binding
+// Buf1 initialization part 1 - global init function that calls ByteAddressBuffer::__createFromBinding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl17ByteAddressBufferC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf1,
+// CHECK-NEXT: call void @_ZN4hlsl17ByteAddressBuffer19__createFromBindingEjjijPKc(ptr {{.*}} @_ZL4Buf1,
// CHECK-SAME: i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
-// Buf1 initialization part 2 - body of ByteAddressBuffer C1 constructor with explicit binding that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4)
-// CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// Buf1 initialization part 2 - body of ByteAddressBuffer::__createFromBinding
+// CHECK: define {{.*}} void @_ZN4hlsl17ByteAddressBuffer19__createFromBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::ByteAddressBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle1:.*]] = call target("dx.RawBuffer", i8, 0, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
+// CHECK: call void @_ZN4hlsl17ByteAddressBufferC1EU13_Res_t_Raw_CTDuu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.RawBuffer", i8, 0, 0) %[[Handle1]])
-// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer C1 constructor with implicit binding
+// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBufferC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]])
-
-// Buf2 initialization part 2 - body of RWByteAddressBuffer C1 constructor with implicit binding that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this1,
-// CHECK-SAME: i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
+// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+
+// Buf2 initialization part 2 - body of RWByteAddressBuffer::__createFromImplicitBinding
+// CHECK: define hidden void @_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWByteAddressBuffer") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle2:.*]] = call target("dx.RawBuffer", i8, 1, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(
+// CHECK: call void @_ZN4hlsl19RWByteAddressBufferC1EU13_Res_u_Raw_CTDuu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.RawBuffer", i8, 1, 0) %[[Handle2]])
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// RasterizerOrderedByteAddressBuffer C1 default constructor
@@ -65,23 +71,17 @@ export void foo() {
// CHECK: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
// CHECK-NEXT: ret void
-// Buf1 initialization part 3 - ByteAddressBuffer C2 constructor with explicit binding that initializes
-// handle with @llvm.dx.resource.handlefrombinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
-// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %[[HANDLE]], ptr %__handle, align 4
-
-// Buf2 initialization part 3 - body of RWByteAddressBuffer C2 constructor with implicit binding that initializes
-// handle with @llvm.dx.resource.handlefromimplicitbinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t
-// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %this1, i32 0, i32 0
-// CHECK-NEXT: store target("dx.RawBuffer", i8, 1, 0) %[[HANDLE]], ptr %__handle, align 4
+// Buf1 initialization part 3 - ByteAddressBuffer constructor constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC2EU13_Res_t_Raw_CTDuu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.RawBuffer", i8, 0, 0) %handle)
+// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
+
+// Buf2 initialization part 3 - body of RWByteAddressBuffer constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC1EU13_Res_u_Raw_CTDuu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.RawBuffer", i8, 1, 0) %handle)
+// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
// Buf3 initialization part 3 - body of RasterizerOrderedByteAddressBuffer default C2 constructor that
// initializes handle to poison
diff --git a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
index 114468914e2ea..c5c40449c6c8e 100644
--- a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
+++ b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
@@ -28,60 +28,60 @@ export void foo() {
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWBuffer.0" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
-// Buf1 initialization part 1 - global init function that calls RWBuffer<float> C1 constructor with explicit binding
+// Buf1 initialization part 1 - global init function that calls RWBuffer<float>::__createFromBinding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf1,
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 @_ZL4Buf1,
// CHECK-SAME: i32 noundef 5, i32 noundef 3, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
-// Buf1 initialization part 2 - body of RWBuffer<float> C1 constructor with explicit binding that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4)
-// CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// Buf1 initialization part 2 - body of RWBuffer<float>::__createFromBinding
+// CHECK: define {{.*}} void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle1:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
+// CHECK: call void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.TypedBuffer", float, 1, 0, 0) %[[Handle1]])
-// Buf2 initialization part 1 - global init function that calls RWBuffer<float> C1 constructor with implicit binding
+// Buf2 initialization part 1 - global init function that RWBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]])
-
-// Buf2 initialization part 2 - body of RWBuffer<float> C1 constructor with implicit binding that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4)
-// CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
+// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+
+// Buf2 initialization part 2 - body of RWBuffer<float>::__createFromImplicitBinding call
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle2:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t(
+// CHECK: call void @_ZN4hlsl8RWBufferIdEC1EU9_Res_u_CTdu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.TypedBuffer", double, 1, 0, 0) %[[Handle2]])
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by RWBuffer<int> C1 default constructor
// CHECK: define void @_Z3foov()
// CHECK-NEXT: entry:
// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::RWBuffer.1", align 4
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3)
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1Ev(ptr {{.*}} %Buf3)
// Buf3 initialization part 2 - body of RWBuffer<int> default C1 constructor that calls the default C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
-// CHECK: call void @_ZN4hlsl8RWBufferIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
-
-// Buf1 initialization part 3 - body of RWBuffer<float> C2 constructor with explicit binding that initializes
-// handle with @llvm.dx.resource.handlefrombinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
-// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %[[HANDLE]], ptr %__handle, align 4
-
-// Buf2 initialization part 3 - body of RWBuffer<float> C2 constructor with implicit binding that initializes
-// handle with @llvm.dx.resource.handlefromimplicitbinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: %[[HANDLE:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t
-// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %{{.*}}, i32 0, i32 0
-// CHECK-NEXT: store target("dx.TypedBuffer", double, 1, 0, 0) %[[HANDLE]], ptr %__handle, align 4
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC1Ev(ptr {{.*}} %this)
+// CHECK: call void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %{{.*}})
+
+// Buf1 initialization part 3 - body of RWBuffer<float> constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.TypedBuffer", float, 1, 0, 0) %handle)
+// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
+
+// Buf2 initialization part 3 - body of RWBuffer<double> constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC1EU9_Res_u_CTdu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) %handle)
+// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", double, 1, 0, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
// Buf3 initialization part 3 - body of RWBuffer<int> default C2 constructor that initializes handle to poison
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.1", ptr %{{.*}}, i32 0, i32 0
// CHECK-NEXT: store target("dx.TypedBuffer", i32, 1, 0, 1) poison, ptr %__handle, align 4
diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
index 28841732df99e..834a9639484a5 100644
--- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
@@ -27,32 +27,37 @@ export void foo() {
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
-// Buf1 initialization part 1 - global init function that calls StructuredBuffer<float> C1 constructor
+// Buf1 initialization part 1 - global init function that calls StructuredBuffer<float>::__createFromBinding
// with explicit binding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl16StructuredBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf1,
+// CHECK-NEXT: call void @_ZN4hlsl16StructuredBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} @_ZL4Buf1,
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
-// Buf1 initialization part 2 - body of StructuredBuffer<float> C1 constructor with explicit binding
-// that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4)
-// CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// Buf1 initialization part 2 - body of StructuredBuffer<float>::::__createFromBinding
-// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer<float> C1 constructor with
-// implicit binding
+// CHECK: define {{.*}} void @_ZN4hlsl16StructuredBufferIfE19__createFromBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::StructuredBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle1:.*]] = call target("dx.RawBuffer", float, 0, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
+// CHECK: call void @_ZN4hlsl16StructuredBufferIfEC1EU13_Res_t_Raw_CTfu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.RawBuffer", float, 0, 0) %[[Handle1]])
+
+// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl18RWStructuredBufferIfEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]])
-
-// Buf2 initialization part 2 - body of RWStructuredBuffer<float> C1 constructor with implicit binding that calls the C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: call void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4)
-// CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}})
+// CHECK-NEXT: call void @_ZN4hlsl18RWStructuredBufferIfE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
+// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+
+// Buf2 initialization part 2 - body of RWStructuredBuffer<float>::__createFromImplicitBinding
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfE27__createFromImplicitBindingEjjijPKc(
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Handle2:.*]] = call target("dx.RawBuffer", float, 1, 0)
+// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t(
+// CHECK: call void @_ZN4hlsl18RWStructuredBufferIfEC1EU13_Res_u_Raw_CTfu17__hlsl_resource_t(
+// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.RawBuffer", float, 1, 0) %[[Handle2]])
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// AppendStructuredBuffer<float> C1 default constructor
@@ -66,23 +71,17 @@ export void foo() {
// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
// CHECK: call void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
-// Buf1 initialization part 3 - body of AppendStructuredBuffer<float> C2 constructor with explicit binding
-// that initializes handle with @llvm.dx.resource.handlefrombinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
-// CHECK-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 0, 0) %[[HANDLE]], ptr %__handle, align 4
-
-// Buf2 initialization part 3 - body of RWStructuredBuffer<float> C2 constructor with implicit binding that initializes
-// handle with @llvm.dx.resource.handlefromimplicitbinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
-// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
-// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t
-// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
-// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-NEXT: store target("dx.RawBuffer", float, 1, 0) %[[HANDLE]], ptr %__handle, align 4
+// Buf1 initialization part 3 - body of StructuredBuffer<float> constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC1EU13_Res_t_Raw_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.RawBuffer", float, 0, 0) %handle)
+// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
+
+// Buf2 initialization part 3 - body of RWStructuredBuffer<float> constructor with handle
+// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC2EU13_Res_u_Raw_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
+// CHECK-SAME: target("dx.RawBuffer", float, 1, 0) %handle)
+// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
// Buf3 initialization part 3 - body of AppendStructuredBuffer<float> default C2 constructor that
// initializes handle to poison
diff --git a/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl b/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
index 2a6e51d765bd1..8884e391ec917 100644
--- a/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
+++ b/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
@@ -12,32 +12,20 @@
// CHECK: @_ZL4T3S0 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
// CHECK: @_ZL5Array = internal global [10 x %"class.hlsl::RWBuffer.1"] poison, align 4
-// CHECK: %[[HANDLE:.*]] = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
+// CHECK: call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_1_0_0t(
-// CHECK-SAME: i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i1 false, ptr %{{.*}})
-// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this{{[0-9]*}}, i32 0, i32 0
-// CHECK: store target("dx.TypedBuffer", <4 x float>, 1, 0, 0) %[[HANDLE]], ptr %[[HANDLE_PTR]], align 4
RWBuffer<float4> U0S0 : register(u0);
-// CHECK: %[[HANDLE:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0)
+// CHECK: call target("dx.TypedBuffer", float, 1, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
-// CHECK-SAME: i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i1 false, ptr %{{.*}})
-// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %this{{[0-9]*}}, i32 0, i32 0
-// CHECK: store target("dx.TypedBuffer", float, 1, 0, 0) %[[HANDLE]], ptr %[[HANDLE_PTR]], align 4
RWBuffer<float> U5S3 : register(u5, space3);
-// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", i32, 0, 0)
+// CHECK: call target("dx.RawBuffer", i32, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(
-// CHECK-SAME: i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i1 false, ptr %{{.*}})
-// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %this{{[0-9]*}}, i32 0, i32 0
-// CHECK: store target("dx.RawBuffer", i32, 0, 0) %[[HANDLE]], ptr %[[HANDLE_PTR]], align 4
StructuredBuffer<int> T2S2 : register(t2, space2);
-// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", %struct.S, 1, 0)
+// CHECK: call target("dx.RawBuffer", %struct.S, 1, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_s_struct.Ss_1_0t(
-// CHECK-SAME: i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i1 false, ptr %{{.*}})
-// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %this{{[0-9]*}}, i32 0, i32 0
-// CHECK: store target("dx.RawBuffer", %struct.S, 1, 0) %[[HANDLE]], ptr %[[HANDLE_PTR]], align 4
struct S {
float4 f;
int i;
diff --git a/clang/test/CodeGenHLSL/static-local-ctor.hlsl b/clang/test/CodeGenHLSL/static-local-ctor.hlsl
index 9a4bf66f030ed..f44d70dff7811 100644
--- a/clang/test/CodeGenHLSL/static-local-ctor.hlsl
+++ b/clang/test/CodeGenHLSL/static-local-ctor.hlsl
@@ -22,7 +22,7 @@ void InitBuf(RWBuffer<int> buf) {
// CHECK-NEXT: br i1 [[Tmp3]]
// CHECK-NOT: _Init_thread_header
// CHECK: init.check:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiE27__createFromImplicitBindingEjjijPKc(
// CHECK-NEXT: store i8 1, ptr @_ZGVZ4mainvE5mybuf
// CHECK-NOT: _Init_thread_footer
diff --git a/out.ll b/out.ll
new file mode 100644
index 0000000000000..81469245d028e
--- /dev/null
+++ b/out.ll
@@ -0,0 +1,251 @@
+; ModuleID = 'C:\llvm-project\clang\test\CodeGenHLSL\debug\rwbuffer_debug_info.hlsl'
+source_filename = "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\rwbuffer_debug_info.hlsl"
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxilv1.6-pc-shadermodel6.6-compute"
+
+%"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
+
+ at _ZL3Out = internal global %"class.hlsl::RWBuffer" poison, align 4, !dbg !0
+ at .str = private unnamed_addr constant [4 x i8] c"Out\00", align 1
+
+; Function Attrs: alwaysinline convergent nounwind
+define internal void @__cxx_global_var_init() #0 !dbg !56 {
+entry:
+ call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr dead_on_unwind writable sret(%"class.hlsl::RWBuffer") align 4 @_ZL3Out, i32 noundef 7, i32 noundef 4, i32 noundef 1, i32 noundef 0, ptr noundef @.str) #5, !dbg !59
+ ret void, !dbg !59
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr dead_on_unwind noalias writable sret(%"class.hlsl::RWBuffer") align 4 %agg.result, i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) #1 align 2 !dbg !60 {
+entry:
+ %registerNo.addr = alloca i32, align 4
+ %spaceNo.addr = alloca i32, align 4
+ %range.addr = alloca i32, align 4
+ %index.addr = alloca i32, align 4
+ %name.addr = alloca ptr, align 4
+ %tmp = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
+ store i32 %registerNo, ptr %registerNo.addr, align 4
+ #dbg_declare(ptr %registerNo.addr, !62, !DIExpression(), !63)
+ store i32 %spaceNo, ptr %spaceNo.addr, align 4
+ #dbg_declare(ptr %spaceNo.addr, !64, !DIExpression(), !63)
+ store i32 %range, ptr %range.addr, align 4
+ #dbg_declare(ptr %range.addr, !65, !DIExpression(), !63)
+ store i32 %index, ptr %index.addr, align 4
+ #dbg_declare(ptr %index.addr, !66, !DIExpression(), !63)
+ store ptr %name, ptr %name.addr, align 4
+ #dbg_declare(ptr %name.addr, !67, !DIExpression(), !63)
+ #dbg_declare(ptr %tmp, !68, !DIExpression(), !63)
+ %0 = load i32, ptr %registerNo.addr, align 4, !dbg !69
+ %1 = load i32, ptr %spaceNo.addr, align 4, !dbg !69
+ %2 = load i32, ptr %range.addr, align 4, !dbg !69
+ %3 = load i32, ptr %index.addr, align 4, !dbg !69
+ %4 = load ptr, ptr %name.addr, align 4, !dbg !69
+ %5 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 %1, i32 %0, i32 %2, i32 %3, i1 false, ptr %4), !dbg !69
+ call void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %agg.result, target("dx.TypedBuffer", float, 1, 0, 0) %5) #5, !dbg !69
+ ret void, !dbg !70
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define internal void @_Z4maini(i32 noundef %GI) #1 !dbg !71 {
+entry:
+ %GI.addr = alloca i32, align 4
+ store i32 %GI, ptr %GI.addr, align 4
+ #dbg_declare(ptr %GI.addr, !74, !DIExpression(), !75)
+ %0 = load i32, ptr %GI.addr, align 4, !dbg !76
+ %call = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl8RWBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3Out, i32 noundef %0) #5, !dbg !77
+ store float 0.000000e+00, ptr %call, align 4, !dbg !78
+ ret void, !dbg !79
+}
+
+; Function Attrs: convergent noinline norecurse optnone
+define void @main() #2 {
+entry:
+ call void @_GLOBAL__sub_I_rwbuffer_debug_info.hlsl()
+ %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
+ call void @_Z4maini(i32 %0)
+ ret void
+}
+
+; Function Attrs: nounwind willreturn memory(none)
+declare i32 @llvm.dx.flattened.thread.id.in.group() #3
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define linkonce_odr hidden noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl8RWBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(4) %this, i32 noundef %Index) #1 align 2 !dbg !80 {
+entry:
+ %this.addr = alloca ptr, align 4
+ %Index.addr = alloca i32, align 4
+ store ptr %this, ptr %this.addr, align 4
+ #dbg_declare(ptr %this.addr, !81, !DIExpression(), !83)
+ store i32 %Index, ptr %Index.addr, align 4
+ #dbg_declare(ptr %Index.addr, !84, !DIExpression(), !85)
+ %this1 = load ptr, ptr %this.addr, align 4
+ %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0, !dbg !83
+ %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %__handle, align 4, !dbg !83
+ %1 = load i32, ptr %Index.addr, align 4, !dbg !83
+ %2 = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %0, i32 %1), !dbg !83
+ ret ptr %2, !dbg !86
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32, i32, i32, i32, i1, ptr) #4
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) unnamed_addr #1 align 2 !dbg !87 {
+entry:
+ %this.addr = alloca ptr, align 4
+ %handle.addr = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
+ store ptr %this, ptr %this.addr, align 4
+ #dbg_declare(ptr %this.addr, !88, !DIExpression(), !89)
+ store target("dx.TypedBuffer", float, 1, 0, 0) %handle, ptr %handle.addr, align 4
+ #dbg_declare(ptr %handle.addr, !90, !DIExpression(), !91)
+ %this1 = load ptr, ptr %this.addr, align 4
+ %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %handle.addr, align 4, !dbg !92
+ call void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this1, target("dx.TypedBuffer", float, 1, 0, 0) %0) #5, !dbg !92
+ ret void, !dbg !93
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) unnamed_addr #1 align 2 !dbg !95 {
+entry:
+ %this.addr = alloca ptr, align 4
+ %handle.addr = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
+ store ptr %this, ptr %this.addr, align 4
+ #dbg_declare(ptr %this.addr, !96, !DIExpression(), !97)
+ store target("dx.TypedBuffer", float, 1, 0, 0) %handle, ptr %handle.addr, align 4
+ #dbg_declare(ptr %handle.addr, !98, !DIExpression(), !99)
+ %this1 = load ptr, ptr %this.addr, align 4
+ %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %handle.addr, align 4, !dbg !100
+ %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0, !dbg !100
+ store target("dx.TypedBuffer", float, 1, 0, 0) %0, ptr %__handle, align 4, !dbg !100
+ ret void, !dbg !102
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #4
+
+; Function Attrs: alwaysinline convergent nounwind
+define internal void @_GLOBAL__sub_I_rwbuffer_debug_info.hlsl() #0 !dbg !104 {
+entry:
+ call void @__cxx_global_var_init(), !dbg !106
+ ret void
+}
+
+attributes #0 = { alwaysinline convergent nounwind "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { alwaysinline convergent mustprogress norecurse nounwind "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { convergent noinline norecurse optnone "approx-func-fp-math"="true" "hlsl.numthreads"="8,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #3 = { nounwind willreturn memory(none) }
+attributes #4 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #5 = { convergent }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!51, !52, !53}
+!dx.valver = !{!54}
+!llvm.ident = !{!55}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "Out", linkageName: "_ZL3Out", scope: !2, file: !5, line: 9, type: !6, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_11, file: !3, producer: "clang version 22.0.0git (C:/llvm-project/clang e5cfb97d26f63942eea3c9353680fa4e669b02e7)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\<stdin>", directory: "")
+!4 = !{!0}
+!5 = !DIFile(filename: "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\rwbuffer_debug_info.hlsl", directory: "")
+!6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWBuffer<float>", scope: !7, size: 32, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !8, templateParams: !49, identifier: "_ZTSN4hlsl8RWBufferIfEE")
+!7 = !DINamespace(name: "hlsl", scope: null)
+!8 = !{!9, !12, !16, !19, !27, !28, !31, !34, !42, !46}
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "__handle", scope: !6, file: !3, line: 9, baseType: !10, size: 32)
+!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 32)
+!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "__hlsl_resource_t", file: !3, flags: DIFlagFwdDecl)
+!12 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !13, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!13 = !DISubroutineType(types: !14)
+!14 = !{null, !15}
+!15 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !6, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
+!16 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !17, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!17 = !DISubroutineType(types: !18)
+!18 = !{null, !15, !10}
+!19 = !DISubprogram(name: "__createFromBinding", linkageName: "_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc", scope: !6, file: !3, type: !20, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: 0)
+!20 = !DISubroutineType(types: !21)
+!21 = !{!6, !22, !22, !23, !22, !24}
+!22 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
+!23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32)
+!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26)
+!26 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!27 = !DISubprogram(name: "__createFromImplicitBinding", linkageName: "_ZN4hlsl8RWBufferIfE27__createFromImplicitBindingEjjijPKc", scope: !6, file: !3, type: !20, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: 0)
+!28 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !29, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!29 = !DISubroutineType(types: !30)
+!30 = !{null, !15, !22, !22, !23, !22, !24}
+!31 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !32, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!32 = !DISubroutineType(types: !33)
+!33 = !{null, !15, !22, !23, !22, !22, !24}
+!34 = !DISubprogram(name: "operator[]", linkageName: "_ZNK4hlsl8RWBufferIfEixEj", scope: !6, file: !3, type: !35, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!35 = !DISubroutineType(types: !36)
+!36 = !{!37, !40, !22}
+!37 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !38, size: 32)
+!38 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !39)
+!39 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!40 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !41, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
+!41 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6)
+!42 = !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl8RWBufferIfEixEj", scope: !6, file: !3, type: !43, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!43 = !DISubroutineType(types: !44)
+!44 = !{!45, !15, !22}
+!45 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !39, size: 32)
+!46 = !DISubprogram(name: "Load", linkageName: "_ZN4hlsl8RWBufferIfE4LoadEj", scope: !6, file: !3, type: !47, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
+!47 = !DISubroutineType(types: !48)
+!48 = !{!39, !15, !22}
+!49 = !{!50}
+!50 = !DITemplateTypeParameter(name: "element_type", type: !39)
+!51 = !{i32 7, !"Dwarf Version", i32 4}
+!52 = !{i32 2, !"Debug Info Version", i32 3}
+!53 = !{i32 1, !"wchar_size", i32 4}
+!54 = !{i32 1, i32 8}
+!55 = !{!"clang version 22.0.0git (C:/llvm-project/clang e5cfb97d26f63942eea3c9353680fa4e669b02e7)"}
+!56 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, type: !57, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2)
+!57 = !DISubroutineType(types: !58)
+!58 = !{null}
+!59 = !DILocation(line: 0, scope: !56)
+!60 = distinct !DISubprogram(name: "__createFromBinding", linkageName: "_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc", scope: !6, file: !3, line: 14, type: !20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !19, retainedNodes: !61)
+!61 = !{}
+!62 = !DILocalVariable(name: "registerNo", arg: 1, scope: !60, file: !3, type: !22)
+!63 = !DILocation(line: 0, column: 1, scope: !60)
+!64 = !DILocalVariable(name: "spaceNo", arg: 2, scope: !60, file: !3, type: !22)
+!65 = !DILocalVariable(name: "range", arg: 3, scope: !60, file: !3, type: !23)
+!66 = !DILocalVariable(name: "index", arg: 4, scope: !60, file: !3, type: !22)
+!67 = !DILocalVariable(name: "name", arg: 5, scope: !60, file: !3, type: !24)
+!68 = !DILocalVariable(name: "tmp", scope: !60, file: !3, type: !10)
+!69 = !DILocation(line: 0, scope: !60)
+!70 = !DILocation(line: 14, column: 1, scope: !60)
+!71 = distinct !DISubprogram(name: "main", linkageName: "_Z4maini", scope: !5, file: !5, line: 12, type: !72, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !61)
+!72 = !DISubroutineType(types: !73)
+!73 = !{null, !23}
+!74 = !DILocalVariable(name: "GI", arg: 1, scope: !71, file: !5, line: 12, type: !23)
+!75 = !DILocation(line: 12, column: 15, scope: !71)
+!76 = !DILocation(line: 13, column: 7, scope: !71)
+!77 = !DILocation(line: 13, column: 3, scope: !71)
+!78 = !DILocation(line: 13, column: 11, scope: !71)
+!79 = !DILocation(line: 14, column: 1, scope: !71)
+!80 = distinct !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl8RWBufferIfEixEj", scope: !6, file: !3, line: 14, type: !43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !42, retainedNodes: !61)
+!81 = !DILocalVariable(name: "this", arg: 1, scope: !80, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
+!82 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !6, size: 32)
+!83 = !DILocation(line: 0, scope: !80)
+!84 = !DILocalVariable(name: "Index", arg: 2, scope: !80, file: !3, type: !22)
+!85 = !DILocation(line: 0, column: 1, scope: !80)
+!86 = !DILocation(line: 14, column: 1, scope: !80)
+!87 = distinct !DISubprogram(name: "RWBuffer", linkageName: "_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t", scope: !6, file: !3, line: 14, type: !17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !16, retainedNodes: !61)
+!88 = !DILocalVariable(name: "this", arg: 1, scope: !87, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
+!89 = !DILocation(line: 0, scope: !87)
+!90 = !DILocalVariable(name: "handle", arg: 2, scope: !87, file: !3, type: !10)
+!91 = !DILocation(line: 0, column: 1, scope: !87)
+!92 = !DILocation(line: 14, column: 1, scope: !87)
+!93 = !DILocation(line: 14, column: 1, scope: !94)
+!94 = !DILexicalBlockFile(scope: !87, file: !5, discriminator: 0)
+!95 = distinct !DISubprogram(name: "RWBuffer", linkageName: "_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t", scope: !6, file: !3, line: 14, type: !17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !16, retainedNodes: !61)
+!96 = !DILocalVariable(name: "this", arg: 1, scope: !95, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
+!97 = !DILocation(line: 0, scope: !95)
+!98 = !DILocalVariable(name: "handle", arg: 2, scope: !95, file: !3, type: !10)
+!99 = !DILocation(line: 0, column: 1, scope: !95)
+!100 = !DILocation(line: 0, scope: !101)
+!101 = distinct !DILexicalBlock(scope: !95, file: !5, line: 14, column: 1)
+!102 = !DILocation(line: 14, column: 1, scope: !103)
+!103 = !DILexicalBlockFile(scope: !95, file: !5, discriminator: 0)
+!104 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_rwbuffer_debug_info.hlsl", scope: !3, file: !3, type: !105, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2)
+!105 = !DISubroutineType(types: !61)
+!106 = !DILocation(line: 0, scope: !104)
>From b13a530c46348a6f8e2c2d770209ffa93ebb1125 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Tue, 2 Sep 2025 17:45:00 -0700
Subject: [PATCH 2/4] cleanup
---
out.ll | 251 ---------------------------------------------------------
1 file changed, 251 deletions(-)
delete mode 100644 out.ll
diff --git a/out.ll b/out.ll
deleted file mode 100644
index 81469245d028e..0000000000000
--- a/out.ll
+++ /dev/null
@@ -1,251 +0,0 @@
-; ModuleID = 'C:\llvm-project\clang\test\CodeGenHLSL\debug\rwbuffer_debug_info.hlsl'
-source_filename = "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\rwbuffer_debug_info.hlsl"
-target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
-target triple = "dxilv1.6-pc-shadermodel6.6-compute"
-
-%"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
-
- at _ZL3Out = internal global %"class.hlsl::RWBuffer" poison, align 4, !dbg !0
- at .str = private unnamed_addr constant [4 x i8] c"Out\00", align 1
-
-; Function Attrs: alwaysinline convergent nounwind
-define internal void @__cxx_global_var_init() #0 !dbg !56 {
-entry:
- call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr dead_on_unwind writable sret(%"class.hlsl::RWBuffer") align 4 @_ZL3Out, i32 noundef 7, i32 noundef 4, i32 noundef 1, i32 noundef 0, ptr noundef @.str) #5, !dbg !59
- ret void, !dbg !59
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr dead_on_unwind noalias writable sret(%"class.hlsl::RWBuffer") align 4 %agg.result, i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) #1 align 2 !dbg !60 {
-entry:
- %registerNo.addr = alloca i32, align 4
- %spaceNo.addr = alloca i32, align 4
- %range.addr = alloca i32, align 4
- %index.addr = alloca i32, align 4
- %name.addr = alloca ptr, align 4
- %tmp = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
- store i32 %registerNo, ptr %registerNo.addr, align 4
- #dbg_declare(ptr %registerNo.addr, !62, !DIExpression(), !63)
- store i32 %spaceNo, ptr %spaceNo.addr, align 4
- #dbg_declare(ptr %spaceNo.addr, !64, !DIExpression(), !63)
- store i32 %range, ptr %range.addr, align 4
- #dbg_declare(ptr %range.addr, !65, !DIExpression(), !63)
- store i32 %index, ptr %index.addr, align 4
- #dbg_declare(ptr %index.addr, !66, !DIExpression(), !63)
- store ptr %name, ptr %name.addr, align 4
- #dbg_declare(ptr %name.addr, !67, !DIExpression(), !63)
- #dbg_declare(ptr %tmp, !68, !DIExpression(), !63)
- %0 = load i32, ptr %registerNo.addr, align 4, !dbg !69
- %1 = load i32, ptr %spaceNo.addr, align 4, !dbg !69
- %2 = load i32, ptr %range.addr, align 4, !dbg !69
- %3 = load i32, ptr %index.addr, align 4, !dbg !69
- %4 = load ptr, ptr %name.addr, align 4, !dbg !69
- %5 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 %1, i32 %0, i32 %2, i32 %3, i1 false, ptr %4), !dbg !69
- call void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %agg.result, target("dx.TypedBuffer", float, 1, 0, 0) %5) #5, !dbg !69
- ret void, !dbg !70
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define internal void @_Z4maini(i32 noundef %GI) #1 !dbg !71 {
-entry:
- %GI.addr = alloca i32, align 4
- store i32 %GI, ptr %GI.addr, align 4
- #dbg_declare(ptr %GI.addr, !74, !DIExpression(), !75)
- %0 = load i32, ptr %GI.addr, align 4, !dbg !76
- %call = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl8RWBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3Out, i32 noundef %0) #5, !dbg !77
- store float 0.000000e+00, ptr %call, align 4, !dbg !78
- ret void, !dbg !79
-}
-
-; Function Attrs: convergent noinline norecurse optnone
-define void @main() #2 {
-entry:
- call void @_GLOBAL__sub_I_rwbuffer_debug_info.hlsl()
- %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
- call void @_Z4maini(i32 %0)
- ret void
-}
-
-; Function Attrs: nounwind willreturn memory(none)
-declare i32 @llvm.dx.flattened.thread.id.in.group() #3
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define linkonce_odr hidden noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl8RWBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(4) %this, i32 noundef %Index) #1 align 2 !dbg !80 {
-entry:
- %this.addr = alloca ptr, align 4
- %Index.addr = alloca i32, align 4
- store ptr %this, ptr %this.addr, align 4
- #dbg_declare(ptr %this.addr, !81, !DIExpression(), !83)
- store i32 %Index, ptr %Index.addr, align 4
- #dbg_declare(ptr %Index.addr, !84, !DIExpression(), !85)
- %this1 = load ptr, ptr %this.addr, align 4
- %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0, !dbg !83
- %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %__handle, align 4, !dbg !83
- %1 = load i32, ptr %Index.addr, align 4, !dbg !83
- %2 = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0) %0, i32 %1), !dbg !83
- ret ptr %2, !dbg !86
-}
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32, i32, i32, i32, i1, ptr) #4
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) unnamed_addr #1 align 2 !dbg !87 {
-entry:
- %this.addr = alloca ptr, align 4
- %handle.addr = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
- store ptr %this, ptr %this.addr, align 4
- #dbg_declare(ptr %this.addr, !88, !DIExpression(), !89)
- store target("dx.TypedBuffer", float, 1, 0, 0) %handle, ptr %handle.addr, align 4
- #dbg_declare(ptr %handle.addr, !90, !DIExpression(), !91)
- %this1 = load ptr, ptr %this.addr, align 4
- %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %handle.addr, align 4, !dbg !92
- call void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this1, target("dx.TypedBuffer", float, 1, 0, 0) %0) #5, !dbg !92
- ret void, !dbg !93
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr noundef nonnull align 4 dereferenceable(4) %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) unnamed_addr #1 align 2 !dbg !95 {
-entry:
- %this.addr = alloca ptr, align 4
- %handle.addr = alloca target("dx.TypedBuffer", float, 1, 0, 0), align 4
- store ptr %this, ptr %this.addr, align 4
- #dbg_declare(ptr %this.addr, !96, !DIExpression(), !97)
- store target("dx.TypedBuffer", float, 1, 0, 0) %handle, ptr %handle.addr, align 4
- #dbg_declare(ptr %handle.addr, !98, !DIExpression(), !99)
- %this1 = load ptr, ptr %this.addr, align 4
- %0 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr %handle.addr, align 4, !dbg !100
- %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %this1, i32 0, i32 0, !dbg !100
- store target("dx.TypedBuffer", float, 1, 0, 0) %0, ptr %__handle, align 4, !dbg !100
- ret void, !dbg !102
-}
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t(target("dx.TypedBuffer", float, 1, 0, 0), i32) #4
-
-; Function Attrs: alwaysinline convergent nounwind
-define internal void @_GLOBAL__sub_I_rwbuffer_debug_info.hlsl() #0 !dbg !104 {
-entry:
- call void @__cxx_global_var_init(), !dbg !106
- ret void
-}
-
-attributes #0 = { alwaysinline convergent nounwind "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { alwaysinline convergent mustprogress norecurse nounwind "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #2 = { convergent noinline norecurse optnone "approx-func-fp-math"="true" "hlsl.numthreads"="8,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #3 = { nounwind willreturn memory(none) }
-attributes #4 = { nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #5 = { convergent }
-
-!llvm.dbg.cu = !{!2}
-!llvm.module.flags = !{!51, !52, !53}
-!dx.valver = !{!54}
-!llvm.ident = !{!55}
-
-!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
-!1 = distinct !DIGlobalVariable(name: "Out", linkageName: "_ZL3Out", scope: !2, file: !5, line: 9, type: !6, isLocal: true, isDefinition: true)
-!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_11, file: !3, producer: "clang version 22.0.0git (C:/llvm-project/clang e5cfb97d26f63942eea3c9353680fa4e669b02e7)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
-!3 = !DIFile(filename: "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\<stdin>", directory: "")
-!4 = !{!0}
-!5 = !DIFile(filename: "C:\\llvm-project\\clang\\test\\CodeGenHLSL\\debug\\rwbuffer_debug_info.hlsl", directory: "")
-!6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWBuffer<float>", scope: !7, size: 32, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !8, templateParams: !49, identifier: "_ZTSN4hlsl8RWBufferIfEE")
-!7 = !DINamespace(name: "hlsl", scope: null)
-!8 = !{!9, !12, !16, !19, !27, !28, !31, !34, !42, !46}
-!9 = !DIDerivedType(tag: DW_TAG_member, name: "__handle", scope: !6, file: !3, line: 9, baseType: !10, size: 32)
-!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 32)
-!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "__hlsl_resource_t", file: !3, flags: DIFlagFwdDecl)
-!12 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !13, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!13 = !DISubroutineType(types: !14)
-!14 = !{null, !15}
-!15 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !6, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
-!16 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !17, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!17 = !DISubroutineType(types: !18)
-!18 = !{null, !15, !10}
-!19 = !DISubprogram(name: "__createFromBinding", linkageName: "_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc", scope: !6, file: !3, type: !20, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: 0)
-!20 = !DISubroutineType(types: !21)
-!21 = !{!6, !22, !22, !23, !22, !24}
-!22 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
-!23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32)
-!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26)
-!26 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
-!27 = !DISubprogram(name: "__createFromImplicitBinding", linkageName: "_ZN4hlsl8RWBufferIfE27__createFromImplicitBindingEjjijPKc", scope: !6, file: !3, type: !20, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: 0)
-!28 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !29, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!29 = !DISubroutineType(types: !30)
-!30 = !{null, !15, !22, !22, !23, !22, !24}
-!31 = !DISubprogram(name: "RWBuffer", scope: !6, file: !3, type: !32, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!32 = !DISubroutineType(types: !33)
-!33 = !{null, !15, !22, !23, !22, !22, !24}
-!34 = !DISubprogram(name: "operator[]", linkageName: "_ZNK4hlsl8RWBufferIfEixEj", scope: !6, file: !3, type: !35, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!35 = !DISubroutineType(types: !36)
-!36 = !{!37, !40, !22}
-!37 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !38, size: 32)
-!38 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !39)
-!39 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!40 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !41, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
-!41 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6)
-!42 = !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl8RWBufferIfEixEj", scope: !6, file: !3, type: !43, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!43 = !DISubroutineType(types: !44)
-!44 = !{!45, !15, !22}
-!45 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !39, size: 32)
-!46 = !DISubprogram(name: "Load", linkageName: "_ZN4hlsl8RWBufferIfE4LoadEj", scope: !6, file: !3, type: !47, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!47 = !DISubroutineType(types: !48)
-!48 = !{!39, !15, !22}
-!49 = !{!50}
-!50 = !DITemplateTypeParameter(name: "element_type", type: !39)
-!51 = !{i32 7, !"Dwarf Version", i32 4}
-!52 = !{i32 2, !"Debug Info Version", i32 3}
-!53 = !{i32 1, !"wchar_size", i32 4}
-!54 = !{i32 1, i32 8}
-!55 = !{!"clang version 22.0.0git (C:/llvm-project/clang e5cfb97d26f63942eea3c9353680fa4e669b02e7)"}
-!56 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, type: !57, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2)
-!57 = !DISubroutineType(types: !58)
-!58 = !{null}
-!59 = !DILocation(line: 0, scope: !56)
-!60 = distinct !DISubprogram(name: "__createFromBinding", linkageName: "_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc", scope: !6, file: !3, line: 14, type: !20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !19, retainedNodes: !61)
-!61 = !{}
-!62 = !DILocalVariable(name: "registerNo", arg: 1, scope: !60, file: !3, type: !22)
-!63 = !DILocation(line: 0, column: 1, scope: !60)
-!64 = !DILocalVariable(name: "spaceNo", arg: 2, scope: !60, file: !3, type: !22)
-!65 = !DILocalVariable(name: "range", arg: 3, scope: !60, file: !3, type: !23)
-!66 = !DILocalVariable(name: "index", arg: 4, scope: !60, file: !3, type: !22)
-!67 = !DILocalVariable(name: "name", arg: 5, scope: !60, file: !3, type: !24)
-!68 = !DILocalVariable(name: "tmp", scope: !60, file: !3, type: !10)
-!69 = !DILocation(line: 0, scope: !60)
-!70 = !DILocation(line: 14, column: 1, scope: !60)
-!71 = distinct !DISubprogram(name: "main", linkageName: "_Z4maini", scope: !5, file: !5, line: 12, type: !72, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !61)
-!72 = !DISubroutineType(types: !73)
-!73 = !{null, !23}
-!74 = !DILocalVariable(name: "GI", arg: 1, scope: !71, file: !5, line: 12, type: !23)
-!75 = !DILocation(line: 12, column: 15, scope: !71)
-!76 = !DILocation(line: 13, column: 7, scope: !71)
-!77 = !DILocation(line: 13, column: 3, scope: !71)
-!78 = !DILocation(line: 13, column: 11, scope: !71)
-!79 = !DILocation(line: 14, column: 1, scope: !71)
-!80 = distinct !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl8RWBufferIfEixEj", scope: !6, file: !3, line: 14, type: !43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !42, retainedNodes: !61)
-!81 = !DILocalVariable(name: "this", arg: 1, scope: !80, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
-!82 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !6, size: 32)
-!83 = !DILocation(line: 0, scope: !80)
-!84 = !DILocalVariable(name: "Index", arg: 2, scope: !80, file: !3, type: !22)
-!85 = !DILocation(line: 0, column: 1, scope: !80)
-!86 = !DILocation(line: 14, column: 1, scope: !80)
-!87 = distinct !DISubprogram(name: "RWBuffer", linkageName: "_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t", scope: !6, file: !3, line: 14, type: !17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !16, retainedNodes: !61)
-!88 = !DILocalVariable(name: "this", arg: 1, scope: !87, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
-!89 = !DILocation(line: 0, scope: !87)
-!90 = !DILocalVariable(name: "handle", arg: 2, scope: !87, file: !3, type: !10)
-!91 = !DILocation(line: 0, column: 1, scope: !87)
-!92 = !DILocation(line: 14, column: 1, scope: !87)
-!93 = !DILocation(line: 14, column: 1, scope: !94)
-!94 = !DILexicalBlockFile(scope: !87, file: !5, discriminator: 0)
-!95 = distinct !DISubprogram(name: "RWBuffer", linkageName: "_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t", scope: !6, file: !3, line: 14, type: !17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, declaration: !16, retainedNodes: !61)
-!96 = !DILocalVariable(name: "this", arg: 1, scope: !95, type: !82, flags: DIFlagArtificial | DIFlagObjectPointer)
-!97 = !DILocation(line: 0, scope: !95)
-!98 = !DILocalVariable(name: "handle", arg: 2, scope: !95, file: !3, type: !10)
-!99 = !DILocation(line: 0, column: 1, scope: !95)
-!100 = !DILocation(line: 0, scope: !101)
-!101 = distinct !DILexicalBlock(scope: !95, file: !5, line: 14, column: 1)
-!102 = !DILocation(line: 14, column: 1, scope: !103)
-!103 = !DILexicalBlockFile(scope: !95, file: !5, discriminator: 0)
-!104 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_rwbuffer_debug_info.hlsl", scope: !3, file: !3, type: !105, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2)
-!105 = !DISubroutineType(types: !61)
-!106 = !DILocation(line: 0, scope: !104)
>From e7d6ee69558321a636358a10d9e0fb792ccecdc0 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 3 Sep 2025 20:46:43 -0700
Subject: [PATCH 3/4] Update tests after create methods body change
---
.../CodeGenHLSL/GlobalConstructorLib.hlsl | 5 ++-
.../ByteAddressBuffers-constructors.hlsl | 28 +++++-------
.../resources/RWBuffer-constructor.hlsl | 28 +++++-------
.../StructuredBuffers-constructors.hlsl | 44 ++++++++-----------
4 files changed, 41 insertions(+), 64 deletions(-)
diff --git a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
index c3d4fbb12a6f4..fa703b0a0a1d2 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
@@ -33,9 +33,10 @@ void SecondEntry() {}
// Verify the constructors are alwaysinline
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
-// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) {{.*}} [[CtorAttr:\#[0-9]+]]
+// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
+
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
-// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this, target("dx.TypedBuffer", float, 1, 0, 0) %handle) {{.*}} [[CtorAttr]]
+// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
// NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]]
diff --git a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
index 35e1c14a0931f..193ce1dd1251b 100644
--- a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
@@ -36,12 +36,14 @@ export void foo() {
// Buf1 initialization part 2 - body of ByteAddressBuffer::__createFromBinding
// CHECK: define {{.*}} void @_ZN4hlsl17ByteAddressBuffer19__createFromBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::ByteAddressBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::ByteAddressBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::ByteAddressBuffer", align 4
// CHECK: %[[Handle1:.*]] = call target("dx.RawBuffer", i8, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
-// CHECK: call void @_ZN4hlsl17ByteAddressBufferC1EU13_Res_t_Raw_CTDuu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.RawBuffer", i8, 0, 0) %[[Handle1]])
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %[[Tmp1]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.RawBuffer", i8, 0, 0) %[[Handle1]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -51,12 +53,14 @@ export void foo() {
// Buf2 initialization part 2 - body of RWByteAddressBuffer::__createFromImplicitBinding
// CHECK: define hidden void @_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWByteAddressBuffer") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWByteAddressBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWByteAddressBuffer", align 4
// CHECK: %[[Handle2:.*]] = call target("dx.RawBuffer", i8, 1, 0)
// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(
-// CHECK: call void @_ZN4hlsl19RWByteAddressBufferC1EU13_Res_u_Raw_CTDuu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.RawBuffer", i8, 1, 0) %[[Handle2]])
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %[[Tmp2]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.RawBuffer", i8, 1, 0) %[[Handle2]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// RasterizerOrderedByteAddressBuffer C1 default constructor
@@ -71,18 +75,6 @@ export void foo() {
// CHECK: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
// CHECK-NEXT: ret void
-// Buf1 initialization part 3 - ByteAddressBuffer constructor constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC2EU13_Res_t_Raw_CTDuu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.RawBuffer", i8, 0, 0) %handle)
-// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
-
-// Buf2 initialization part 3 - body of RWByteAddressBuffer constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC1EU13_Res_u_Raw_CTDuu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.RawBuffer", i8, 1, 0) %handle)
-// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
-
// Buf3 initialization part 3 - body of RasterizerOrderedByteAddressBuffer default C2 constructor that
// initializes handle to poison
// CHECK: define linkonce_odr hidden void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
diff --git a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
index c5c40449c6c8e..75db79d5a196d 100644
--- a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
+++ b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
@@ -36,12 +36,14 @@ export void foo() {
// Buf1 initialization part 2 - body of RWBuffer<float>::__createFromBinding
// CHECK: define {{.*}} void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::RWBuffer", align 4
// CHECK: %[[Handle1:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
-// CHECK: call void @_ZN4hlsl8RWBufferIfEC1EU9_Res_u_CTfu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.TypedBuffer", float, 1, 0, 0) %[[Handle1]])
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %[[Tmp1]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.TypedBuffer", float, 1, 0, 0) %[[Handle1]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
// Buf2 initialization part 1 - global init function that RWBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -51,12 +53,14 @@ export void foo() {
// Buf2 initialization part 2 - body of RWBuffer<float>::__createFromImplicitBinding call
// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
+// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer.0", align 4
// CHECK: %[[Handle2:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t(
-// CHECK: call void @_ZN4hlsl8RWBufferIdEC1EU9_Res_u_CTdu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.TypedBuffer", double, 1, 0, 0) %[[Handle2]])
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %[[Tmp2]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.TypedBuffer", double, 1, 0, 0) %[[Handle2]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by RWBuffer<int> C1 default constructor
// CHECK: define void @_Z3foov()
@@ -68,18 +72,6 @@ export void foo() {
// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC1Ev(ptr {{.*}} %this)
// CHECK: call void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %{{.*}})
-// Buf1 initialization part 3 - body of RWBuffer<float> constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EU9_Res_u_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.TypedBuffer", float, 1, 0, 0) %handle)
-// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
-
-// Buf2 initialization part 3 - body of RWBuffer<double> constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC1EU9_Res_u_CTdu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) %handle)
-// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", double, 1, 0, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
-
// Buf3 initialization part 3 - body of RWBuffer<int> default C2 constructor that initializes handle to poison
// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.1", ptr %{{.*}}, i32 0, i32 0
diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
index 834a9639484a5..1939f28a1f2ff 100644
--- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
@@ -18,9 +18,9 @@ export void foo() {
AppendStructuredBuffer<float> Buf3;
}
-// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) }
-// CHECK: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
-// CHECK: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
+// CHECK-DXIL: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) }
+// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
+// CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
// CHECK: @_ZL4Buf1 = internal global %"class.hlsl::StructuredBuffer" poison, align 4
// CHECK: @[[Buf1Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf1\00", align 1
@@ -37,12 +37,14 @@ export void foo() {
// Buf1 initialization part 2 - body of StructuredBuffer<float>::::__createFromBinding
// CHECK: define {{.*}} void @_ZN4hlsl16StructuredBufferIfE19__createFromBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::StructuredBuffer") align 4 %[[Tmp1:.*]], i32 noundef %registerNo,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::StructuredBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK: %[[Handle1:.*]] = call target("dx.RawBuffer", float, 0, 0)
-// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
-// CHECK: call void @_ZN4hlsl16StructuredBufferIfEC1EU13_Res_t_Raw_CTfu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp1]], target("dx.RawBuffer", float, 0, 0) %[[Handle1]])
+// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::StructuredBuffer", align 4
+// CHECK-DXIL: %[[Handle1:.*]] = call target("dx.RawBuffer", float, 0, 0)
+// CHECK-DXIL-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %[[Tmp1]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) %[[Handle1]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -52,12 +54,14 @@ export void foo() {
// Buf2 initialization part 2 - body of RWStructuredBuffer<float>::__createFromImplicitBinding
// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfE27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[Tmp2:.*]], i32 noundef %orderId,
+// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
-// CHECK: %[[Handle2:.*]] = call target("dx.RawBuffer", float, 1, 0)
-// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t(
-// CHECK: call void @_ZN4hlsl18RWStructuredBufferIfEC1EU13_Res_u_Raw_CTfu17__hlsl_resource_t(
-// CHECK-SAME: ptr {{.*}} %[[Tmp2]], target("dx.RawBuffer", float, 1, 0) %[[Handle2]])
+// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWStructuredBuffer", align 4
+// CHECK-DXIL: %[[Handle2:.*]] = call target("dx.RawBuffer", float, 1, 0)
+// CHECK-DXIL-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t(
+// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0
+// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) %[[Handle2]], ptr %__handle, align 4
+// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// AppendStructuredBuffer<float> C1 default constructor
@@ -71,23 +75,11 @@ export void foo() {
// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
// CHECK: call void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
-// Buf1 initialization part 3 - body of StructuredBuffer<float> constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC1EU13_Res_t_Raw_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.RawBuffer", float, 0, 0) %handle)
-// CHECK: %[[HandlePtr1:.*]] = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 0, 0) %{{.*}}, ptr %[[HandlePtr1]], align 4
-
-// Buf2 initialization part 3 - body of RWStructuredBuffer<float> constructor with handle
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC2EU13_Res_u_Raw_CTfu17__hlsl_resource_t(ptr {{.*}} %this,
-// CHECK-SAME: target("dx.RawBuffer", float, 1, 0) %handle)
-// CHECK: %[[HandlePtr2:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %{{.*}}, ptr %[[HandlePtr2]], align 4
-
// Buf3 initialization part 3 - body of AppendStructuredBuffer<float> default C2 constructor that
// initializes handle to poison
// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::AppendStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
-// CHECK: store target("dx.RawBuffer", float, 1, 0) poison, ptr %__handle, align 4
+// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) poison, ptr %__handle, align 4
// Module initialization
// CHECK: define internal void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
>From 7782eeab76ef6b205ea70c4f7e8072dc5c60cc02 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 4 Sep 2025 15:45:07 -0700
Subject: [PATCH 4/4] Update tests to use llvm-cxxfilt to have unmangled names
in the baselines
---
clang/lib/Sema/SemaHLSL.cpp | 2 +-
.../CodeGenHLSL/GlobalConstructorLib.hlsl | 12 +++----
.../ByteAddressBuffers-constructors.hlsl | 36 ++++++++++---------
.../resources/RWBuffer-constructor.hlsl | 36 ++++++++++---------
.../StructuredBuffers-constructors.hlsl | 34 +++++++++---------
.../resources/resource-bindings.hlsl | 3 +-
clang/test/CodeGenHLSL/static-local-ctor.hlsl | 11 +++---
7 files changed, 71 insertions(+), 63 deletions(-)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 63ca46583a59b..775098d06b18c 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3767,7 +3767,7 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
SpaceNo = RBA->getSpaceNumber();
}
- // Find correct initialization method and create its argumentss.
+ // Find correct initialization method and create its arguments.
QualType ResourceTy = VD->getType();
CXXRecordDecl *ResourceDecl = ResourceTy->getAsCXXRecordDecl();
CXXMethodDecl *CreateMethod = nullptr;
diff --git a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
index fa703b0a0a1d2..3cb7827e26884 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
@@ -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
@@ -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
@@ -25,7 +25,7 @@ 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
@@ -33,10 +33,10 @@ void SecondEntry() {}
// Verify the constructors are alwaysinline
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
-// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
+// 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 @_ZN4hlsl8RWBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
+// 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 internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]]
diff --git a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
index 193ce1dd1251b..71ff3bf16afcc 100644
--- a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | \
+// RUN: llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// FIXME: SPIR-V codegen of llvm.spv.resource.handlefrombinding and resource types is not yet implemented
-// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | \
+// llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
// NOTE: Itanium ABI for C++ requires Clang to generate 2 constructors types to support polymorphism:
// - C1 - Complete object constructor - constructs the complete object, including virtual base classes.
@@ -23,20 +25,20 @@ export void foo() {
// CHECK: %"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
// CHECK: %"class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
-// CHECK: @_ZL4Buf1 = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4
+// CHECK: @Buf1 = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4
// CHECK: @[[Buf1Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf1\00", align 1
-// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+// CHECK: @Buf2 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
// Buf1 initialization part 1 - global init function that calls ByteAddressBuffer::__createFromBinding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl17ByteAddressBuffer19__createFromBindingEjjijPKc(ptr {{.*}} @_ZL4Buf1,
-// CHECK-SAME: i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
+// CHECK-NEXT: call void @hlsl::ByteAddressBuffer::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} @Buf1, i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
// Buf1 initialization part 2 - body of ByteAddressBuffer::__createFromBinding
-// CHECK: define {{.*}} void @_ZN4hlsl17ByteAddressBuffer19__createFromBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::ByteAddressBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
+// CHECK: define {{.*}} void @hlsl::ByteAddressBuffer::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::ByteAddressBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::ByteAddressBuffer", align 4
// CHECK: %[[Handle1:.*]] = call target("dx.RawBuffer", i8, 0, 0)
@@ -48,12 +50,12 @@ export void foo() {
// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+// CHECK-NEXT: call void @hlsl::RWByteAddressBuffer::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} @Buf2, i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
// Buf2 initialization part 2 - body of RWByteAddressBuffer::__createFromImplicitBinding
-// CHECK: define hidden void @_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWByteAddressBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
+// CHECK: define hidden void @hlsl::RWByteAddressBuffer::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWByteAddressBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWByteAddressBuffer", align 4
// CHECK: %[[Handle2:.*]] = call target("dx.RawBuffer", i8, 1, 0)
@@ -64,20 +66,20 @@ export void foo() {
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// RasterizerOrderedByteAddressBuffer C1 default constructor
-// CHECK: define void @_Z3foov()
+// CHECK: define void @foo()
// CHECK-NEXT: entry:
// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::RasterizerOrderedByteAddressBuffer", align 4
-// CHECK-NEXT: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3)
+// CHECK-NEXT: call void @hlsl::RasterizerOrderedByteAddressBuffer::RasterizerOrderedByteAddressBuffer()(ptr {{.*}} %Buf3)
// Buf3 initialization part 2 - body of RasterizerOrderedByteAddressBuffer default C1 constructor that
// calls the default C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
-// CHECK: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
+// CHECK: define linkonce_odr hidden void @hlsl::RasterizerOrderedByteAddressBuffer::RasterizerOrderedByteAddressBuffer()(ptr {{.*}} %this)
+// CHECK: call void @hlsl::RasterizerOrderedByteAddressBuffer::RasterizerOrderedByteAddressBuffer()(ptr {{.*}} %this1)
// CHECK-NEXT: ret void
// Buf3 initialization part 3 - body of RasterizerOrderedByteAddressBuffer default C2 constructor that
// initializes handle to poison
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
+// CHECK: define linkonce_odr hidden void @hlsl::RasterizerOrderedByteAddressBuffer::RasterizerOrderedByteAddressBuffer()(ptr {{.*}} %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// CHECK: store target("dx.RawBuffer", i8, 1, 1) poison, ptr %__handle, align 4
diff --git a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
index 75db79d5a196d..47ba8bec2bfce 100644
--- a/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
+++ b/clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | \
+// RUN: llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// FIXME: SPIR-V codegen of llvm.spv.resource.handlefrombinding and resource types is not yet implemented
-// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | \
+// llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
// NOTE: Itanium ABI for C++ requires Clang to generate 2 constructors types to support polymorphism:
// - C1 - Complete object constructor - constructs the complete object, including virtual base classes.
@@ -23,20 +25,20 @@ export void foo() {
// CHECK: %"class.hlsl::RWBuffer.0" = type { target("dx.TypedBuffer", double, 1, 0, 0) }
// CHECK: %"class.hlsl::RWBuffer.1" = type { target("dx.TypedBuffer", i32, 1, 0, 1) }
-// CHECK: @_ZL4Buf1 = internal global %"class.hlsl::RWBuffer" poison, align 4
+// CHECK: @Buf1 = internal global %"class.hlsl::RWBuffer" poison, align 4
// CHECK: @[[Buf1Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf1\00", align 1
-// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWBuffer.0" poison, align 4
+// CHECK: @Buf2 = internal global %"class.hlsl::RWBuffer.0" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
// Buf1 initialization part 1 - global init function that calls RWBuffer<float>::__createFromBinding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 @_ZL4Buf1,
-// CHECK-SAME: i32 noundef 5, i32 noundef 3, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
+// CHECK-NEXT: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 @Buf1, i32 noundef 5, i32 noundef 3, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
// Buf1 initialization part 2 - body of RWBuffer<float>::__createFromBinding
-// CHECK: define {{.*}} void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
+// CHECK: define {{.*}} void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::RWBuffer", align 4
// CHECK: %[[Handle1:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0)
@@ -48,12 +50,12 @@ export void foo() {
// Buf2 initialization part 1 - global init function that RWBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+// CHECK-NEXT: call void @hlsl::RWBuffer<double>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} @Buf2, i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
// Buf2 initialization part 2 - body of RWBuffer<float>::__createFromImplicitBinding call
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
+// CHECK: define linkonce_odr hidden void @hlsl::RWBuffer<double>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer.0", align 4
// CHECK: %[[Handle2:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
@@ -63,17 +65,17 @@ export void foo() {
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by RWBuffer<int> C1 default constructor
-// CHECK: define void @_Z3foov()
+// CHECK: define void @foo()
// CHECK-NEXT: entry:
// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::RWBuffer.1", align 4
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1Ev(ptr {{.*}} %Buf3)
+// CHECK-NEXT: call void @hlsl::RWBuffer<int>::RWBuffer()(ptr {{.*}} %Buf3)
// Buf3 initialization part 2 - body of RWBuffer<int> default C1 constructor that calls the default C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC1Ev(ptr {{.*}} %this)
-// CHECK: call void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %{{.*}})
+// CHECK: define linkonce_odr hidden void @hlsl::RWBuffer<int>::RWBuffer()(ptr {{.*}} %this)
+// CHECK: call void @hlsl::RWBuffer<int>::RWBuffer()(ptr {{.*}} %{{.*}})
// Buf3 initialization part 3 - body of RWBuffer<int> default C2 constructor that initializes handle to poison
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC2Ev(ptr {{.*}} %this)
+// CHECK: define linkonce_odr hidden void @hlsl::RWBuffer<int>::RWBuffer()(ptr {{.*}} %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.1", ptr %{{.*}}, i32 0, i32 0
// CHECK-NEXT: store target("dx.TypedBuffer", i32, 1, 0, 1) poison, ptr %__handle, align 4
diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
index 1939f28a1f2ff..d342c8ab456e2 100644
--- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
+++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | \
+// RUN: llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// FIXME: SPIR-V codegen of llvm.spv.resource.handlefrombinding and resource types is not yet implemented
-// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | \
+// llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
// NOTE: Itanium ABI for C++ requires Clang to generate 2 constructors types to support polymorphism:
// - C1 - Complete object constructor - constructs the complete object, including virtual base classes.
@@ -22,21 +24,21 @@ export void foo() {
// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
// CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
-// CHECK: @_ZL4Buf1 = internal global %"class.hlsl::StructuredBuffer" poison, align 4
+// CHECK: @Buf1 = internal global %"class.hlsl::StructuredBuffer" poison, align 4
// CHECK: @[[Buf1Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf1\00", align 1
-// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
+// CHECK: @Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
// CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1
// Buf1 initialization part 1 - global init function that calls StructuredBuffer<float>::__createFromBinding
// with explicit binding
// CHECK: define internal void @__cxx_global_var_init()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl16StructuredBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} @_ZL4Buf1,
-// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
+// CHECK-NEXT: call void @hlsl::StructuredBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} @Buf1, i32 noundef 10, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]])
// Buf1 initialization part 2 - body of StructuredBuffer<float>::::__createFromBinding
-// CHECK: define {{.*}} void @_ZN4hlsl16StructuredBufferIfE19__createFromBindingEjjijPKc(
+// CHECK: define {{.*}} void @hlsl::StructuredBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::StructuredBuffer") align 4 %[[RetValue1:.*]], i32 noundef %registerNo,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::StructuredBuffer", align 4
@@ -49,12 +51,12 @@ export void foo() {
// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer<float>::__createFromImplicitBinding
// CHECK: define internal void @__cxx_global_var_init.1()
// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @_ZN4hlsl18RWStructuredBufferIfE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} @_ZL4Buf2,
-// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
+// CHECK-NEXT: call void @hlsl::RWStructuredBuffer<float>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} @Buf2, i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]])
// Buf2 initialization part 2 - body of RWStructuredBuffer<float>::__createFromImplicitBinding
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfE27__createFromImplicitBindingEjjijPKc(
-// CHECK-SAME: ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
+// CHECK: define linkonce_odr hidden void @hlsl::RWStructuredBuffer<float>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[RetValue2:.*]], i32 noundef %orderId,
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWStructuredBuffer", align 4
// CHECK-DXIL: %[[Handle2:.*]] = call target("dx.RawBuffer", float, 1, 0)
@@ -65,19 +67,19 @@ export void foo() {
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
// AppendStructuredBuffer<float> C1 default constructor
-// CHECK: define void @_Z3foov()
+// CHECK: define void @foo()
// CHECK-NEXT: entry:
// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::AppendStructuredBuffer", align 4
-// CHECK-NEXT: call void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3)
+// CHECK-NEXT: call void @hlsl::AppendStructuredBuffer<float>::AppendStructuredBuffer()(ptr {{.*}} %Buf3)
// Buf3 initialization part 2 - body of AppendStructuredBuffer<float> default C1 constructor that calls
// the default C2 constructor
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
-// CHECK: call void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}})
+// CHECK: define linkonce_odr hidden void @hlsl::StructuredBuffer<float>::StructuredBuffer()(ptr {{.*}} %this)
+// CHECK: call void @hlsl::StructuredBuffer<float>::StructuredBuffer()(ptr {{.*}} %this1)
// Buf3 initialization part 3 - body of AppendStructuredBuffer<float> default C2 constructor that
// initializes handle to poison
-// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
+// CHECK: define linkonce_odr hidden void @hlsl::StructuredBuffer<float>::StructuredBuffer()(ptr {{.*}} %this)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::AppendStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) poison, ptr %__handle, align 4
diff --git a/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl b/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
index 8884e391ec917..4ffa7cfc84e17 100644
--- a/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
+++ b/clang/test/CodeGenHLSL/resources/resource-bindings.hlsl
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple dxil--shadermodel6.6-compute -x hlsl -finclude-default-header -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil--shadermodel6.6-compute -x hlsl -finclude-default-header \
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0) }
// CHECK: %"class.hlsl::RWBuffer.0" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
diff --git a/clang/test/CodeGenHLSL/static-local-ctor.hlsl b/clang/test/CodeGenHLSL/static-local-ctor.hlsl
index f44d70dff7811..bb575d23216b0 100644
--- a/clang/test/CodeGenHLSL/static-local-ctor.hlsl
+++ b/clang/test/CodeGenHLSL/static-local-ctor.hlsl
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -o - -disable-llvm-passes %s | \
+// RUN: llvm-cxxfilt | FileCheck %s
// Verify that no per variable _Init_thread instructions are emitted for non-trivial static locals
// These would normally be emitted by the MicrosoftCXXABI, but the DirectX backend should exlude them
@@ -13,17 +14,17 @@ void InitBuf(RWBuffer<int> buf) {
}
// CHECK-NOT: _Init_thread_epoch
-// CHECK: define internal void @_Z4mainv
+// CHECK: define internal void @main
// CHECK-NEXT: entry:
// CHECK-NEXT: [[Tmp0:%.*]] = alloca %"class.hlsl::RWBuffer"
// CHECK-NEXT: [[Tmp1:%.*]] = alloca %"class.hlsl::RWBuffer"
-// CHECK-NEXT: [[Tmp2:%.*]] = load i8, ptr @_ZGVZ4mainvE5mybuf
+// CHECK-NEXT: [[Tmp2:%.*]] = load i8, ptr @guard variable for main()::mybuf
// CHECK-NEXT: [[Tmp3:%.*]] = icmp eq i8 [[Tmp2]], 0
// CHECK-NEXT: br i1 [[Tmp3]]
// CHECK-NOT: _Init_thread_header
// CHECK: init.check:
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiE27__createFromImplicitBindingEjjijPKc(
-// CHECK-NEXT: store i8 1, ptr @_ZGVZ4mainvE5mybuf
+// CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding
+// CHECK-NEXT: store i8 1, ptr @guard variable for main()::mybuf
// CHECK-NOT: _Init_thread_footer
More information about the llvm-branch-commits
mailing list