diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 79fc2751b7381..09fced1115687 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -191,6 +191,19 @@ class BuiltinTypeDeclBuilder { return *this; } + BuiltinTypeDeclBuilder &addLoadMethods() { + if (Record->isCompleteDefinition()) + return *this; + + ASTContext &AST = Record->getASTContext(); + IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier); + DeclarationName Load(&II); + // TODO: We also need versions with status for CheckAccessFullyMapped. + addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false); + + return *this; + } + FieldDecl *getResourceHandleField() { auto I = Fields.find("__handle"); assert(I != Fields.end() && @@ -921,6 +934,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { ResourceKind::TypedBuffer, /*IsROV=*/false, /*RawBuffer=*/false) .addArraySubscriptOperators() + .addLoadMethods() .completeDefinition(); }); @@ -933,6 +947,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { ResourceKind::TypedBuffer, /*IsROV=*/true, /*RawBuffer=*/false) .addArraySubscriptOperators() + .addLoadMethods() .completeDefinition(); }); diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 6bab39de5a233..d6dfb0caba5d9 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -87,6 +87,21 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline +// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Load 'element_type (unsigned int)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' +// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' +// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + // CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> class [[RESOURCE]] definition // CHECK: TemplateArgument type 'float' diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl index 8ce8417772530..4428b77dd9ec8 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl @@ -6,9 +6,16 @@ RWBuffer Out; [numthreads(1,1,1)] void main(unsigned GI : SV_GroupIndex) { // CHECK: define void @main() + // CHECK: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] // CHECK: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] Out[GI] = In[GI]; + + // CHECK: %[[INPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] + // CHECK: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] + Out[GI] = In.Load(GI); }