llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

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

Reply via email to