Skip to content

Commit c7ba48c

Browse files
committed
[HLSL] Add RWBuffer::Load(Index)
This method is the same as `operator[]`, except that it returns a value instead of a reference.
1 parent 0fc42a4 commit c7ba48c

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,29 @@ struct BuiltinTypeDeclBuilder {
189189
BuiltinTypeDeclBuilder &addArraySubscriptOperators(Sema &S) {
190190
if (Record->isCompleteDefinition())
191191
return *this;
192-
addArraySubscriptOperator(S, true);
193-
addArraySubscriptOperator(S, false);
192+
ASTContext &AST = Record->getASTContext();
193+
DeclarationName Subscript =
194+
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
195+
addHandleAccessFunction(S, Subscript, /*IsConst=*/true, /*IsRef=*/true);
196+
addHandleAccessFunction(S, Subscript, /*IsConst=*/false, /*IsRef=*/true);
197+
return *this;
198+
}
199+
200+
BuiltinTypeDeclBuilder &addLoadMethods(Sema &S) {
201+
if (Record->isCompleteDefinition())
202+
return *this;
203+
204+
ASTContext &AST = Record->getASTContext();
205+
IdentifierInfo &II =
206+
AST.Idents.get("Load", tok::TokenKind::identifier);
207+
DeclarationName Load(&II);
208+
addHandleAccessFunction(S, Load, /*IsConst=*/false, /*IsRef=*/false);
209+
194210
return *this;
195211
}
196212

197-
BuiltinTypeDeclBuilder &addArraySubscriptOperator(Sema &S, bool IsConst) {
213+
BuiltinTypeDeclBuilder &addHandleAccessFunction(Sema &S, DeclarationName Name,
214+
bool IsConst, bool IsRef) {
198215
if (Record->isCompleteDefinition())
199216
return *this;
200217

@@ -216,18 +233,16 @@ struct BuiltinTypeDeclBuilder {
216233
ExtInfo.TypeQuals.addConst();
217234
ReturnTy.addConst();
218235
}
219-
ReturnTy = AST.getLValueReferenceType(ReturnTy);
236+
if (IsRef)
237+
ReturnTy = AST.getLValueReferenceType(ReturnTy);
220238

221239
QualType MethodTy =
222240
AST.getFunctionType(ReturnTy, {AST.UnsignedIntTy}, ExtInfo);
223241
auto *TSInfo = AST.getTrivialTypeSourceInfo(MethodTy, SourceLocation());
224242
auto *MethodDecl = CXXMethodDecl::Create(
225243
AST, Record, SourceLocation(),
226-
DeclarationNameInfo(
227-
AST.DeclarationNames.getCXXOperatorName(OO_Subscript),
228-
SourceLocation()),
229-
MethodTy, TSInfo, SC_None, false, false, ConstexprSpecKind::Unspecified,
230-
SourceLocation());
244+
DeclarationNameInfo(Name, SourceLocation()), MethodTy, TSInfo, SC_None,
245+
false, false, ConstexprSpecKind::Unspecified, SourceLocation());
231246

232247
IdentifierInfo &II = AST.Idents.get("Idx", tok::TokenKind::identifier);
233248
auto *IdxParam = ParmVarDecl::Create(
@@ -489,6 +504,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
489504
ResourceKind::TypedBuffer, /*IsROV=*/false,
490505
/*RawBuffer=*/false)
491506
.addArraySubscriptOperators(*SemaPtr)
507+
.addLoadMethods(*SemaPtr)
492508
.completeDefinition();
493509
});
494510

@@ -501,6 +517,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
501517
ResourceKind::TypedBuffer, /*IsROV=*/true,
502518
/*RawBuffer=*/false)
503519
.addArraySubscriptOperators(*SemaPtr)
520+
.addLoadMethods(*SemaPtr)
504521
.completeDefinition();
505522
});
506523

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,21 @@ RWBuffer<float> Buffer;
6464
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
6565
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
6666

67+
// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Load 'element_type (unsigned int)'
68+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
69+
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
70+
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
71+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
72+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
73+
// 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'
74+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
75+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
76+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
77+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
78+
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type>' lvalue implicit this
79+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
80+
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
81+
6782
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition
6883

6984
// 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)