[llvm-branch-commits] [clang] [HLSL] Use static create methods to initialize resources in arrays (PR #157005)
Helena Kotas via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Sep 4 20:02:23 PDT 2025
https://github.com/hekota created https://github.com/llvm/llvm-project/pull/157005
Use static methods __createFromBinding and __createFromImplicitBinding to initialize resources in resource arrays.
Depends on #156544
Part 3 of #154221
>From 7e9d4c5d6757062b53c5fe99cf01636441af93af Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 4 Sep 2025 10:12:01 -0700
Subject: [PATCH 1/2] [HLSL] Use static create methods to initialize resources
in arrays
Use static methods __createFromBinding and __createFromImplicitBinding to initialize
resources in resource arrays.
Depends on #156544
Part 3 of #154221
---
clang/include/clang/Sema/SemaHLSL.h | 5 -
clang/lib/CodeGen/CGHLSLRuntime.cpp | 126 ++++++++++--------
clang/lib/Sema/SemaHLSL.cpp | 92 ++++---------
.../resources/res-array-global-dyn-index.hlsl | 9 +-
.../resources/res-array-global-multi-dim.hlsl | 28 ++--
.../res-array-global-subarray-many.hlsl | 47 ++++---
.../res-array-global-subarray-one.hlsl | 23 ++--
.../resources/res-array-global.hlsl | 43 +++---
.../hlsl_resource_handle_attrs.hlsl | 4 +-
9 files changed, 183 insertions(+), 194 deletions(-)
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 5cbe1b658f5cd..86265a51fb252 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -241,11 +241,6 @@ class SemaHLSL : public SemaBase {
bool initGlobalResourceDecl(VarDecl *VD);
bool initGlobalResourceArrayDecl(VarDecl *VD);
- void createResourceRecordCtorArgs(const Type *ResourceTy, StringRef VarName,
- HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding,
- uint32_t ArrayIndex,
- llvm::SmallVectorImpl<Expr *> &Args);
};
} // namespace clang
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index d27f3781c69a3..fa365f419cdb1 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "CGHLSLRuntime.h"
+#include "Address.h"
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
@@ -38,6 +39,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include <cstdint>
+#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -148,14 +150,22 @@ static Value *buildNameForResource(llvm::StringRef BaseName,
.getPointer();
}
-static void createResourceCtorArgs(CodeGenModule &CGM, CXXConstructorDecl *CD,
- llvm::Value *ThisPtr, llvm::Value *Range,
- llvm::Value *Index, StringRef Name,
- HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding,
- CallArgList &Args) {
+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;
+}
+
+static CXXMethodDecl *lookupResourceInitMethodAndSetupArgs(
+ CodeGenModule &CGM, CXXRecordDecl *ResourceDecl, llvm::Value *Range,
+ llvm::Value *Index, StringRef Name, HLSLResourceBindingAttr *RBA,
+ HLSLVkBindingAttr *VkBinding, CallArgList &Args) {
assert((VkBinding || RBA) && "at least one a binding attribute expected");
+ ASTContext &AST = CGM.getContext();
std::optional<uint32_t> RegisterSlot;
uint32_t SpaceNo = 0;
if (VkBinding) {
@@ -167,44 +177,57 @@ static void createResourceCtorArgs(CodeGenModule &CGM, CXXConstructorDecl *CD,
SpaceNo = RBA->getSpaceNumber();
}
- ASTContext &AST = CD->getASTContext();
+ CXXMethodDecl *CreateMethod = nullptr;
Value *NameStr = buildNameForResource(Name, CGM);
Value *Space = llvm::ConstantInt::get(CGM.IntTy, SpaceNo);
- Args.add(RValue::get(ThisPtr), CD->getThisType());
if (RegisterSlot.has_value()) {
// explicit binding
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RegisterSlot.value());
Args.add(RValue::get(RegSlot), AST.UnsignedIntTy);
- Args.add(RValue::get(Space), AST.UnsignedIntTy);
- Args.add(RValue::get(Range), AST.IntTy);
- Args.add(RValue::get(Index), AST.UnsignedIntTy);
-
+ CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
} else {
// implicit binding
- assert(RBA && "missing implicit binding attribute");
auto *OrderID =
llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
- Args.add(RValue::get(Space), AST.UnsignedIntTy);
- Args.add(RValue::get(Range), AST.IntTy);
- Args.add(RValue::get(Index), AST.UnsignedIntTy);
Args.add(RValue::get(OrderID), AST.UnsignedIntTy);
+ CreateMethod =
+ lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
}
+ Args.add(RValue::get(Space), AST.UnsignedIntTy);
+ Args.add(RValue::get(Range), AST.IntTy);
+ Args.add(RValue::get(Index), AST.UnsignedIntTy);
Args.add(RValue::get(NameStr), AST.getPointerType(AST.CharTy.withConst()));
+
+ return CreateMethod;
+}
+
+static void callResourceInitMethod(CodeGenFunction &CGF,
+ CXXMethodDecl *CreateMethod,
+ CallArgList &Args, Address ReturnAddress) {
+ llvm::Constant *CalleeFn = CGF.CGM.GetAddrOfFunction(CreateMethod);
+ const FunctionProtoType *Proto =
+ CreateMethod->getType()->getAs<FunctionProtoType>();
+ const CGFunctionInfo &FnInfo =
+ CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, Proto, false);
+ ReturnValueSlot ReturnValue(ReturnAddress, false);
+ CGCallee Callee(CGCalleeInfo(Proto), CalleeFn);
+ CGF.EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr);
}
// Initializes local resource array variable. For multi-dimensional arrays it
// calls itself recursively to initialize its sub-arrays. The Index used in the
// resource constructor calls will begin at StartIndex and will be incremented
// for each array element. The last used resource Index is returned to the
-// caller.
-static Value *initializeLocalResourceArray(
- CodeGenFunction &CGF, AggValueSlot &ValueSlot,
- const ConstantArrayType *ArrayTy, CXXConstructorDecl *CD,
+// caller. If the function returns std::nullopt, it indicates an error.
+static std::optional<llvm::Value *> initializeLocalResourceArray(
+ CodeGenFunction &CGF, CXXRecordDecl *ResourceDecl,
+ const ConstantArrayType *ArrayTy, AggValueSlot &ValueSlot,
llvm::Value *Range, llvm::Value *StartIndex, StringRef ResourceName,
HLSLResourceBindingAttr *RBA, HLSLVkBindingAttr *VkBinding,
ArrayRef<llvm::Value *> PrevGEPIndices, SourceLocation ArraySubsExprLoc) {
+ ASTContext &AST = CGF.getContext();
llvm::IntegerType *IntTy = CGF.CGM.IntTy;
llvm::Value *Index = StartIndex;
llvm::Value *One = llvm::ConstantInt::get(IntTy, 1);
@@ -225,16 +248,19 @@ static Value *initializeLocalResourceArray(
Index = CGF.Builder.CreateAdd(Index, One);
GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
}
- Index = initializeLocalResourceArray(
- CGF, ValueSlot, SubArrayTy, CD, Range, Index, ResourceName, RBA,
- VkBinding, GEPIndices, ArraySubsExprLoc);
+ std::optional<llvm::Value *> MaybeIndex = initializeLocalResourceArray(
+ CGF, ResourceDecl, SubArrayTy, ValueSlot, Range, Index, ResourceName,
+ RBA, VkBinding, GEPIndices, ArraySubsExprLoc);
+ if (!MaybeIndex)
+ return std::nullopt;
+ Index = *MaybeIndex;
}
return Index;
}
// For array of resources, initialize each resource in the array.
llvm::Type *Ty = CGF.ConvertTypeForMem(ElemType);
- CharUnits ElemSize = CD->getASTContext().getTypeSizeInChars(ElemType);
+ CharUnits ElemSize = AST.getTypeSizeInChars(ElemType);
CharUnits Align =
TmpArrayAddr.getAlignment().alignmentOfArrayElement(ElemSize);
@@ -243,16 +269,18 @@ static Value *initializeLocalResourceArray(
Index = CGF.Builder.CreateAdd(Index, One);
GEPIndices.back() = llvm::ConstantInt::get(IntTy, I);
}
- Address ThisAddress =
+ Address ReturnAddress =
CGF.Builder.CreateGEP(TmpArrayAddr, GEPIndices, Ty, Align);
- llvm::Value *ThisPtr = CGF.getAsNaturalPointerTo(ThisAddress, ElemType);
CallArgList Args;
- createResourceCtorArgs(CGF.CGM, CD, ThisPtr, Range, Index, ResourceName,
- RBA, VkBinding, Args);
- CGF.EmitCXXConstructorCall(CD, Ctor_Complete, false, false, ThisAddress,
- Args, ValueSlot.mayOverlap(), ArraySubsExprLoc,
- ValueSlot.isSanitizerChecked());
+ CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
+ CGF.CGM, ResourceDecl, Range, Index, ResourceName, RBA, VkBinding,
+ Args);
+
+ if (!CreateMethod)
+ return std::nullopt;
+
+ callResourceInitMethod(CGF, CreateMethod, Args, ReturnAddress);
}
return Index;
}
@@ -906,11 +934,6 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
QualType ResourceTy =
ResultTy->isArrayType() ? AST.getBaseElementType(ResultTy) : ResultTy;
- // Lookup the resource class constructor based on the resource type and
- // binding.
- CXXConstructorDecl *CD = findResourceConstructorDecl(
- AST, ResourceTy, VkBinding || RBA->hasRegisterSlot());
-
// Create a temporary variable for the result, which is either going
// to be a single resource instance or a local array of resources (we need to
// return an LValue).
@@ -923,7 +946,6 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
TmpVar, Qualifiers(), AggValueSlot::IsDestructed_t(true),
AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsAliased_t(false),
AggValueSlot::DoesNotOverlap);
- Address TmpVarAddress = ValueSlot.getAddress();
// Calculate total array size (= range size).
llvm::Value *Range =
@@ -932,27 +954,27 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr(
// If the result of the subscript operation is a single resource, call the
// constructor.
if (ResultTy == ResourceTy) {
- QualType ThisType = CD->getThisType()->getPointeeType();
- llvm::Value *ThisPtr = CGF.getAsNaturalPointerTo(TmpVarAddress, ThisType);
-
- // Assemble the constructor parameters.
CallArgList Args;
- createResourceCtorArgs(CGM, CD, ThisPtr, Range, Index, ArrayDecl->getName(),
- RBA, VkBinding, Args);
- // Call the constructor.
- CGF.EmitCXXConstructorCall(CD, Ctor_Complete, false, false, TmpVarAddress,
- Args, ValueSlot.mayOverlap(),
- ArraySubsExpr->getExprLoc(),
- ValueSlot.isSanitizerChecked());
+ CXXMethodDecl *CreateMethod = lookupResourceInitMethodAndSetupArgs(
+ CGF.CGM, ResourceTy->getAsCXXRecordDecl(), Range, Index,
+ ArrayDecl->getName(), RBA, VkBinding, Args);
+
+ if (!CreateMethod)
+ return std::nullopt;
+
+ callResourceInitMethod(CGF, CreateMethod, Args, ValueSlot.getAddress());
+
} else {
// The result of the subscript operation is a local resource array which
// needs to be initialized.
const ConstantArrayType *ArrayTy =
cast<ConstantArrayType>(ResultTy.getTypePtr());
- initializeLocalResourceArray(CGF, ValueSlot, ArrayTy, CD, Range, Index,
- ArrayDecl->getName(), RBA, VkBinding,
- {llvm::ConstantInt::get(CGM.IntTy, 0)},
- ArraySubsExpr->getExprLoc());
+ std::optional<llvm::Value *> EndIndex = initializeLocalResourceArray(
+ CGF, ResourceTy->getAsCXXRecordDecl(), ArrayTy, ValueSlot, Range, Index,
+ ArrayDecl->getName(), RBA, VkBinding,
+ {llvm::ConstantInt::get(CGM.IntTy, 0)}, ArraySubsExpr->getExprLoc());
+ if (!EndIndex)
+ return std::nullopt;
}
return CGF.MakeAddrLValue(TmpVar, ResultTy, AlignmentSource::Decl);
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 63ca46583a59b..e9beb3f39ae68 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3696,55 +3696,6 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
deduceAddressSpace(VD);
}
-void SemaHLSL::createResourceRecordCtorArgs(
- const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA,
- HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex,
- llvm::SmallVectorImpl<Expr *> &Args) {
- 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();
- }
-
- ASTContext &AST = SemaRef.getASTContext();
- uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
- uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
- IntegerLiteral *RangeSize = IntegerLiteral::Create(
- AST, llvm::APInt(IntTySize, 1), AST.IntTy, SourceLocation());
- IntegerLiteral *Index =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, ArrayIndex),
- AST.UnsignedIntTy, SourceLocation());
- IntegerLiteral *Space =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
- AST.UnsignedIntTy, SourceLocation());
- StringLiteral *Name = StringLiteral::Create(
- AST, VarName, StringLiteralKind::Ordinary, false,
- AST.getStringLiteralArrayType(AST.CharTy.withConst(), VarName.size()),
- SourceLocation());
-
- // resource with explicit binding
- if (RegisterSlot.has_value()) {
- IntegerLiteral *RegSlot = IntegerLiteral::Create(
- AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy,
- SourceLocation());
- Args.append({RegSlot, Space, RangeSize, Index, Name});
- } else {
- // resource with implicit binding
- uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
- ? RBA->getImplicitBindingOrderID()
- : getNextImplicitBindingOrderID();
- IntegerLiteral *OrderId =
- IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID),
- AST.UnsignedIntTy, SourceLocation());
- Args.append({Space, RangeSize, Index, OrderId, Name});
- }
-}
-
bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
assert(VD->getType()->isHLSLResourceRecord() &&
"expected resource record type");
@@ -3849,28 +3800,37 @@ bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) {
// Individual resources in a resource array are not initialized here. They
// are initialized later on during codegen when the individual resources are
- // accessed. Codegen will emit a call to the resource constructor with the
- // specified array index. We need to make sure though that the constructor
+ // accessed. Codegen will emit a call to the resource initialization method
+ // with the specified array index. We need to make sure though that the method
// for the specific resource type is instantiated, so codegen can emit a call
// to it when the array element is accessed.
- SmallVector<Expr *> Args;
- QualType ResElementTy = VD->getASTContext().getBaseElementType(VD->getType());
- createResourceRecordCtorArgs(ResElementTy.getTypePtr(), VD->getName(),
- VD->getAttr<HLSLResourceBindingAttr>(),
- VD->getAttr<HLSLVkBindingAttr>(), 0, Args);
- SourceLocation Loc = VD->getLocation();
- InitializedEntity Entity =
- InitializedEntity::InitializeTemporary(ResElementTy);
- InitializationKind Kind = InitializationKind::CreateDirect(Loc, Loc, Loc);
- InitializationSequence InitSeq(SemaRef, Entity, Kind, Args);
- if (InitSeq.Failed())
+ // Find correct initialization method based on the resource binding
+ // information.
+ ASTContext &AST = SemaRef.getASTContext();
+ QualType ResElementTy = AST.getBaseElementType(VD->getType());
+ CXXRecordDecl *ResourceDecl = ResElementTy->getAsCXXRecordDecl();
+
+ HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
+ HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
+ CXXMethodDecl *CreateMethod = nullptr;
+
+ if (VkBinding || (RBA && RBA->hasRegisterSlot()))
+ // Resource has explicit binding.
+ CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static);
+ else
+ // Resource has implicit binding.
+ CreateMethod =
+ lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static);
+
+ if (!CreateMethod)
return false;
- // This takes care of instantiating and emitting of the constructor that will
- // be called from codegen when the array is accessed.
- ExprResult OneResInit = InitSeq.Perform(SemaRef, Entity, Kind, Args);
- return !OneResInit.isInvalid();
+ // Make sure the create method template is instantiated and emitted.
+ if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation())
+ SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod,
+ true);
+ return true;
}
// Returns true if the initialization has been handled.
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
index 5b62452ef9844..9638fa5d77934 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
@@ -6,10 +6,8 @@
RWBuffer<float> A[4][3] : register(u2);
RWStructuredBuffer<float> Out;
-// Make sure A[GI.x][GI.y] is translated to a RWBuffer<float> constructor call with range 12 and dynamically calculated index
-
-// NOTE:
-// Constructor call for explicit binding has "jjij" in the mangled name and the arguments are (register, space, range_size, index, name).
+// Make sure A[GI.x][GI.y] is translated to a RWBuffer<float>::__createFromBinding call
+// with range 12 and dynamically calculated index
// CHECK: define internal void @_Z4mainDv3_j(<3 x i32> noundef %GI)
// CHECK: %[[GI_alloca:.*]] = alloca <3 x i32>, align 16
@@ -22,7 +20,8 @@ RWStructuredBuffer<float> Out;
// CHECK: %[[GI_x:.*]] = extractelement <3 x i32> %[[GI]], i32 0
// CHECK: %[[Tmp1:.*]] = mul i32 %[[GI_x]], 3
// CHECK: %[[Index:.*]] = add i32 %[[GI_y]], %[[Tmp1]]
-// CHECK: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 2, i32 noundef 0, i32 noundef 12, i32 noundef %[[Index]], ptr noundef @A.str)
+// CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
+// CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 12, i32 noundef %[[Index]], ptr noundef @A.str)
[numthreads(4,1,1)]
void main(uint3 GI : SV_GroupThreadID) {
Out[0] = A[GI.x][GI.y][0];
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
index 8d664dad58153..e267b01947abb 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
@@ -23,24 +23,20 @@ void main() {
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp3:.*]] = alloca %"class.hlsl::RWBuffer
- // NOTE:
- // Constructor call for explicit binding has "jjij" in the mangled name and the arguments are (register, space, range_size, index, name).
- // For implicit binding the constructor has "jijj" in the mangled name and the arguments are (space, range_size, index, order_id, name).
- // The range_size can be -1 for unbounded arrays, and that is the only signed int in the signature.
- // The order_id argument is a sequential number that is assigned to resources with implicit binding and corresponds to the order in which
- // the resources were declared. It is needed because implicit bindings are assigned later on in an LLVM pass that needs to know the order
- // of the resource declarations.
+ // Make sure that B[3][2] is translated to a RWBuffer<float>::__createFromBinding call (u2, space0) with range 16 and index 14
+ // CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}}sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp0]],
+ // CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
- // Make sure that B[3][2] is translated to a RWBuffer<float> constructor call for explicit binding (u2, space0) with range 16 and index 14
- // CHECK: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
+ // Make sure that C[1][0][3] is translated to a RWBuffer<int>::__createFromBinding call (u10, space1) with range 20 and index 13
+ // CHECK: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align {{(4|8)}} %[[Tmp1]],
+ // CHECK-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 20, i32 noundef 13, ptr noundef @[[BufC]])
- // Make sure that C[1][0][3] is translated to a RWBuffer<int> constructor call for explicit binding (u10, space1) with range 20 and index 13
- // CHECK: call void @_ZN4hlsl8RWBufferIiEC1EjjijPKc(ptr {{.*}} %[[Tmp1]], i32 noundef 10, i32 noundef 1, i32 noundef 20, i32 noundef 13, ptr noundef @[[BufC]])
+ // Make sure that D[9][2] is translated to a RWBuffer<uint>::__createFromImplicitBinding call with range 50 and index 47
+ // CHECK: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align {{(4|8)}} %[[Tmp2]],
+ // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 50, i32 noundef 47, ptr noundef @[[BufD]])
- // Make sure that D[9][2] is translated to a RWBuffer<uint> constructor call for implicit binding (u18, space0) with range 50 and index 47
- // CHECK: call void @_ZN4hlsl8RWBufferIjEC1EjijjPKc(ptr {{.*}} %[[Tmp2]], i32 noundef 0, i32 noundef 50, i32 noundef 47, i32 noundef 0, ptr noundef @[[BufD]])
-
- // Make sure that the second B[3][2] is translated to the same a RWBuffer<float> constructor call as the first B[3][2] subscript
- // CHECK: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp3]], i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
+ // Make sure that the second B[3][2] is translated to the same RWBuffer<float>::__createFromBinding call as the first B[3][2] subscript
+ // CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} writable sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp3]],
+ // CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
Out[0] = B[3][2][0] + (float)C[1][0][3][0] + (float)D[9][2][0] + B[3][2][1];
}
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
index 254d1900cd2f1..9cb413058f463 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
@@ -17,11 +17,6 @@ float foo(RWBuffer<float> Arr[3][2]) {
return Arr[1][0][0];
}
-// NOTE:
-// - _ZN4hlsl8RWBufferIfEC1EjjijPKc is the constructor call for explicit binding
-// (has "jjij" in the mangled name) and the arguments are (register, space, range_size, index, name).
-// - _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float>
-
// CHECK: define internal void @_Z4mainj(i32 noundef %GI)
// CHECK-NEXT: entry:
// CHECK-NEXT: %[[GI_alloca:.*]] = alloca i32, align 4
@@ -35,21 +30,27 @@ float foo(RWBuffer<float> Arr[3][2]) {
[numthreads(4,1,1)]
void main(uint GI : SV_GroupThreadID) {
// Codegen for "A[4][1]" - create local array [[Tmp0]] of size 3 x 2 and initialize
-// each element by a call to the resource constructor
+// each element by a call to RWBuffer<float>::__createFromBinding
// The resource index for A[4][1][0][0] is 102 = 4 * (4 * 3 * 2) + 1 * (3 * 2)
// (index in the resource array as if it was flattened)
// CHECK-NEXT: %[[Ptr_Tmp0_0_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_0_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 102, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 102, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_0_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_0_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 103, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 103, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_1_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 1, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_1_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 104, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 104, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_1_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 1, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_1_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 105, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 105, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_2_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 2, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_2_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 106, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_2_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 106, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_2_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 2, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_2_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 107, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_2_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 107, ptr noundef @[[BufA]])
// After this Tmp0 values are copied to %Sub using the standard array loop initializaion
// (generated from ArrayInitLoopExpr AST node)
RWBuffer<float> Sub[3][2] = A[4][1];
@@ -62,8 +63,8 @@ void main(uint GI : SV_GroupThreadID) {
float a = Sub[2][1][0];
// Codegen for "foo(A[2][GI])" - create local array [[Tmp2]] of size 3 x 2 and initialize
-// each element by a call to the resource constructor with dynamic index, and then
-// copy-in the array as an argument of "foo"
+// each element by a call to the RWBuffer<float>::__createFromBinding with dynamic index,
+// and then copy-in the array as an argument of "foo"
// Calculate the resource index for A[2][GI][0][0] (index in the resource array as if it was flattened)
// The index is 2 * (4 * 3 * 2) + GI * (3 * 2) = 48 + GI * 6
@@ -73,32 +74,38 @@ void main(uint GI : SV_GroupThreadID) {
// A[2][GI][0][0]
// CHECK-NEXT: %[[Ptr_Tmp2_0_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_0_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_0]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_0_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_0]], ptr noundef @[[BufA]])
// A[2][GI][0][1]
// CHECK-NEXT: %[[Index_A_2_GI_0_1:.*]] = add i32 %[[Index_A_2_GI_0_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_0_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_0_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_1]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_0_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_1]], ptr noundef @[[BufA]])
// A[2][GI][1][0]
// CHECK-NEXT: %[[Index_A_2_GI_1_0:.*]] = add i32 %[[Index_A_2_GI_0_1]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_1_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 1, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_1_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_0]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_1_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_0]], ptr noundef @[[BufA]])
// A[2][GI][1][1]
// CHECK-NEXT: %[[Index_A_2_GI_1_1:.*]] = add i32 %[[Index_A_2_GI_1_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_1_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 1, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_1_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_1]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_1_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_1]], ptr noundef @[[BufA]])
// A[2][GI][2][0]
// CHECK-NEXT: %[[Index_A_2_GI_2_0:.*]] = add i32 %[[Index_A_2_GI_1_1]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_2_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 2, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_2_0]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_0]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_2_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_0]], ptr noundef @[[BufA]])
// A[2][GI][2][1]
// CHECK-NEXT: %[[Index_A_2_GI_2_1:.*]] = add i32 %[[Index_A_2_GI_2_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_2_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 2, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_2_1]], i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_1]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_2_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_1]], ptr noundef @[[BufA]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 24, i1 false)
// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @_Z3fooA3_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([3 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[Tmp1]])
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
index 6f343f1282c3d..0a7745f7d0768 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
@@ -10,11 +10,6 @@ float foo(RWBuffer<float> Arr[2]) {
return Arr[1][0];
}
-// NOTE:
-// - _ZN4hlsl8RWBufferIfEC1EjjijPKc is the constructor call for explicit binding
-// (has "jjij" in the mangled name) and the arguments are (register, space, range_size, index, name).
-// - _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float>
-
// CHECK: define internal void @_Z4mainj(i32 noundef %GI)
// CHECK-NEXT: entry:
// CHECK-NEXT: %[[GI_alloca:.*]] = alloca i32, align 4
@@ -28,11 +23,13 @@ float foo(RWBuffer<float> Arr[2]) {
[numthreads(4,1,1)]
void main(uint GI : SV_GroupThreadID) {
// Codegen for "A[2]" - create local array [[Tmp0]] of size 2 and initialize
-// each element by a call to the resource constructor
+// each element by a call to RWBuffer<float>::__createFromBinding method
// CHECK-NEXT: %[[Ptr_Tmp0_0:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp0]], i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_0]], i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 6, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 6, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_1:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp0]], i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp0_1]], i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 7, ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 7, ptr noundef @[[BufA]])
// After this Tmp0 values are copied to %Sub using the standard array loop initializaion
// (generated from ArrayInitLoopExpr AST node)
RWBuffer<float> Sub[2] = A[3];
@@ -44,15 +41,17 @@ void main(uint GI : SV_GroupThreadID) {
float a = Sub[1][0];
// Codegen for "foo(A[GI])" - create local array [[Tmp2]] of size 2 and initialize
-// each element by a call to the resource constructor with dynamic index, and then
-// copy-in the array as an argument of "foo"
+// each element by a call to the RWBuffer<float>::__createFromBinding method
+// with dynamic index, and then copy-in the array as an argument of "foo"
// CHECK: %[[GI:.*]] = load i32, ptr %[[GI_alloca]], align 4
// CHECK-NEXT: %[[Index_A_GI_0:.*]] = mul i32 %[[GI]], 2
// CHECK-NEXT: %[[Ptr_Tmp2_GI_0:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_GI_0]], i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_0]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_GI_0]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_0]], ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Index_A_GI_1:.*]] = add i32 %[[Index_A_GI_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_GI_1:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Ptr_Tmp2_GI_1]], i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_1]], ptr noundef @[[BufA]])
+// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_GI_1]],
+// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_1]], ptr noundef @[[BufA]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 8, i1 false)
// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @_Z3fooA2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x %"class.hlsl::RWBuffer"]) align 4 %[[Tmp1]])
// CHECK-NEXT: store float %[[FooReturned]], ptr %b, align 4
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
index 595ea818e913b..4618e7ecde274 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
@@ -45,31 +45,42 @@ void main() {
// the resources were declared. It is needed because implicit bindings are assigned later on in an LLVM pass that needs to know the order
// of the resource declarations.
- // Make sure A[2] is translated to a RWBuffer<float> constructor call with range 4 and index 2
+ // Make sure A[2] is translated to a RWBuffer<float>::__createFromBinding call with range 4 and index 2
// and DXIL explicit binding (u10, space1)
// and SPIR-V explicit binding (binding 12, set 2)
- // DXIL: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 10, i32 noundef 1, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
- // SPV: call void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr {{.*}} %[[Tmp0]], i32 noundef 12, i32 noundef 2, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
+ // DXIL: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
+ // DXIL-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
+ // SPV: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 8 %[[Tmp0]],
+ // SPV-SAME: i32 noundef 12, i32 noundef 2, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
- // Make sure B[3] is translated to a RWBuffer<int> constructor call with range 5 and index 3
+ // Make sure B[3] is translated to a RWBuffer<int>::__createFromImplicitBinding call with range 5 and index 3
// and DXIL for implicit binding in space0, order id 0
// and SPIR-V explicit binding (binding 13, set 0)
- // DXIL: call void @_ZN4hlsl8RWBufferIiEC1EjijjPKc(ptr {{.*}} %[[Tmp1]], i32 noundef 0, i32 noundef 5, i32 noundef 3, i32 noundef 0, ptr noundef @[[BufB]])
- // SPV: call void @_ZN4hlsl8RWBufferIiEC1EjjijPKc(ptr {{.*}} %[[Tmp1]], i32 noundef 13, i32 noundef 0, i32 noundef 5, i32 noundef 3, ptr noundef @[[BufB]])
+ // DXIL: call void @_ZN4hlsl8RWBufferIiE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp1]],
+ // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 5, i32 noundef 3, ptr noundef @[[BufB]])
+ // SPV: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp1]],
+ // SPV-SAME: i32 noundef 13, i32 noundef 0, i32 noundef 5, i32 noundef 3, ptr noundef @[[BufB]])
- // Make sure C[1] is translated to a RWBuffer<int> constructor call with range 3 and index 1
- // and DXIL explicit binding (u2, space0)
+ // Make sure C[1] is translated to a RWBuffer<int>::__createFromBinding call with range 3 and index 1
+ // and DXIL explicit binding (u2, space0)
// and SPIR-V explicit binding (binding 2, set 0)
- // DXIL: call void @_ZN4hlsl8RWBufferIiEC1EjjijPKc(ptr {{.*}} %[[Tmp2]], i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
- // SPV: call void @_ZN4hlsl8RWBufferIiEC1EjjijPKc(ptr {{.*}} %[[Tmp2]], i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
+ // DXIL: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp2]],
+ // DXIL-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
+ // SPV: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp2]],
+ // SPV-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
- // Make sure D[7] is translated to a RWBuffer<double> constructor call with implicit binding
+ // Make sure D[7] is translated to a RWBuffer<double>::__createFromImplicitBinding call
// for both DXIL and SPIR-V
- // DXIL: call void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr {{.*}} %[[Tmp3]], i32 noundef 0, i32 noundef 10, i32 noundef 7, i32 noundef 1, ptr noundef @[[BufD]])
- // SPV: call void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr {{.*}} %[[Tmp3]], i32 noundef 0, i32 noundef 10, i32 noundef 7, i32 noundef 0, ptr noundef @[[BufD]])
+ // DXIL: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 4 %[[Tmp3]],
+ // DXIL-SAME: i32 noundef 1, i32 noundef 0, i32 noundef 10, i32 noundef 7, ptr noundef @D.str)
+ // SPV: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 8 %[[Tmp3]],
+ // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 10, i32 noundef 7, ptr noundef @[[BufD]])
- // Make sure E[5][0] is translated to RWBuffer<uint> constructor call with implicit binding and specified space/set 2
- // DXIL: call void @_ZN4hlsl8RWBufferIjEC1EjijjPKc(ptr {{.*}} %[[Tmp4]], i32 noundef 2, i32 noundef 15, i32 noundef 5, i32 noundef 2, ptr noundef @[[BufE]])
- // SPV: call void @_ZN4hlsl8RWBufferIjEC1EjijjPKc(ptr {{.*}} %[[Tmp4]], i32 noundef 2, i32 noundef 15, i32 noundef 5, i32 noundef 1, ptr noundef @[[BufE]])
+ // Make sure E[5][0] is translated to RWBuffer<uint>::__createFromImplicitBinding call
+ // for both DXIL and SPIR-V with specified space/set 2
+ // DXIL: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 4 %[[Tmp4]],
+ // DXIL-SAME: i32 noundef 2, i32 noundef 2, i32 noundef 15, i32 noundef 5, ptr noundef @[[BufE]])
+ // SPV: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 8 %[[Tmp4]],
+ // SPV-SAME: i32 noundef 1, i32 noundef 2, i32 noundef 15, i32 noundef 5, ptr noundef @[[BufE]])
Out[0] = A[2][0] + (float)B[3][0] + (float)C[1][0] + (float)D[7][0] + (float)E[5][0];
}
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index 36e70bc686be8..8f1aab1c94a02 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -3,7 +3,7 @@
// CHECK: ClassTemplateSpecializationDecl {{.*}} class RWBuffer definition implicit_instantiation
// CHECK: TemplateArgument type 'float'
// CHECK: BuiltinType {{.*}} 'float'
-// CHECK: FieldDecl {{.*}} implicit referenced __handle '__hlsl_resource_t
+// CHECK: FieldDecl {{.*}} implicit{{.*}} __handle '__hlsl_resource_t
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]]
RWBuffer<float> Buffer1;
@@ -12,7 +12,7 @@ RWBuffer<float> Buffer1;
// CHECK: TemplateArgument type 'vector<float, 4>'
// CHECK: ExtVectorType {{.*}} 'vector<float, 4>' 4
// CHECK: BuiltinType {{.*}} 'float'
-// CHECK: FieldDecl {{.*}} implicit referenced __handle '__hlsl_resource_t
+// CHECK: FieldDecl {{.*}} implicit{{.*}} __handle '__hlsl_resource_t
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]
// CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<float, 4>)]]
>From 6669bd72d95a783123844d13397fe79799a753ce Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 4 Sep 2025 20:00:33 -0700
Subject: [PATCH 2/2] Update tests to use llvm-cxxfilt to have names without
mangling
---
.../resources/res-array-global-dyn-index.hlsl | 7 ++-
.../resources/res-array-global-multi-dim.hlsl | 18 +++---
.../res-array-global-subarray-many.hlsl | 56 +++++++++++++------
.../res-array-global-subarray-one.hlsl | 20 ++++---
.../resources/res-array-global.hlsl | 46 +++++++--------
5 files changed, 89 insertions(+), 58 deletions(-)
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
index e5acfbf6e20ab..f17cf12945e4a 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1
@@ -9,7 +9,7 @@ RWStructuredBuffer<float> Out;
// Make sure A[GI.x][GI.y] is translated to a RWBuffer<float>::__createFromBinding call
// with range 12 and dynamically calculated index
-// CHECK: define internal void @_Z4mainDv3_j(<3 x i32> noundef %GI)
+// CHECK: define internal void @main(unsigned int vector[3])(<3 x i32> noundef %GI)
// CHECK: %[[GI_alloca:.*]] = alloca <3 x i32>, align 16
// CHECK: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: store <3 x i32> %GI, ptr %[[GI_alloca]]
@@ -20,7 +20,8 @@ RWStructuredBuffer<float> Out;
// CHECK: %[[GI_x:.*]] = extractelement <3 x i32> %[[GI]], i32 0
// CHECK: %[[Tmp1:.*]] = mul i32 %[[GI_x]], 3
// CHECK: %[[Index:.*]] = add i32 %[[GI_y]], %[[Tmp1]]
-// CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
+// CHECK: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
// CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 12, i32 noundef %[[Index]], ptr noundef @A.str)
[numthreads(4,1,1)]
void main(uint3 GI : SV_GroupThreadID) {
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
index be2ff87c800a4..1a05897b9e70b 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufB:.*]] = private unnamed_addr constant [2 x i8] c"B\00", align 1
// CHECK: @[[BufC:.*]] = private unnamed_addr constant [2 x i8] c"C\00", align 1
@@ -17,26 +17,30 @@ RWStructuredBuffer<float> Out;
[numthreads(4,1,1)]
void main() {
- // CHECK: define internal{{.*}} void @_Z4mainv()
+ // CHECK: define internal{{.*}} void @main()
// CHECK: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp3:.*]] = alloca %"class.hlsl::RWBuffer
// Make sure that B[3][2] is translated to a RWBuffer<float>::__createFromBinding call (u2, space0) with range 16 and index 14
- // CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}}sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp0]],
+ // CHECK: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp0]],
// CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
// Make sure that C[1][0][3] is translated to a RWBuffer<int>::__createFromBinding call (u10, space1) with range 20 and index 13
- // CHECK: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align {{(4|8)}} %[[Tmp1]],
+ // CHECK: call void @hlsl::RWBuffer<int>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align {{(4|8)}} %[[Tmp1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 20, i32 noundef 13, ptr noundef @[[BufC]])
// Make sure that D[9][2] is translated to a RWBuffer<uint>::__createFromImplicitBinding call with range 50 and index 47
- // CHECK: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align {{(4|8)}} %[[Tmp2]],
+ // CHECK: call void @hlsl::RWBuffer<unsigned int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align {{(4|8)}} %[[Tmp2]],
// CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 50, i32 noundef 47, ptr noundef @[[BufD]])
// Make sure that the second B[3][2] is translated to the same RWBuffer<float>::__createFromBinding call as the first B[3][2] subscript
- // CHECK: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} writable sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp3]],
+ // CHECK: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // CHECK-SAME: (ptr {{.*}} writable sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Tmp3]],
// CHECK-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 16, i32 noundef 14, ptr noundef @[[BufB]])
Out[0] = B[3][2][0] + (float)C[1][0][3][0] + (float)D[9][2][0] + B[3][2][1];
}
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
index 9cb413058f463..a7a37e5ccc9be 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
@@ -1,23 +1,24 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1
RWBuffer<float> A[5][4][3][2] : register(u10, space2);
RWStructuredBuffer<float> Out;
-// CHECK: define {{.*}} float @_Z3fooA3_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([3 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %Arr)
+// CHECK: define {{.*}} float @foo(hlsl::RWBuffer<float> [3][2])
+// CHECK-SAME: (ptr noundef byval([3 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %Arr)
// CHECK-NEXT: entry:
float foo(RWBuffer<float> Arr[3][2]) {
// CHECK-NEXT: %[[Arr_1_Ptr:.*]] = getelementptr inbounds [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %Arr, i32 0, i32 1
// CHECK-NEXT: %[[Arr_1_0_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %[[Arr_1_Ptr]], i32 0, i32 0
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Arr_1_0_Ptr]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Arr_1_0_Ptr]], i32 noundef 0)
// CHECK-NEXT: %[[Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: ret float %[[Value]]
return Arr[1][0][0];
}
-// CHECK: define internal void @_Z4mainj(i32 noundef %GI)
+// CHECK: define internal void @main(unsigned int)(i32 noundef %GI)
// CHECK-NEXT: entry:
// CHECK-NEXT: %[[GI_alloca:.*]] = alloca i32, align 4
// CHECK-NEXT: %Sub = alloca [3 x [2 x %"class.hlsl::RWBuffer"]], align 4
@@ -34,30 +35,42 @@ void main(uint GI : SV_GroupThreadID) {
// The resource index for A[4][1][0][0] is 102 = 4 * (4 * 3 * 2) + 1 * (3 * 2)
// (index in the resource array as if it was flattened)
// CHECK-NEXT: %[[Ptr_Tmp0_0_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0_0]],
+// 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 %[[Ptr_Tmp0_0_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 102, ptr noundef @[[BufA]])
+
// CHECK-NEXT: %[[Ptr_Tmp0_0_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0_1]],
+// 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 %[[Ptr_Tmp0_0_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 103, ptr noundef @[[BufA]])
+
// CHECK-NEXT: %[[Ptr_Tmp0_1_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 1, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1_0]],
+// 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 %[[Ptr_Tmp0_1_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 104, ptr noundef @[[BufA]])
+
// CHECK-NEXT: %[[Ptr_Tmp0_1_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 1, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1_1]],
+// 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 %[[Ptr_Tmp0_1_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 105, ptr noundef @[[BufA]])
+
// CHECK-NEXT: %[[Ptr_Tmp0_2_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 2, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_2_0]],
+// 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 %[[Ptr_Tmp0_2_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 106, ptr noundef @[[BufA]])
+
// CHECK-NEXT: %[[Ptr_Tmp0_2_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %tmp, i32 0, i32 2, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_2_1]],
+// 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 %[[Ptr_Tmp0_2_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef 107, ptr noundef @[[BufA]])
+
// After this Tmp0 values are copied to %Sub using the standard array loop initializaion
// (generated from ArrayInitLoopExpr AST node)
RWBuffer<float> Sub[3][2] = A[4][1];
// CHECK: %[[Ptr_Sub_2:.*]] = getelementptr inbounds [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %Sub, i32 0, i32 2
// CHECK: %[[Ptr_Sub_2_1:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %[[Ptr_Sub_2]], i32 0, i32 1
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Ptr_Sub_2_1]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Ptr_Sub_2_1]], i32 noundef 0)
// CHECK-NEXT: %[[Sub_2_1_0_Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: store float %[[Sub_2_1_0_Value]], ptr %a, align 4
float a = Sub[2][1][0];
@@ -74,41 +87,48 @@ void main(uint GI : SV_GroupThreadID) {
// A[2][GI][0][0]
// CHECK-NEXT: %[[Ptr_Tmp2_0_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_0_0]],
+// 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 %[[Ptr_Tmp2_0_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_0]], ptr noundef @[[BufA]])
// A[2][GI][0][1]
// CHECK-NEXT: %[[Index_A_2_GI_0_1:.*]] = add i32 %[[Index_A_2_GI_0_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_0_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_0_1]],
+// 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 %[[Ptr_Tmp2_0_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_0_1]], ptr noundef @[[BufA]])
// A[2][GI][1][0]
// CHECK-NEXT: %[[Index_A_2_GI_1_0:.*]] = add i32 %[[Index_A_2_GI_0_1]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_1_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 1, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_1_0]],
+// 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 %[[Ptr_Tmp2_1_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_0]], ptr noundef @[[BufA]])
// A[2][GI][1][1]
// CHECK-NEXT: %[[Index_A_2_GI_1_1:.*]] = add i32 %[[Index_A_2_GI_1_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_1_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 1, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_1_1]],
+// 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 %[[Ptr_Tmp2_1_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_1_1]], ptr noundef @[[BufA]])
// A[2][GI][2][0]
// CHECK-NEXT: %[[Index_A_2_GI_2_0:.*]] = add i32 %[[Index_A_2_GI_1_1]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_2_0:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 2, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_2_0]],
+// 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 %[[Ptr_Tmp2_2_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_0]], ptr noundef @[[BufA]])
// A[2][GI][2][1]
// CHECK-NEXT: %[[Index_A_2_GI_2_1:.*]] = add i32 %[[Index_A_2_GI_2_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_2_1:.*]] = getelementptr [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %[[Tmp2]], i32 0, i32 2, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_2_1]],
+// 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 %[[Ptr_Tmp2_2_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 120, i32 noundef %[[Index_A_2_GI_2_1]], ptr noundef @[[BufA]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 24, i1 false)
-// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @_Z3fooA3_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([3 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[Tmp1]])
+// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @foo(hlsl::RWBuffer<float> [3][2])
+// CHECK-SAME: (ptr noundef byval([3 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[Tmp1]])
// CHECK-NEXT: store float %[[FooReturned]], ptr %b, align 4
float b = foo(A[2][GI]);
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
index 2f256c117016d..bbd48b7ddea52 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1
@@ -10,7 +10,7 @@ float foo(RWBuffer<float> Arr[2]) {
return Arr[1][0];
}
-// CHECK: define internal void @_Z4mainj(i32 noundef %GI)
+// CHECK: define internal void @main(unsigned int)(i32 noundef %GI)
// CHECK-NEXT: entry:
// CHECK-NEXT: %[[GI_alloca:.*]] = alloca i32, align 4
// CHECK-NEXT: %Sub = alloca [2 x %"class.hlsl::RWBuffer"], align 4
@@ -25,17 +25,19 @@ void main(uint GI : SV_GroupThreadID) {
// Codegen for "A[2]" - create local array [[Tmp0]] of size 2 and initialize
// each element by a call to RWBuffer<float>::__createFromBinding method
// CHECK-NEXT: %[[Ptr_Tmp0_0:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp0]], i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_0]],
+// 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 %[[Ptr_Tmp0_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 6, ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Ptr_Tmp0_1:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp0]], i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp0_1]],
+// 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 %[[Ptr_Tmp0_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef 7, ptr noundef @[[BufA]])
// After this Tmp0 values are copied to %Sub using the standard array loop initializaion
// (generated from ArrayInitLoopExpr AST node)
RWBuffer<float> Sub[2] = A[3];
// CHECK: %[[Ptr_Sub_1:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %Sub, i32 0, i32 1
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Ptr_Sub_1]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Ptr_Sub_1]], i32 noundef 0)
// CHECK-NEXT: %[[Sub_1_0_Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: store float %[[Sub_1_0_Value]], ptr %a, align 4
float a = Sub[1][0];
@@ -46,14 +48,16 @@ void main(uint GI : SV_GroupThreadID) {
// CHECK: %[[GI:.*]] = load i32, ptr %[[GI_alloca]], align 4
// CHECK-NEXT: %[[Index_A_GI_0:.*]] = mul i32 %[[GI]], 2
// CHECK-NEXT: %[[Ptr_Tmp2_GI_0:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 0
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_GI_0]],
+// 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 %[[Ptr_Tmp2_GI_0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_0]], ptr noundef @[[BufA]])
// CHECK-NEXT: %[[Index_A_GI_1:.*]] = add i32 %[[Index_A_GI_0]], 1
// CHECK-NEXT: %[[Ptr_Tmp2_GI_1:.*]] = getelementptr [2 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 1
-// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Ptr_Tmp2_GI_1]],
+// 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 %[[Ptr_Tmp2_GI_1]],
// CHECK-SAME: i32 noundef 10, i32 noundef 2, i32 noundef 8, i32 noundef %[[Index_A_GI_1]], ptr noundef @[[BufA]])
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 8, i1 false)
-// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @_Z3fooA2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x %"class.hlsl::RWBuffer"]) align 4 %[[Tmp1]])
+// CHECK-NEXT: %[[FooReturned:.*]] = call {{.*}} float @foo(hlsl::RWBuffer<float> [2])(ptr noundef byval([2 x %"class.hlsl::RWBuffer"]) align 4 %[[Tmp1]])
// CHECK-NEXT: store float %[[FooReturned]], ptr %b, align 4
float b = foo(A[GI]);
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
index 4618e7ecde274..2f530ccaa54cf 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global.hlsl
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -check-prefixes=CHECK,DXIL
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s -check-prefixes=CHECK,DXIL
// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute \
-// RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -check-prefixes=CHECK,SPV
+// RUN: -emit-llvm -disable-llvm-passes -o - %s | llvm-cxxfilt | FileCheck %s -check-prefixes=CHECK,SPV
// CHECK: @[[BufA:.*]] = private unnamed_addr constant [2 x i8] c"A\00", align 1
// CHECK: @[[BufB:.*]] = private unnamed_addr constant [2 x i8] c"B\00", align 1
@@ -30,57 +30,59 @@ RWStructuredBuffer<float> Out;
[numthreads(4,1,1)]
void main() {
- // CHECK: define internal{{.*}} void @_Z4mainv()
+ // CHECK: define internal{{.*}} void @main()
// CHECK: %[[Tmp0:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp3:.*]] = alloca %"class.hlsl::RWBuffer
// CHECK: %[[Tmp4:.*]] = alloca %"class.hlsl::RWBuffer
- // NOTE:
- // Constructor call for explicit binding has "jjij" in the mangled name and the arguments are (register, space, range_size, index, name).
- // For implicit binding the constructor has "jijj" in the mangled name and the arguments are (space, range_size, index, order_id, name).
- // The range_size can be -1 for unbounded arrays, and that is the only signed int in the signature.
- // The order_id argument is a sequential number that is assigned to resources with implicit binding and corresponds to the order in which
- // the resources were declared. It is needed because implicit bindings are assigned later on in an LLVM pass that needs to know the order
- // of the resource declarations.
-
// Make sure A[2] is translated to a RWBuffer<float>::__createFromBinding call with range 4 and index 2
// and DXIL explicit binding (u10, space1)
// and SPIR-V explicit binding (binding 12, set 2)
- // DXIL: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
+ // DXIL: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // DXIL-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[Tmp0]],
// DXIL-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
- // SPV: call void @_ZN4hlsl8RWBufferIfE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 8 %[[Tmp0]],
+ // SPV: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // SPV-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 8 %[[Tmp0]],
// SPV-SAME: i32 noundef 12, i32 noundef 2, i32 noundef 4, i32 noundef 2, ptr noundef @[[BufA]])
// Make sure B[3] is translated to a RWBuffer<int>::__createFromImplicitBinding call with range 5 and index 3
// and DXIL for implicit binding in space0, order id 0
// and SPIR-V explicit binding (binding 13, set 0)
- // DXIL: call void @_ZN4hlsl8RWBufferIiE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp1]],
+ // DXIL: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // DXIL-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp1]],
// DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 5, i32 noundef 3, ptr noundef @[[BufB]])
- // SPV: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp1]],
+ // SPV: call void @hlsl::RWBuffer<int>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // SPV-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp1]],
// SPV-SAME: i32 noundef 13, i32 noundef 0, i32 noundef 5, i32 noundef 3, ptr noundef @[[BufB]])
// Make sure C[1] is translated to a RWBuffer<int>::__createFromBinding call with range 3 and index 1
// and DXIL explicit binding (u2, space0)
// and SPIR-V explicit binding (binding 2, set 0)
- // DXIL: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp2]],
+ // DXIL: call void @hlsl::RWBuffer<int>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // DXIL-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 4 %[[Tmp2]],
// DXIL-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
- // SPV: call void @_ZN4hlsl8RWBufferIiE19__createFromBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp2]],
+ // SPV: call void @hlsl::RWBuffer<int>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // SPV-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align 8 %[[Tmp2]],
// SPV-SAME: i32 noundef 2, i32 noundef 0, i32 noundef 3, i32 noundef 1, ptr noundef @[[BufC]])
// Make sure D[7] is translated to a RWBuffer<double>::__createFromImplicitBinding call
// for both DXIL and SPIR-V
- // DXIL: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 4 %[[Tmp3]],
- // DXIL-SAME: i32 noundef 1, i32 noundef 0, i32 noundef 10, i32 noundef 7, ptr noundef @D.str)
- // SPV: call void @_ZN4hlsl8RWBufferIdE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 8 %[[Tmp3]],
+ // DXIL: call void @hlsl::RWBuffer<double>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // DXIL-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 4 %[[Tmp3]],
+ // DXIL-SAME: i32 noundef 1, i32 noundef 0, i32 noundef 10, i32 noundef 7, ptr noundef @D.str)
+ // SPV: call void @hlsl::RWBuffer<double>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // SPV-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.1") align 8 %[[Tmp3]],
// SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 10, i32 noundef 7, ptr noundef @[[BufD]])
// Make sure E[5][0] is translated to RWBuffer<uint>::__createFromImplicitBinding call
// for both DXIL and SPIR-V with specified space/set 2
- // DXIL: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 4 %[[Tmp4]],
+ // DXIL: call void @hlsl::RWBuffer<unsigned int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // DXIL-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 4 %[[Tmp4]],
// DXIL-SAME: i32 noundef 2, i32 noundef 2, i32 noundef 15, i32 noundef 5, ptr noundef @[[BufE]])
- // SPV: call void @_ZN4hlsl8RWBufferIjE27__createFromImplicitBindingEjjijPKc(ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 8 %[[Tmp4]],
+ // SPV: call void @hlsl::RWBuffer<unsigned int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*)
+ // SPV-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.2") align 8 %[[Tmp4]],
// SPV-SAME: i32 noundef 1, i32 noundef 2, i32 noundef 15, i32 noundef 5, ptr noundef @[[BufE]])
Out[0] = A[2][0] + (float)B[3][0] + (float)C[1][0] + (float)D[7][0] + (float)E[5][0];
}
More information about the llvm-branch-commits
mailing list