llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Steven Perron (s-perron) <details> <summary>Changes</summary> This is part 1 of implementing the typed buffer counters proposal: https://github.com/llvm/wg-hlsl/blob/main/proposals/0023-typed-buffer-counters.md This patch adds the initial plumbing for supporting counter variables associated with structured buffers for the SPIR-V backend. It introduces an `IsCounter` attribute to `HLSLAttributedResourceType` and threads it through the AST, type printing, and mangling. It also adds a `__counter_handle` member to the relevant buffer types in `HLSLBuiltinTypeDeclBuilder`. --- Patch is 30.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161414.diff 17 Files Affected: - (modified) clang/include/clang/AST/TypeBase.h (+12-5) - (modified) clang/include/clang/AST/TypeProperties.td (+4-1) - (modified) clang/include/clang/Basic/Attr.td (+6) - (modified) clang/lib/AST/ItaniumMangle.cpp (+2) - (modified) clang/lib/AST/TypePrinter.cpp (+3) - (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+6) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+121-11) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+4) - (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+18-3) - (modified) clang/lib/Sema/SemaHLSL.cpp (+11) - (modified) clang/test/AST/HLSL/StructuredBuffers-AST.hlsl (+18-3) - (modified) clang/test/CodeGenHLSL/resources/RWStructuredBuffer-elementtype.hlsl (+17-17) - (modified) clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl (+2-2) - (modified) clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl (+3-3) - (modified) clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl (+1-1) - (modified) clang/test/CodeGenHLSL/resources/resource-bindings.hlsl (+1-1) - (modified) llvm/lib/Target/SPIRV/SPIRVLegalizeImplicitBinding.cpp (+1-1) ``````````diff diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index b02d9c7499fe5..b60ef6911d84a 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -6700,15 +6700,21 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode { LLVM_PREFERRED_TYPE(bool) uint8_t RawBuffer : 1; + LLVM_PREFERRED_TYPE(bool) + uint8_t IsCounter : 1; + Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV = false, - bool RawBuffer = false) - : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {} + bool RawBuffer = false, bool IsCounter = false) + : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer), + IsCounter(IsCounter) {} - Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {} + Attributes() + : Attributes(llvm::dxil::ResourceClass::UAV, false, false, false) {} friend bool operator==(const Attributes &LHS, const Attributes &RHS) { - return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer) == - std::tie(RHS.ResourceClass, RHS.IsROV, RHS.RawBuffer); + return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer, + LHS.IsCounter) == std::tie(RHS.ResourceClass, RHS.IsROV, + RHS.RawBuffer, RHS.IsCounter); } friend bool operator!=(const Attributes &LHS, const Attributes &RHS) { return !(LHS == RHS); @@ -6749,6 +6755,7 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode { ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass)); ID.AddBoolean(Attrs.IsROV); ID.AddBoolean(Attrs.RawBuffer); + ID.AddBoolean(Attrs.IsCounter); } static bool classof(const Type *T) { diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index b3932a67db69d..9dc85fb88e267 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -662,6 +662,9 @@ let Class = HLSLAttributedResourceType in { def : Property<"rawBuffer", Bool> { let Read = [{ node->getAttrs().RawBuffer }]; } + def : Property<"isCounter", Bool> { + let Read = [{ node->getAttrs().IsCounter }]; + } def : Property<"wrappedTy", QualType> { let Read = [{ node->getWrappedType() }]; } @@ -669,7 +672,7 @@ let Class = HLSLAttributedResourceType in { let Read = [{ node->getContainedType() }]; } def : Creator<[{ - HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer); + HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer, isCounter); return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs); }]>; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 2623f9ff6972f..1d6f4e809a1fa 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -5059,6 +5059,12 @@ def HLSLRawBuffer : TypeAttr { let Documentation = [InternalOnly]; } +def HLSLIsCounter : TypeAttr { + let Spellings = [CXX11<"hlsl", "is_counter">]; + let LangOpts = [HLSL]; + let Documentation = [InternalOnly]; +} + def HLSLGroupSharedAddressSpace : TypeAttr { let Spellings = [CustomKeyword<"groupshared">]; let Subjects = SubjectList<[Var]>; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 2173aed5b45af..844db79f18a4a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4624,6 +4624,8 @@ void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) { Str += "_ROV"; if (Attrs.RawBuffer) Str += "_Raw"; + if (Attrs.IsCounter) + Str += "_Counter"; if (T->hasContainedType()) Str += "_CT"; mangleVendorQualifier(Str); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index cd59678d67f2f..b2ba569843897 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2033,6 +2033,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::HLSLROV: case attr::HLSLRawBuffer: case attr::HLSLContainedType: + case attr::HLSLIsCounter: llvm_unreachable("HLSL resource type attributes handled separately"); case attr::OpenCLPrivateAddressSpace: @@ -2181,6 +2182,8 @@ void TypePrinter::printHLSLAttributedResourceAfter( OS << " [[hlsl::is_rov]]"; if (Attrs.RawBuffer) OS << " [[hlsl::raw_buffer]]"; + if (Attrs.IsCounter) + OS << " [[hlsl::is_counter]]"; QualType ContainedTy = T->getContainedType(); if (!ContainedTy.isNull()) { diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 2e3fc53c58edc..4aa63143a66cd 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -486,6 +486,12 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType( return getSPIRVImageTypeFromHLSLResource(ResAttrs, ContainedTy, CGM); } + if (ResAttrs.IsCounter) { + llvm::Type *ElemType = llvm::Type::getInt32Ty(Ctx); + uint32_t StorageClass = /* StorageBuffer storage class */ 12; + return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer", {ElemType}, + {StorageClass, true}); + } llvm::Type *ElemType = CGM.getTypes().ConvertTypeForMem(ContainedTy); llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0); uint32_t StorageClass = /* StorageBuffer storage class */ 12; diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 5eafd03d89efe..847f4a26c8788 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -138,7 +138,16 @@ struct BuiltinTypeMethodBuilder { // LastStmt - refers to the last statement in the method body; referencing // LastStmt will remove the statement from the method body since // it will be linked from the new expression being constructed. - enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt }; + enum class PlaceHolder { + _0, + _1, + _2, + _3, + _4, + Handle = 128, + CounterHandle, + LastStmt + }; Expr *convertPlaceholder(PlaceHolder PH); Expr *convertPlaceholder(LocalVar &Var); @@ -178,10 +187,17 @@ struct BuiltinTypeMethodBuilder { template <typename ResourceT, typename ValueT> BuiltinTypeMethodBuilder &setHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue); + template <typename T> + BuiltinTypeMethodBuilder & + accessCounterHandleFieldOnResource(T ResourceRecord); + template <typename ResourceT, typename ValueT> + BuiltinTypeMethodBuilder & + setCounterHandleFieldOnResource(ResourceT ResourceRecord, ValueT HandleValue); template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue); BuiltinTypeMethodBuilder &returnThis(); BuiltinTypeDeclBuilder &finalize(); Expr *getResourceHandleExpr(); + Expr *getResourceCounterHandleExpr(); private: void createDecl(); @@ -346,6 +362,8 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) { Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { if (PH == PlaceHolder::Handle) return getResourceHandleExpr(); + if (PH == PlaceHolder::CounterHandle) + return getResourceCounterHandleExpr(); if (PH == PlaceHolder::LastStmt) { assert(!StmtsList.empty() && "no statements in the list"); @@ -467,6 +485,18 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() { OK_Ordinary); } +Expr *BuiltinTypeMethodBuilder::getResourceCounterHandleExpr() { + ensureCompleteDecl(); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + CXXThisExpr *This = CXXThisExpr::Create( + AST, SourceLocation(), Method->getFunctionObjectParameterType(), true); + FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField(); + return MemberExpr::CreateImplicit(AST, This, false, HandleField, + HandleField->getType(), VK_LValue, + OK_Ordinary); +} + BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::declareLocalVar(LocalVar &Var) { ensureCompleteDecl(); @@ -583,6 +613,44 @@ BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord, return *this; } +template <typename T> +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::accessCounterHandleFieldOnResource(T ResourceRecord) { + ensureCompleteDecl(); + + Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField(); + MemberExpr *HandleExpr = MemberExpr::CreateImplicit( + AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + StmtsList.push_back(HandleExpr); + return *this; +} + +template <typename ResourceT, typename ValueT> +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::setCounterHandleFieldOnResource( + ResourceT ResourceRecord, ValueT HandleValue) { + ensureCompleteDecl(); + + Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + Expr *HandleValueExpr = convertPlaceholder(HandleValue); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField(); + MemberExpr *HandleMemberExpr = MemberExpr::CreateImplicit( + AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + Stmt *AssignStmt = BinaryOperator::Create( + DeclBuilder.SemaRef.getASTContext(), HandleMemberExpr, HandleValueExpr, + BO_Assign, HandleMemberExpr->getType(), ExprValueKind::VK_PRValue, + ExprObjectKind::OK_Ordinary, SourceLocation(), FPOptionsOverride()); + StmtsList.push_back(AssignStmt); + return *this; +} + template <typename T> BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) { ensureCompleteDecl(); @@ -745,6 +813,30 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember( return *this; } +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember( + ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + ASTContext &Ctx = SemaRef.getASTContext(); + TypeSourceInfo *ElementTypeInfo = + Ctx.getTrivialTypeSourceInfo(getHandleElementType(), SourceLocation()); + + // add handle member with resource type attributes + QualType AttributedResTy = QualType(); + SmallVector<const Attr *> Attrs = { + HLSLResourceClassAttr::CreateImplicit(Ctx, RC), + IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr, + RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr, + ElementTypeInfo + ? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo) + : nullptr, + HLSLIsCounterAttr::CreateImplicit(Ctx)}; + if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs, + AttributedResTy)) + addMemberVariable("__counter_handle", AttributedResTy, {}, Access); + return *this; +} + // Adds default constructor to the resource class: // Resource::Resource() BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDefaultHandleConstructor() { @@ -848,12 +940,18 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { using PH = BuiltinTypeMethodBuilder::PlaceHolder; - return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy, - /*IsConst=*/false, /*IsCtor=*/true) - .addParam("other", ConstRecordRefType) + BuiltinTypeMethodBuilder MMB(*this, /*Name=*/"", AST.VoidTy, + /*IsConst=*/false, /*IsCtor=*/true); + MMB.addParam("other", ConstRecordRefType) .accessHandleFieldOnResource(PH::_0) - .assign(PH::Handle, PH::LastStmt) - .finalize(); + .assign(PH::Handle, PH::LastStmt); + + if (getResourceCounterHandleField()) { + MMB.accessCounterHandleFieldOnResource(PH::_0).assign(PH::CounterHandle, + PH::LastStmt); + } + + return MMB.finalize(); } BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() { @@ -868,12 +966,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() { using PH = BuiltinTypeMethodBuilder::PlaceHolder; DeclarationName Name = AST.DeclarationNames.getCXXOperatorName(OO_Equal); - return BuiltinTypeMethodBuilder(*this, Name, RecordRefType) - .addParam("other", ConstRecordRefType) + BuiltinTypeMethodBuilder MMB(*this, Name, RecordRefType); + MMB.addParam("other", ConstRecordRefType) .accessHandleFieldOnResource(PH::_0) - .assign(PH::Handle, PH::LastStmt) - .returnThis() - .finalize(); + .assign(PH::Handle, PH::LastStmt); + + if (getResourceCounterHandleField()) { + MMB.accessCounterHandleFieldOnResource(PH::_0).assign(PH::CounterHandle, + PH::LastStmt); + } + + return MMB.returnThis().finalize(); } BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() { @@ -909,6 +1012,13 @@ FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const { return I->second; } +FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField() const { + auto I = Fields.find("__counter_handle"); + if (I == Fields.end()) + return nullptr; + return I->second; +} + QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() { assert(Template && "record it not a template"); if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>( diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index 9448af13530cb..a62088e0ef551 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -74,6 +74,9 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder & addHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access = AccessSpecifier::AS_private); + BuiltinTypeDeclBuilder & + addCounterHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer, + AccessSpecifier Access = AccessSpecifier::AS_private); BuiltinTypeDeclBuilder &addArraySubscriptOperators(); // Builtin types constructors @@ -96,6 +99,7 @@ class BuiltinTypeDeclBuilder { private: FieldDecl *getResourceHandleField() const; + FieldDecl *getResourceCounterHandleField() const; QualType getFirstTemplateTypeParam(); QualType getHandleElementType(); Expr *getConstantIntExpr(int value); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 781f0445d0b61..650ad386f074b 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -126,16 +126,31 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() { } /// Set up common members and attributes for buffer types +static bool resourceHasCounter(const CXXRecordDecl *Decl) { + StringRef Name = Decl->getName(); + return Name == "RWStructuredBuffer" || Name == "AppendStructuredBuffer" || + Name == "ConsumeStructuredBuffer"; +} + static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, bool IsROV, bool RawBuffer) { - return BuiltinTypeDeclBuilder(S, Decl) - .addHandleMember(RC, IsROV, RawBuffer) - .addDefaultHandleConstructor() + // TODO: This should be cleaned up. We should have a function + // addCounterHandleMembers that will add the main handle, and if necessary add + // the counter handle. + BuiltinTypeDeclBuilder BTB(S, Decl); + BTB.addHandleMember(RC, IsROV, RawBuffer); + + if (resourceHasCounter(Decl)) { + BTB.addCounterHandleMember(RC, IsROV, RawBuffer); + } + + BTB.addDefaultHandleConstructor() .addCopyConstructor() .addCopyAssignmentOperator() .addCreateFromBinding() .addCreateFromImplicitBinding(); + return BTB; } // 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 55be036207eec..190d2dec8758a 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1811,6 +1811,13 @@ bool clang::CreateHLSLAttributedResourceType( } ResAttrs.RawBuffer = true; break; + case attr::HLSLIsCounter: + if (ResAttrs.IsCounter) { + S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A; + return false; + } + ResAttrs.IsCounter = true; + break; case attr::HLSLContainedType: { const HLSLContainedTypeAttr *CTAttr = cast<HLSLContainedTypeAttr>(A); QualType Ty = CTAttr->getType(); @@ -1903,6 +1910,10 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) { A = HLSLRawBufferAttr::Create(getASTContext(), ACI); break; + case ParsedAttr::AT_HLSLIsCounter: + A = HLSLIsCounterAttr::Create(getASTContext(), ACI); + break; + case ParsedAttr::AT_HLSLContainedType: { if (AL.getNumArgs() != 1 && !AL.hasParsedType()) { Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1; diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index a490b22ab437b..a0cad2c7f1e8b 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -12,7 +12,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-COUNTER,CHECK-LOAD %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-COUNTER,CHECK-LOAD,CHECK-COUNTER-HANDLE %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ @@ -20,7 +20,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-APPEND %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-APPEND,CHECK-COUNTER-HANDLE %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ @@ -28,7 +28,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-CONSUME %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-CONSUME,CHECK-COUNTER-HANDLE %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ @@ -113,6 +113,11 @@ RESOURCE<float> Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle // CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]]<element_type> &' +// CHECK-COUNTER-HANDLE-NEXT: BinaryOperator {{.*}} '=' +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} lvalue .__counter_handle +// CHECK-COUNTER-HANDLE-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-COUNTER-HANDLE-NEXT: MemberExpr {{.*}} lvalu... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/161414 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
