diff --git a/clang/include/clang/AST/HLSLResource.h b/clang/include/clang/AST/HLSLResource.h index 7440050c7b2b9..1be1e422f5f12 100644 --- a/clang/include/clang/AST/HLSLResource.h +++ b/clang/include/clang/AST/HLSLResource.h @@ -74,6 +74,19 @@ struct ResourceBindingAttrs { assert(hasBinding() && !isExplicit() && !hasImplicitOrderID()); RegBinding->setImplicitBindingOrderID(Value); } + void setCounterImplicitOrderID(unsigned Value) const { + assert(hasBinding() && !hasCounterImplicitOrderID()); + RegBinding->setImplicitCounterBindingOrderID(Value); + } + + bool hasCounterImplicitOrderID() const { + return RegBinding && RegBinding->hasImplicitCounterBindingOrderID(); + } + + unsigned getCounterImplicitOrderID() const { + assert(hasCounterImplicitOrderID()); + return RegBinding->getImplicitCounterBindingOrderID(); + } }; } // namespace hlsl diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 3c697ed8dd882..3cde249e286fa 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4944,6 +4944,7 @@ def HLSLResourceBinding: InheritableAttr { std::optional SlotNumber; unsigned SpaceNumber; std::optional ImplicitBindingOrderID; + std::optional ImplicitCounterBindingOrderID; public: void setBinding(RegisterType RT, std::optional SlotNum, unsigned SpaceNum) { @@ -4976,6 +4977,17 @@ def HLSLResourceBinding: InheritableAttr { assert(hasImplicitBindingOrderID() && "attribute does not have implicit binding order id"); return ImplicitBindingOrderID.value(); } + void setImplicitCounterBindingOrderID(uint32_t Value) { + assert(!hasImplicitCounterBindingOrderID() && "attribute already has implicit counter binding order id"); + ImplicitCounterBindingOrderID = Value; + } + bool hasImplicitCounterBindingOrderID() const { + return ImplicitCounterBindingOrderID.has_value(); + } + uint32_t getImplicitCounterBindingOrderID() const { + assert(hasImplicitCounterBindingOrderID() && "attribute does not have implicit counter binding order id"); + return ImplicitCounterBindingOrderID.value(); + } }]; } diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 468121f7d20ab..792e2e07ec594 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4945,6 +4945,12 @@ def HLSLResourceHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLResourceCounterHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_resource_counterhandlefromimplicitbinding"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(...)"; +} + def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_nonuniformindex"]; let Attributes = [NoThrow]; diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 6c0fc8d7f07be..4f2f5a761f197 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -352,6 +352,19 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, SmallVector Args{OrderID, SpaceOp, RangeOp, IndexOp, Name}; return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args); } + case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: { + Value *MainHandle = EmitScalarExpr(E->getArg(0)); + if (!CGM.getTriple().isSPIRV()) + return MainHandle; + + llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType()); + Value *OrderID = EmitScalarExpr(E->getArg(1)); + Value *SpaceOp = EmitScalarExpr(E->getArg(2)); + llvm::Intrinsic::ID IntrinsicID = + llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding; + SmallVector Args{MainHandle, OrderID, SpaceOp}; + return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args); + } case Builtin::BI__builtin_hlsl_resource_nonuniformindex: { Value *IndexOp = EmitScalarExpr(E->getArg(0)); llvm::Type *RetTy = ConvertType(E->getType()); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index ede1780592bf5..603cef9116dc2 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -145,19 +145,29 @@ static CXXMethodDecl *lookupResourceInitMethodAndSetupArgs( // explicit binding auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, Binding.getSlot()); Args.add(RValue::get(RegSlot), AST.UnsignedIntTy); - CreateMethod = lookupMethod(ResourceDecl, "__createFromBinding", SC_Static); + const char *Name = Binding.hasCounterImplicitOrderID() + ? "__createFromBindingWithImplicitCounter" + : "__createFromBinding"; + CreateMethod = lookupMethod(ResourceDecl, Name, SC_Static); } else { // implicit binding auto *OrderID = llvm::ConstantInt::get(CGM.IntTy, Binding.getImplicitOrderID()); Args.add(RValue::get(OrderID), AST.UnsignedIntTy); - CreateMethod = - lookupMethod(ResourceDecl, "__createFromImplicitBinding", SC_Static); + const char *Name = Binding.hasCounterImplicitOrderID() + ? "__createFromImplicitBindingWithImplicitCounter" + : "__createFromImplicitBinding"; + CreateMethod = lookupMethod(ResourceDecl, Name, 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())); + if (Binding.hasCounterImplicitOrderID()) { + uint32_t CounterBinding = Binding.getCounterImplicitOrderID(); + auto *CounterOrderID = llvm::ConstantInt::get(CGM.IntTy, CounterBinding); + Args.add(RValue::get(CounterOrderID), AST.UnsignedIntTy); + } return CreateMethod; } diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 3c20ccd799b2d..40c318ae55427 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -144,6 +144,7 @@ struct BuiltinTypeMethodBuilder { _2, _3, _4, + _5, Handle = 128, CounterHandle, LastStmt @@ -190,6 +191,9 @@ struct BuiltinTypeMethodBuilder { template BuiltinTypeMethodBuilder & accessCounterHandleFieldOnResource(T ResourceRecord); + template + BuiltinTypeMethodBuilder & + setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue); template BuiltinTypeMethodBuilder &returnValue(T ReturnValue); BuiltinTypeMethodBuilder &returnThis(); BuiltinTypeDeclBuilder &finalize(); @@ -205,6 +209,11 @@ struct BuiltinTypeMethodBuilder { if (!Method) createDecl(); } + + template + BuiltinTypeMethodBuilder &setFieldOnResource(ResourceT ResourceRecord, + ValueT HandleValue, + FieldDecl *HandleField); }; TemplateParameterListBuilder::~TemplateParameterListBuilder() { @@ -592,13 +601,27 @@ template BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue) { + return setFieldOnResource(ResourceRecord, HandleValue, + DeclBuilder.getResourceHandleField()); +} + +template +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::setCounterHandleFieldOnResource( + ResourceT ResourceRecord, ValueT HandleValue) { + return setFieldOnResource(ResourceRecord, HandleValue, + DeclBuilder.getResourceCounterHandleField()); +} + +template +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::setFieldOnResource( + ResourceT ResourceRecord, ValueT HandleValue, FieldDecl *HandleField) { ensureCompleteDecl(); Expr *ResourceExpr = convertPlaceholder(ResourceRecord); Expr *HandleValueExpr = convertPlaceholder(HandleValue); ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); - FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit( AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, OK_Ordinary); @@ -829,6 +852,18 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { .finalize(); } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addStaticInitializationFunctions(bool HasCounter) { + if (HasCounter) { + addCreateFromBindingWithImplicitCounter(); + addCreateFromImplicitBindingWithImplicitCounter(); + } else { + addCreateFromBinding(); + addCreateFromImplicitBinding(); + } + return *this; +} + // Adds static method that initializes resource from binding: // // static Resource __createFromBinding(unsigned registerNo, @@ -903,6 +938,102 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCreateFromImplicitBinding() { .finalize(); } +// Adds static method that initializes resource from binding: +// +// static Resource +// __createFromBindingWithImplicitCounter(unsigned registerNo, +// unsigned spaceNo, int range, +// unsigned index, const char *name, +// unsigned counterOrderId) { +// Resource tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefrombinding( +// tmp.__handle, registerNo, spaceNo, range, index, name); +// tmp.__counter_handle = +// __builtin_hlsl_resource_counterhandlefromimplicitbinding( +// tmp.__handle, counterOrderId, spaceNo); +// return tmp; +// } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addCreateFromBindingWithImplicitCounter() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder(*this, + "__createFromBindingWithImplicitCounter", + RecordType, false, false, SC_Static) + .addParam("registerNo", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .addParam("counterOrderId", AST.UnsignedIntTy) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefrombinding", HandleType, + PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_counterhandlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_5, PH::_1) + .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + +// Adds static method that initializes resource from binding: +// +// static Resource +// __createFromImplicitBindingWithImplicitCounter(unsigned orderId, +// unsigned spaceNo, int range, +// unsigned index, +// const char *name, +// unsigned counterOrderId) { +// Resource tmp; +// tmp.__handle = __builtin_hlsl_resource_handlefromimplicitbinding( +// tmp.__handle, orderId, spaceNo, range, index, name); +// tmp.__counter_handle = +// __builtin_hlsl_resource_counterhandlefromimplicitbinding( +// tmp.__handle, counterOrderId, spaceNo); +// return tmp; +// } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addCreateFromImplicitBindingWithImplicitCounter() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + QualType RecordType = AST.getTypeDeclType(cast(Record)); + BuiltinTypeMethodBuilder::LocalVar TmpVar("tmp", RecordType); + + return BuiltinTypeMethodBuilder( + *this, "__createFromImplicitBindingWithImplicitCounter", + RecordType, false, false, SC_Static) + .addParam("orderId", AST.UnsignedIntTy) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("name", AST.getPointerType(AST.CharTy.withConst())) + .addParam("counterOrderId", AST.UnsignedIntTy) + .declareLocalVar(TmpVar) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_0, PH::_1, PH::_2, PH::_3, + PH::_4) + .setHandleFieldOnResource(TmpVar, PH::LastStmt) + .accessHandleFieldOnResource(TmpVar) + .callBuiltin("__builtin_hlsl_resource_counterhandlefromimplicitbinding", + HandleType, PH::LastStmt, PH::_5, PH::_1) + .setCounterHandleFieldOnResource(TmpVar, PH::LastStmt) + .returnValue(TmpVar) + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { assert(!Record->isCompleteDefinition() && "record is already complete"); @@ -1048,7 +1179,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() { return BuiltinTypeMethodBuilder(*this, "IncrementCounter", SemaRef.getASTContext().UnsignedIntTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(), - PH::Handle, getConstantIntExpr(1)) + PH::CounterHandle, getConstantIntExpr(1)) .finalize(); } @@ -1057,7 +1188,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() { return BuiltinTypeMethodBuilder(*this, "DecrementCounter", SemaRef.getASTContext().UnsignedIntTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", QualType(), - PH::Handle, getConstantIntExpr(-1)) + PH::CounterHandle, getConstantIntExpr(-1)) .finalize(); } @@ -1102,7 +1233,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() { return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy) .addParam("value", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, - PH::Handle, getConstantIntExpr(1)) + PH::CounterHandle, getConstantIntExpr(1)) .callBuiltin("__builtin_hlsl_resource_getpointer", AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::LastStmt) @@ -1119,7 +1250,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() { AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device); return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, - PH::Handle, getConstantIntExpr(-1)) + PH::CounterHandle, getConstantIntExpr(-1)) .callBuiltin("__builtin_hlsl_resource_getpointer", AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::LastStmt) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index a981602a50461..86cbd10e4cd6c 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -83,8 +83,7 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addCopyAssignmentOperator(); // Static create methods - BuiltinTypeDeclBuilder &addCreateFromBinding(); - BuiltinTypeDeclBuilder &addCreateFromImplicitBinding(); + BuiltinTypeDeclBuilder &addStaticInitializationFunctions(bool HasCounter); // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); @@ -96,6 +95,10 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addConsumeMethod(); private: + BuiltinTypeDeclBuilder &addCreateFromBinding(); + BuiltinTypeDeclBuilder &addCreateFromImplicitBinding(); + BuiltinTypeDeclBuilder &addCreateFromBindingWithImplicitCounter(); + BuiltinTypeDeclBuilder &addCreateFromImplicitBindingWithImplicitCounter(); BuiltinTypeDeclBuilder &addResourceMember(StringRef MemberName, ResourceClass RC, bool IsROV, bool RawBuffer, bool IsCounter, diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index cc43e9474ea79..e118dda4780e2 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -236,8 +236,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, .addDefaultHandleConstructor() .addCopyConstructor() .addCopyAssignmentOperator() - .addCreateFromBinding() - .addCreateFromImplicitBinding(); + .addStaticInitializationFunctions(HasCounter); } // This function is responsible for constructing the constraint expression for diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 09e5d69b39329..17cb1e4f153ca 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1240,6 +1240,20 @@ static CXXMethodDecl *lookupMethod(Sema &S, CXXRecordDecl *RecordDecl, } // end anonymous namespace +static bool hasCounterHandle(const CXXRecordDecl *RD) { + if (RD->field_empty()) + return false; + auto It = std::next(RD->field_begin()); + if (It == RD->field_end()) + return false; + const FieldDecl *SecondField = *It; + if (const auto *ResTy = + SecondField->getType()->getAs()) { + return ResTy->getAttrs().IsCounter; + } + return false; +} + bool SemaHLSL::handleRootSignatureElements( ArrayRef Elements) { // Define some common error handling functions @@ -2973,6 +2987,25 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ResourceTy); break; } + case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: { + ASTContext &AST = SemaRef.getASTContext(); + if (SemaRef.checkArgCount(TheCall, 3) || + CheckResourceHandle(&SemaRef, TheCall, 0) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.UnsignedIntTy)) + return true; + + QualType MainHandleTy = TheCall->getArg(0)->getType(); + auto *MainResType = MainHandleTy->getAs(); + auto MainAttrs = MainResType->getAttrs(); + assert(!MainAttrs.IsCounter && "cannot create a counter from a counter"); + MainAttrs.IsCounter = true; + QualType CounterHandleTy = AST.getHLSLAttributedResourceType( + MainResType->getWrappedType(), MainResType->getContainedType(), + MainAttrs); + TheCall->setType(CounterHandleTy); + break; + } case Builtin::BI__builtin_hlsl_and: case Builtin::BI__builtin_hlsl_or: { if (SemaRef.checkArgCount(TheCall, 2)) @@ -3780,10 +3813,24 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { uint32_t OrderID = getNextImplicitBindingOrderID(); if (Binding.hasBinding()) Binding.setImplicitOrderID(OrderID); - else + else { addImplicitBindingAttrToDecl( SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)), OrderID); + // Re-create the binding object to pick up the new attribute. + Binding = ResourceBindingAttrs(VD); + } + } + + // Get to the base type of a potentially multi-dimensional array. + QualType Ty = getASTContext().getBaseElementType(VD->getType()); + + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + if (hasCounterHandle(RD)) { + if (!Binding.hasCounterImplicitOrderID()) { + uint32_t OrderID = getNextImplicitBindingOrderID(); + Binding.setCounterImplicitOrderID(OrderID); + } } } } @@ -3808,19 +3855,31 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { CXXMethodDecl *CreateMethod = nullptr; llvm::SmallVector Args; + bool HasCounter = hasCounterHandle(ResourceDecl); + const char *CreateMethodName; + if (Binding.isExplicit()) + CreateMethodName = HasCounter ? "__createFromBindingWithImplicitCounter" + : "__createFromBinding"; + else + CreateMethodName = HasCounter + ? "__createFromImplicitBindingWithImplicitCounter" + : "__createFromImplicitBinding"; + + CreateMethod = + lookupMethod(SemaRef, ResourceDecl, CreateMethodName, VD->getLocation()); + + if (!CreateMethod) + // This can happen if someone creates a struct that looks like an HLSL + // resource record but does not have the required static create method. + // No binding will be generated for it. + return false; + if (Binding.isExplicit()) { - // The resource has explicit binding. - CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding", - VD->getLocation()); IntegerLiteral *RegSlot = IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSlot()), AST.UnsignedIntTy, SourceLocation()); Args.push_back(RegSlot); } else { - // The resource has implicit binding. - CreateMethod = - lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding", - VD->getLocation()); uint32_t OrderID = (Binding.hasImplicitOrderID()) ? Binding.getImplicitOrderID() : getNextImplicitBindingOrderID(); @@ -3830,12 +3889,6 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { Args.push_back(OrderId); } - if (!CreateMethod) - // This can happen if someone creates a struct that looks like an HLSL - // resource record but does not have the required static create method. - // No binding will be generated for it. - return false; - IntegerLiteral *Space = IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, Binding.getSpace()), AST.UnsignedIntTy, SourceLocation()); @@ -3859,6 +3912,15 @@ bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { Name, nullptr, VK_PRValue, FPOptionsOverride()); Args.push_back(NameCast); + if (HasCounter) { + // Will this be in the correct order? + uint32_t CounterOrderID = getNextImplicitBindingOrderID(); + IntegerLiteral *CounterId = + IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, CounterOrderID), + AST.UnsignedIntTy, SourceLocation()); + Args.push_back(CounterId); + } + // Make sure the create method template is instantiated and emitted. if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation()) SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod, @@ -3899,20 +3961,24 @@ bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) { ASTContext &AST = SemaRef.getASTContext(); QualType ResElementTy = AST.getBaseElementType(VD->getType()); CXXRecordDecl *ResourceDecl = ResElementTy->getAsCXXRecordDecl(); - - HLSLResourceBindingAttr *RBA = VD->getAttr(); - HLSLVkBindingAttr *VkBinding = VD->getAttr(); CXXMethodDecl *CreateMethod = nullptr; - if (VkBinding || (RBA && RBA->hasRegisterSlot())) + bool HasCounter = hasCounterHandle(ResourceDecl); + ResourceBindingAttrs ResourceAttrs(VD); + if (ResourceAttrs.isExplicit()) // Resource has explicit binding. - CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding", - VD->getLocation()); - else - // Resource has implicit binding. CreateMethod = - lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding", + lookupMethod(SemaRef, ResourceDecl, + HasCounter ? "__createFromBindingWithImplicitCounter" + : "__createFromBinding", VD->getLocation()); + else + // Resource has implicit binding. + CreateMethod = lookupMethod( + SemaRef, ResourceDecl, + HasCounter ? "__createFromImplicitBindingWithImplicitCounter" + : "__createFromImplicitBinding", + VD->getLocation()); if (!CreateMethod) return false; diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index 6779abb10bec4..e72207e10132c 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -4,7 +4,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT,CHECK-LOAD %s +// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT,CHECK-LOAD,CHECK-BINDING %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ @@ -141,59 +141,133 @@ RESOURCE Buffer; // Static __createFromBinding method -// CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static -// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' -// CHECK-NEXT: CompoundStmt -// CHECK-NEXT: DeclStmt -// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' -// CHECK-NEXT: ReturnStmt -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// CHECK-BINDING: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-BINDING-NEXT: CompoundStmt +// CHECK-BINDING-NEXT: DeclStmt +// CHECK-BINDING-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-BINDING-NEXT: ReturnStmt +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Static __createFromImplicitBinding method -// CHECK: CXXMethodDecl {{.*}} __createFromImplicitBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static -// CHECK-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' -// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' -// CHECK-NEXT: ParmVarDecl {{.*}} name 'const char *' -// CHECK-NEXT: CompoundStmt {{.*}} -// CHECK-NEXT: DeclStmt {{.*}} -// CHECK-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' -// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' -// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' -// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' -// CHECK-NEXT: ReturnStmt -// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' -// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// CHECK-BINDING: CXXMethodDecl {{.*}} __createFromImplicitBinding 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *)' static +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-BINDING-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-BINDING-NEXT: CompoundStmt {{.*}} +// CHECK-BINDING-NEXT: DeclStmt {{.*}} +// CHECK-BINDING-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-BINDING-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// CHECK-BINDING-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-BINDING-NEXT: ReturnStmt +// CHECK-BINDING-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-BINDING-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// CHECK-COUNTER-HANDLE: CXXMethodDecl {{.*}} __createFromBindingWithImplicitCounter 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' static +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} counterOrderId 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: CompoundStmt +// CHECK-COUNTER-HANDLE-NEXT: DeclStmt +// CHECK-COUNTER-HANDLE-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding' 'void (...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-COUNTER-HANDLE-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__counter_handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 'void (...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'counterOrderId' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ReturnStmt +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// CHECK-COUNTER-HANDLE: CXXMethodDecl {{.*}} __createFromImplicitBindingWithImplicitCounter 'hlsl::[[RESOURCE]] (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' static +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} orderId 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} name 'const char *' +// CHECK-COUNTER-HANDLE-NEXT: ParmVarDecl {{.*}} counterOrderId 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: CompoundStmt +// CHECK-COUNTER-HANDLE-NEXT: DeclStmt +// CHECK-COUNTER-HANDLE-NEXT: VarDecl {{.*}} tmp 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' 'void (...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'orderId' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *' +// CHECK-COUNTER-HANDLE-NEXT: BinaryOperator {{.*}} '__hlsl_resource_t {{.*}}]]' '=' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__counter_handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: CallExpr {{.*}} '__hlsl_resource_t {{.*}}' +// CHECK-COUNTER-HANDLE-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_counterhandlefromimplicitbinding' 'void (...) noexcept' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'counterOrderId' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-COUNTER-HANDLE-NEXT: ReturnStmt +// CHECK-COUNTER-HANDLE-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' +// CHECK-COUNTER-HANDLE-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline // Subscript operators @@ -263,7 +337,7 @@ RESOURCE Buffer; // CHECK-COUNTER-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__counter_handle // CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'hlsl::RWStructuredBuffer' lvalue implicit this // CHECK-COUNTER-NEXT: IntegerLiteral {{.*}} 'int' 1 // CHECK-COUNTER-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline @@ -279,7 +353,7 @@ RESOURCE Buffer; // CHECK-COUNTER-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__counter_handle // CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'hlsl::RWStructuredBuffer' lvalue implicit this // CHECK-COUNTER-NEXT: IntegerLiteral {{.*}} 'int' -1 // CHECK-COUNTER-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline @@ -305,7 +379,7 @@ RESOURCE Buffer; // CHECK-APPEND-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__counter_handle // CHECK-APPEND-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-APPEND-NEXT: IntegerLiteral {{.*}} 'int' 1 // CHECK-APPEND-NEXT: DeclRefExpr {{.*}} 'element_type' ParmVar {{.*}} 'value' 'element_type' @@ -330,7 +404,7 @@ RESOURCE Buffer; // CHECK-CONSUME-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__counter_handle // CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-CONSUME-NEXT: IntegerLiteral {{.*}} 'int' -1 diff --git a/clang/test/AST/HLSL/vk_binding_attr.hlsl b/clang/test/AST/HLSL/vk_binding_attr.hlsl index 13e7544eb672c..da5a42c2780a1 100644 --- a/clang/test/AST/HLSL/vk_binding_attr.hlsl +++ b/clang/test/AST/HLSL/vk_binding_attr.hlsl @@ -76,13 +76,13 @@ // CHECK: VarDecl {{.*}} Buf6 'RWStructuredBuffer':'hlsl::RWStructuredBuffer' // CHECK-NEXT: CallExpr {{.*}} 'RWStructuredBuffer':'hlsl::RWStructuredBuffer' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWStructuredBuffer (*)(unsigned int, unsigned int, int, unsigned int, const char *)' -// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *)' -// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWStructuredBuffer (*)(unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' +// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' +// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBindingwithImplicitCounter' 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 26 // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 105 -// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *)' -// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *)' +// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' +// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBindingwithImplicitCounter' 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *, unsigned int)' // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 4 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 // CHECK: HLSLVkBindingAttr {{.*}} 26 105 diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl index 89a66b047a3bd..96c2d950b50d7 100644 --- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl +++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl @@ -1,8 +1,7 @@ // 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 | \ -// llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | \ +// RUN: llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,CHECK-SPV // 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. @@ -24,52 +23,65 @@ export void foo() { // CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0), target("dx.RawBuffer", float, 1, 0) } // CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0), target("dx.RawBuffer", float, 1, 0) } -// CHECK: @Buf1 = internal global %"class.hlsl::StructuredBuffer" poison, align 4 +// CHECK: @Buf1 = internal global %"class.hlsl::StructuredBuffer" poison // CHECK: @[[Buf1Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf1\00", align 1 -// CHECK: @Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4 +// CHECK: @Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison // CHECK: @[[Buf2Str:.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00", align 1 // Buf1 initialization part 1 - global init function that calls StructuredBuffer::__createFromBinding // with explicit binding -// CHECK: define internal void @__cxx_global_var_init() +// CHECK: define internal {{.*}}void @__cxx_global_var_init() // CHECK-NEXT: entry: -// CHECK-NEXT: call void @hlsl::StructuredBuffer::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*) +// CHECK: call void @hlsl::StructuredBuffer::__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::::__createFromBinding // CHECK: define {{.*}} void @hlsl::StructuredBuffer::__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: ptr {{.*}} sret(%"class.hlsl::StructuredBuffer") align {{(4|8)}} %[[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 +// CHECK: %[[Tmp1:.*]] = alloca %"class.hlsl::StructuredBuffer" // 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: call void @hlsl::StructuredBuffer::StructuredBuffer(hlsl::StructuredBuffer const&)(ptr {{.*}} %[[RetValue1]], ptr {{.*}} %[[Tmp1]]) -// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer::__createFromImplicitBinding -// CHECK: define internal void @__cxx_global_var_init.1() +// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer::__createFromImplicitBindingWithImplicitCounter +// CHECK: define internal {{.*}}void @__cxx_global_var_init.1() // CHECK-NEXT: entry: -// CHECK-NEXT: call void @hlsl::RWStructuredBuffer::__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]]) +// CHECK: call void @hlsl::RWStructuredBuffer::__createFromImplicitBindingWithImplicitCounter(unsigned int, unsigned int, int, unsigned int, char const*, unsigned int) +// CHECK-SAME: (ptr {{.*}} @Buf2, i32 noundef 0, i32 noundef 0, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf2Str]], i32 noundef 1) -// Buf2 initialization part 2 - body of RWStructuredBuffer::__createFromImplicitBinding -// CHECK: define linkonce_odr hidden void @hlsl::RWStructuredBuffer::__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 +// Buf2 initialization part 2 - body of RWStructuredBuffer::__createFromImplicitBindingWithImplicitCounter +// CHECK: define linkonce_odr hidden void @hlsl::RWStructuredBuffer::__createFromImplicitBindingWithImplicitCounter(unsigned int, unsigned int, int, unsigned int, char const*, unsigned int) +// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align {{(4|8)}} %[[RetValue2:.*]], i32 noundef %orderId, +// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name, i32 noundef %counterOrderId) +// CHECK: %[[Tmp2:.*]] = alloca %"class.hlsl::RWStructuredBuffer" // 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: %[[HandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0 +// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %[[Handle2]], ptr %[[HandlePtr]], align 4 +// CHECK-DXIL: %[[HandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0 +// CHECK-DXIL: %[[LoadedHandle:.*]] = load target("dx.RawBuffer", float, 1, 0), ptr %[[HandlePtr]], align 4 +// CHECK-DXIL: %[[CounterHandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 1 +// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 1, 0) %[[LoadedHandle]], ptr %[[CounterHandlePtr]], align 4 +// CHECK-SPV: %[[Handle2:.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 1) +// CHECK-SPV-SAME: @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0f32_12_1t( +// CHECK-SPV: %[[HandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0 +// CHECK-SPV-NEXT: store target("spirv.VulkanBuffer", [0 x float], 12, 1) %[[Handle2]], ptr %[[HandlePtr]], align 8 +// CHECK-SPV: %[[HandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0 +// CHECK-SPV: %[[LoadedHandle:.*]] = load target("spirv.VulkanBuffer", [0 x float], 12, 1), ptr %[[HandlePtr]], align 8 +// CHECK-SPV: %[[CounterHandle:.*]] = call target("spirv.VulkanBuffer", i32, 12, 1) @llvm.spv.resource.counterhandlefromimplicitbinding +// CHECK-SPV: %[[CounterHandlePtr:.*]] = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 1 +// CHECK-SPV-NEXT: store target("spirv.VulkanBuffer", i32, 12, 1) %[[CounterHandle]], ptr %[[CounterHandlePtr]], align 8 // CHECK: call void @hlsl::RWStructuredBuffer::RWStructuredBuffer(hlsl::RWStructuredBuffer const&)(ptr {{.*}} %[[RetValue2]], ptr {{.*}} %[[Tmp2]]) // Buf3 initialization part 1 - local variable declared in function foo() is initialized by // AppendStructuredBuffer C1 default constructor -// CHECK: define void @foo() +// CHECK: define {{.*}}void @foo() // CHECK-NEXT: entry: -// CHECK-NEXT: %Buf3 = alloca %"class.hlsl::AppendStructuredBuffer", align 4 +// CHECK: %Buf3 = alloca %"class.hlsl::AppendStructuredBuffer", align {{4|8}} // CHECK-NEXT: call void @hlsl::AppendStructuredBuffer::AppendStructuredBuffer()(ptr {{.*}} %Buf3) // Buf3 initialization part 2 - body of AppendStructuredBuffer default C1 constructor that calls @@ -84,7 +96,7 @@ export void foo() { // 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() +// CHECK: define internal {{.*}}void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl() // CHECK-NEXT: entry: -// CHECK-NEXT: call void @__cxx_global_var_init() -// CHECK-NEXT: call void @__cxx_global_var_init.1() +// CHECK: call {{.*}}void @__cxx_global_var_init() +// CHECK-NEXT: call {{.*}}void @__cxx_global_var_init.1() diff --git a/clang/test/CodeGenHLSL/resources/res-array-rw-counter.hlsl b/clang/test/CodeGenHLSL/resources/res-array-rw-counter.hlsl new file mode 100644 index 0000000000000..c3d5784184fca --- /dev/null +++ b/clang/test/CodeGenHLSL/resources/res-array-rw-counter.hlsl @@ -0,0 +1,26 @@ +// 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 spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPV + +// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0), target("dx.RawBuffer", float, 1, 0) } +// CHECK-SPV: %"class.hlsl::RWStructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x float], 12, 1), target("spirv.VulkanBuffer", i32, 12, 1) } + +RWStructuredBuffer BufArray[4]; + +export void foo(int idx) { + BufArray[0].IncrementCounter(); + BufArray[idx].DecrementCounter(); +} + +// CHECK: @[[BufArrayStr:.*]] = private unnamed_addr constant [9 x i8] c"BufArray\00", align 1 + +// CHECK: define {{.*}}void @_Z3fooi(i32 noundef %[[IDX_ARG:.*]]) +// CHECK-NEXT: entry: +// CHECK: %[[IDX_ADDR:.*]] = alloca i32 +// CHECK: [[TMP_INC:%.*]] = alloca %"class.hlsl::RWStructuredBuffer" +// CHECK: [[TMP_DEC:%.*]] = alloca %"class.hlsl::RWStructuredBuffer" +// CHECK: store i32 %[[IDX_ARG]], ptr %[[IDX_ADDR]] +// CHECK: call void @_ZN4hlsl18RWStructuredBufferIfE46__createFromImplicitBindingWithImplicitCounterEjjijPKcj(ptr {{.*}} [[TMP_INC]], i32 noundef 0, i32 noundef 0, i32 noundef 4, i32 noundef 0, ptr noundef @[[BufArrayStr]], i32 noundef 1) +// CHECK: call noundef i32 @_ZN4hlsl18RWStructuredBufferIfE16IncrementCounterEv(ptr {{.*}} [[TMP_INC]]) +// CHECK: %[[IDX_LOADED:.*]] = load i32, ptr %[[IDX_ADDR]] +// CHECK: call void @_ZN4hlsl18RWStructuredBufferIfE46__createFromImplicitBindingWithImplicitCounterEjjijPKcj(ptr {{.*}} [[TMP_DEC]], i32 noundef 0, i32 noundef 0, i32 noundef 4, i32 noundef %[[IDX_LOADED]], ptr noundef @[[BufArrayStr]], i32 noundef 1) +// CHECK: call noundef i32 @_ZN4hlsl18RWStructuredBufferIfE16DecrementCounterEv(ptr {{.*}} [[TMP_DEC]]) \ No newline at end of file diff --git a/clang/test/CodeGenHLSL/vk_binding_attr.hlsl b/clang/test/CodeGenHLSL/vk_binding_attr.hlsl index bbef05130116d..45955e1327a53 100644 --- a/clang/test/CodeGenHLSL/vk_binding_attr.hlsl +++ b/clang/test/CodeGenHLSL/vk_binding_attr.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-library -finclude-default-header -O3 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-compute -finclude-default-header -O3 -emit-llvm -o - %s | FileCheck %s // CHECK: [[Buf:@.*]] = private unnamed_addr constant [4 x i8] c"Buf\00" // CHECK: [[Buf2:@.*]] = private unnamed_addr constant [5 x i8] c"Buf2\00" // CHECK: [[Buf3:@.*]] = private unnamed_addr constant [5 x i8] c"Buf3\00"