llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-hlsl Author: Kaitlin Peng (kmpeng) <details> <summary>Changes</summary> Closes #<!-- -->108058. This PR adds the `uint` `Load` and `Store` methods (`Load`, `Load2`, `Load3`, `Load4`, `Store`, `Store2`, `Store3`, `Store4`) to the existing `ByteAddressBuffer` and `RWByteAddressBuffer` objects , as well as the new templated `Load` and `Store` methods, allowing types other than `uint` (e.g. aggregate types) to be used directly. --- Patch is 48.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/176058.diff 10 Files Affected: - (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+3) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+124-3) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+2) - (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+3) - (modified) clang/lib/Sema/SemaHLSL.cpp (+20-2) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+14-2) - (modified) clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl (+216-3) - (modified) clang/test/AST/HLSL/StructuredBuffers-AST.hlsl (+5-5) - (modified) clang/test/AST/HLSL/TypedBuffers-AST.hlsl (+3-3) - (modified) clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl (+160) ``````````diff diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 1b6c3714f7821..98708f23a35e6 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -432,6 +432,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, if (RT->getAttrs().RawBuffer) { Value *Offset = Builder.getInt32(0); + // Offset is poison for ByteAddressBuffer + if (RT->getContainedType()->isChar8Type()) + Offset = llvm::PoisonValue::get(Builder.getInt32Ty()); Args.push_back(Offset); } diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 868f894a03c49..fea27d487526c 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -153,6 +153,8 @@ struct BuiltinTypeMethodBuilder { StorageClass SC; llvm::SmallVector<Param> Params; llvm::SmallVector<Stmt *> StmtsList; + TemplateParameterList *TemplateParams; + llvm::SmallVector<NamedDecl *> TemplateParamDecls; // Argument placeholders, inspired by std::placeholder. These are the indices // of arguments to forward to `callBuiltin` and other method builder methods. @@ -184,7 +186,7 @@ struct BuiltinTypeMethodBuilder { QualType ReturnTy, bool IsConst = false, bool IsCtor = false, StorageClass SC = SC_None) : DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr), - IsConst(IsConst), IsCtor(IsCtor), SC(SC) {} + IsConst(IsConst), IsCtor(IsCtor), SC(SC), TemplateParams(nullptr) {} BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr, QualType ReturnTy, bool IsConst = false, @@ -199,6 +201,7 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty, HLSLParamModifierAttr::Spelling Modifier = HLSLParamModifierAttr::Keyword_in); + QualType addTemplateTypeParam(StringRef Name); BuiltinTypeMethodBuilder &declareLocalVar(LocalVar &Var); template <typename... Ts> BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName, @@ -449,6 +452,22 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty, Params.emplace_back(II, Ty, Modifier); return *this; } +QualType BuiltinTypeMethodBuilder::addTemplateTypeParam(StringRef Name) { + assert(Method == nullptr && + "Cannot add template param, method already created"); + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + unsigned Position = static_cast<unsigned>(TemplateParamDecls.size()); + auto *Decl = TemplateTypeParmDecl::Create( + AST, DeclBuilder.Record, SourceLocation(), SourceLocation(), + /* TemplateDepth */ 0, Position, + &AST.Idents.get(Name, tok::TokenKind::identifier), + /* Typename */ true, + /* ParameterPack */ false, + /* HasTypeConstraint*/ false); + TemplateParamDecls.emplace_back(Decl); + + return QualType(Decl->getTypeForDecl(), 0); +} void BuiltinTypeMethodBuilder::createDecl() { assert(Method == nullptr && "Method or constructor is already created"); @@ -615,7 +634,7 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::dereference(T Ptr) { Expr *Deref = UnaryOperator::Create(DeclBuilder.SemaRef.getASTContext(), PtrExpr, UO_Deref, PtrExpr->getType()->getPointeeType(), - VK_PRValue, OK_Ordinary, SourceLocation(), + VK_LValue, OK_Ordinary, SourceLocation(), /*CanOverflow=*/false, FPOptionsOverride()); StmtsList.push_back(Deref); return *this; @@ -747,7 +766,22 @@ BuiltinTypeDeclBuilder &BuiltinTypeMethodBuilder::finalize() { Method->setAccess(AS_public); Method->addAttr(AlwaysInlineAttr::CreateImplicit( AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline)); - DeclBuilder.Record->addDecl(Method); + if (!TemplateParamDecls.empty()) { + TemplateParams = TemplateParameterList::Create( + AST, SourceLocation(), SourceLocation(), TemplateParamDecls, + SourceLocation(), nullptr); + + auto *FuncTemplate = FunctionTemplateDecl::Create(AST, DeclBuilder.Record, + SourceLocation(), Name, + TemplateParams, Method); + FuncTemplate->setAccess(AS_public); + FuncTemplate->setLexicalDeclContext(DeclBuilder.Record); + FuncTemplate->setImplicit(true); + Method->setDescribedFunctionTemplate(FuncTemplate); + DeclBuilder.Record->addDecl(FuncTemplate); + } else { + DeclBuilder.Record->addDecl(Method); + } } return DeclBuilder; } @@ -1145,6 +1179,93 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() { return *this; } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + + auto addLoadMethod = [&](StringRef MethodName, QualType ReturnType) { + IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier); + DeclarationName Load(&II); + + // Load without status + BuiltinTypeMethodBuilder MMB(*this, Load, ReturnType); + if (ReturnType->isDependentType()) { + ReturnType = MMB.addTemplateTypeParam("element_type"); + MMB.ReturnTy = ReturnType; // Update return type to template parameter + } + QualType AddrSpaceElemTy = + AST.getAddrSpaceQualType(ReturnType, LangAS::hlsl_device); + + MMB.addParam("Index", AST.UnsignedIntTy) + .callBuiltin("__builtin_hlsl_resource_getpointer", + AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::_0) + .dereference(PH::LastStmt) + .finalize(); + + // Load with status + BuiltinTypeMethodBuilder MMB2(*this, Load, ReturnType); + if (ReturnType->isDependentType()) { + ReturnType = MMB2.addTemplateTypeParam("element_type"); + MMB2.ReturnTy = ReturnType; // Update return type to template parameter + } + + MMB2.addParam("Index", AST.UnsignedIntTy) + .addParam("Status", AST.UnsignedIntTy, + HLSLParamModifierAttr::Keyword_out) + .callBuiltin("__builtin_hlsl_resource_load_with_status", ReturnType, + PH::Handle, PH::_0, PH::_1) + .finalize(); + }; + + addLoadMethod("Load", AST.UnsignedIntTy); + addLoadMethod("Load2", AST.getExtVectorType(AST.UnsignedIntTy, 2)); + addLoadMethod("Load3", AST.getExtVectorType(AST.UnsignedIntTy, 3)); + addLoadMethod("Load4", AST.getExtVectorType(AST.UnsignedIntTy, 4)); + addLoadMethod("Load", AST.DependentTy); // Templated version + + return *this; +} + +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addByteAddressBufferStoreMethods() { + assert(!Record->isCompleteDefinition() && "record is already complete"); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + + // Helper to add uint Store methods + auto addStoreMethod = [&](StringRef MethodName, QualType ValueType) { + IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier); + DeclarationName Store(&II); + + BuiltinTypeMethodBuilder MMB(*this, Store, AST.VoidTy); + if (ValueType->isDependentType()) { + ValueType = MMB.addTemplateTypeParam("element_type"); + } + QualType AddrSpaceElemTy = + AST.getAddrSpaceQualType(ValueType, LangAS::hlsl_device); + + MMB.addParam("Index", AST.UnsignedIntTy) + .addParam("Value", ValueType) + .callBuiltin("__builtin_hlsl_resource_getpointer", + AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::_0) + .dereference(PH::LastStmt) + .assign(PH::LastStmt, PH::_1) + .finalize(); + }; + + addStoreMethod("Store", AST.UnsignedIntTy); + addStoreMethod("Store2", AST.getExtVectorType(AST.UnsignedIntTy, 2)); + addStoreMethod("Store3", AST.getExtVectorType(AST.UnsignedIntTy, 3)); + addStoreMethod("Store4", AST.getExtVectorType(AST.UnsignedIntTy, 4)); + addStoreMethod("Store", AST.DependentTy); // Templated version + + return *this; +} + FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const { auto I = Fields.find("__handle"); assert(I != Fields.end() && diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index 47c8b0e225612..8309ba990fda0 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -87,6 +87,8 @@ class BuiltinTypeDeclBuilder { // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); + BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods(); + BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods(); BuiltinTypeDeclBuilder &addIncrementCounterMethod(); BuiltinTypeDeclBuilder &addDecrementCounterMethod(); BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name, diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 6be84f19a8f08..948005312f4dd 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -480,6 +480,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false, /*RawBuffer=*/true, /*HasCounter=*/false) + .addByteAddressBufferLoadMethods() .addGetDimensionsMethodForBuffer() .completeDefinition(); }); @@ -488,6 +489,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false, /*RawBuffer=*/true, /*HasCounter=*/false) + .addByteAddressBufferLoadMethods() + .addByteAddressBufferStoreMethods() .addGetDimensionsMethodForBuffer() .completeDefinition(); }); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index f15b274a65a53..a705e5d9792f3 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -3308,9 +3308,22 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { auto *ResourceTy = TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>(); - QualType ContainedTy = ResourceTy->getContainedType(); + QualType ElementTy = ResourceTy->getContainedType(); + // ByteAddressBuffer uses the FunctionDecl types instead of the contained + // type + if (ResourceTy->getAttrs().RawBuffer && ElementTy->isChar8Type()) { + // Load method uses return type + FunctionDecl *FD = dyn_cast<FunctionDecl>(SemaRef.CurContext); + ElementTy = FD->getReturnType(); + // Store method uses 2nd parameter type + if (ElementTy->isVoidType()) { + assert(FD->getNumParams() == 2 && + "expected 2 parameters for Store method"); + ElementTy = FD->getParamDecl(1)->getType(); + } + } auto ReturnType = - SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device); + SemaRef.Context.getAddrSpaceQualType(ElementTy, LangAS::hlsl_device); ReturnType = SemaRef.Context.getPointerType(ReturnType); TheCall->setType(ReturnType); TheCall->setValueKind(VK_LValue); @@ -3330,6 +3343,11 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { auto *ResourceTy = TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>(); QualType ReturnType = ResourceTy->getContainedType(); + // ByteAddressBuffer uses the FunctionDecl return type instead of the + // contained type + if (ResourceTy->getAttrs().RawBuffer && ReturnType->isChar8Type()) { + ReturnType = dyn_cast<FunctionDecl>(SemaRef.CurContext)->getReturnType(); + } TheCall->setType(ReturnType); break; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e74c41517ecbf..348ac5e75af7c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -6901,8 +6901,20 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // whose type is not instantiation dependent, do nothing to the decl // - otherwise find its instantiated decl. if (isa<ParmVarDecl>(D) && !ParentDependsOnArgs && - !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType()) - return D; + !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType()) { + // Check if D belongs to a function template + auto *PVD = cast<ParmVarDecl>(D); + bool IsFromFunctionTemplate = + llvm::any_of(ParentDC->decls(), [PVD](Decl *D) { + if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) + return llvm::is_contained(FTD->getTemplatedDecl()->parameters(), + PVD); + return false; + }); + + if (!IsFromFunctionTemplate) + return D; + } if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) || (ParentDependsOnArgs && (ParentDC->isFunctionOrMethod() || diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index 2713cc19ea2be..212c8b0cbbb39 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -4,7 +4,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT %s +// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT,CHECK-LOAD %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \ @@ -12,7 +12,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-LOAD,CHECK-STORE %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \ @@ -142,9 +142,222 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// Load methods + +// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int)' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: CompoundStmt +// CHECK-LOAD-NEXT: ReturnStmt +// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'hlsl_device unsigned int' lvalue prefix '*' cannot overflow +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'hlsl_device unsigned int *' +// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int, out unsigned int) +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict' +// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-LOAD-NEXT: CompoundStmt +// CHECK-LOAD-NEXT: ReturnStmt +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'unsigned int' +// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Status' 'unsigned int &__restrict' +// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int (unsigned int), 2>' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: CompoundStmt +// CHECK-LOAD-NEXT: ReturnStmt +// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'vector<unsigned int hlsl_device, 2>' lvalue prefix '*' cannot overflow +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int hlsl_device *, 2>' +// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int (unsigned int, out unsigned int), 2>' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict' +// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-LOAD-NEXT: CompoundStmt +// CHECK-LOAD-NEXT: ReturnStmt +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int, 2>' +// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Status' 'unsigned int &__restrict' +// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline + +// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int (unsigned int), 3>' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: CompoundStmt +// CHECK-LOAD-NEXT: ReturnStmt +// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'vector<unsigned int hlsl_device, 3>' lvalue prefix '*' cannot overflow +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int hlsl_device *, 3>' +// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr> +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle +// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline +// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int (unsigned int, out unsigned int), 3>' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' +// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict' +// CHECK-LOAD-NEXT: HLSLPa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/176058 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
