Skip to content

Commit de40159

Browse files
authored
[HLSL] Add RWBuffer::Load(Index) (#117018)
This method is the same as `operator[]`, except that it returns a value instead of a reference.
1 parent 8217c2e commit de40159

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ class BuiltinTypeDeclBuilder {
191191
return *this;
192192
}
193193

194+
BuiltinTypeDeclBuilder &addLoadMethods() {
195+
if (Record->isCompleteDefinition())
196+
return *this;
197+
198+
ASTContext &AST = Record->getASTContext();
199+
IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
200+
DeclarationName Load(&II);
201+
// TODO: We also need versions with status for CheckAccessFullyMapped.
202+
addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false);
203+
204+
return *this;
205+
}
206+
194207
FieldDecl *getResourceHandleField() {
195208
auto I = Fields.find("__handle");
196209
assert(I != Fields.end() &&
@@ -921,6 +934,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
921934
ResourceKind::TypedBuffer, /*IsROV=*/false,
922935
/*RawBuffer=*/false)
923936
.addArraySubscriptOperators()
937+
.addLoadMethods()
924938
.completeDefinition();
925939
});
926940

@@ -933,6 +947,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
933947
ResourceKind::TypedBuffer, /*IsROV=*/true,
934948
/*RawBuffer=*/false)
935949
.addArraySubscriptOperators()
950+
.addLoadMethods()
936951
.completeDefinition();
937952
});
938953

clang/test/AST/HLSL/TypedBuffers-AST.hlsl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ RESOURCE<float> Buffer;
8787
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int'
8888
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
8989

90+
// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Load 'element_type (unsigned int)'
91+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Index 'unsigned int'
92+
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
93+
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
94+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
95+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
96+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
97+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
98+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
99+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
100+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
101+
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '[[RESOURCE]]<element_type>' lvalue implicit this
102+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int'
103+
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
104+
90105
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class [[RESOURCE]] definition
91106

92107
// CHECK: TemplateArgument type 'float'

clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ RWBuffer<int> Out;
66
[numthreads(1,1,1)]
77
void main(unsigned GI : SV_GroupIndex) {
88
// CHECK: define void @main()
9+
910
// 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 %{{.*}})
1011
// CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]]
1112
// 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 %{{.*}})
1213
// CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]]
1314
Out[GI] = In[GI];
15+
16+
// CHECK: %[[INPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}})
17+
// CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]]
18+
// 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 %{{.*}})
19+
// CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]]
20+
Out[GI] = In.Load(GI);
1421
}

0 commit comments

Comments
 (0)