diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 7830cdd18c6cd..b8591b0fe475a 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -156,6 +156,10 @@ struct BuiltinTypeMethodBuilder { BuiltinTypeDeclBuilder &finalize(); Expr *getResourceHandleExpr(); + template + BuiltinTypeMethodBuilder &getResourceHandle(T ResourceRecord); + BuiltinTypeMethodBuilder &returnThis(); + private: void createDecl(); @@ -332,7 +336,7 @@ Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) { return DeclRefExpr::Create( AST, NestedNameSpecifierLoc(), SourceLocation(), ParamDecl, false, DeclarationNameInfo(ParamDecl->getDeclName(), SourceLocation()), - ParamDecl->getType(), VK_PRValue); + ParamDecl->getType().getNonReferenceType(), VK_PRValue); } BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, @@ -431,6 +435,31 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() { OK_Ordinary); } +template +BuiltinTypeMethodBuilder & +BuiltinTypeMethodBuilder::getResourceHandle(T ResourceRecord) { + ensureCompleteDecl(); + + Expr *ResourceExpr = convertPlaceholder(ResourceRecord); + + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + FieldDecl *HandleField = DeclBuilder.getResourceHandleField(); + MemberExpr *HandleExpr = MemberExpr::CreateImplicit( + AST, ResourceExpr, /*IsArrow=*/false, HandleField, HandleField->getType(), + VK_LValue, OK_Ordinary); + StmtsList.push_back(HandleExpr); + return *this; +} + +BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnThis() { + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + CXXThisExpr *ThisExpr = CXXThisExpr::Create( + AST, SourceLocation(), Method->getFunctionObjectParameterType(), + /*IsImplicit=*/true); + StmtsList.push_back(ThisExpr); + return *this; +} + template BuiltinTypeMethodBuilder & BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName, @@ -676,6 +705,45 @@ BuiltinTypeDeclBuilder::addHandleConstructorFromImplicitBinding() { .finalize(); } +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() { + if (Record->isCompleteDefinition()) + return *this; + + ASTContext &AST = SemaRef.getASTContext(); + QualType RecordType = AST.getCanonicalTagType(Record); + QualType ConstRecordType = RecordType.withConst(); + QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + + return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy, + /*IsConst=*/false, /*IsCtor=*/true) + .addParam("other", ConstRecordRefType) + .getResourceHandle(PH::_0) + .assign(PH::Handle, PH::LastStmt) + .finalize(); +} + +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() { + if (Record->isCompleteDefinition()) + return *this; + + ASTContext &AST = SemaRef.getASTContext(); + QualType RecordType = AST.getCanonicalTagType(Record); + QualType ConstRecordType = RecordType.withConst(); + QualType ConstRecordRefType = AST.getLValueReferenceType(ConstRecordType); + QualType RecordRefType = AST.getLValueReferenceType(RecordType); + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + DeclarationName Name = AST.DeclarationNames.getCXXOperatorName(OO_Equal); + return BuiltinTypeMethodBuilder(*this, Name, RecordRefType) + .addParam("other", ConstRecordRefType) + .getResourceHandle(PH::_0) + .assign(PH::Handle, PH::LastStmt) + .returnThis() + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() { ASTContext &AST = Record->getASTContext(); DeclarationName Subscript = diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index 098b72692bd3a..4c4c2083a8440 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -80,6 +80,8 @@ class BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addDefaultHandleConstructor(); BuiltinTypeDeclBuilder &addHandleConstructorFromBinding(); BuiltinTypeDeclBuilder &addHandleConstructorFromImplicitBinding(); + BuiltinTypeDeclBuilder &addCopyConstructor(); + BuiltinTypeDeclBuilder &addCopyAssignmentOperator(); // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 726581d131623..8c893c0c30baf 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -132,6 +132,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, return BuiltinTypeDeclBuilder(S, Decl) .addHandleMember(RC, IsROV, RawBuffer) .addDefaultHandleConstructor() + .addCopyConstructor() + .addCopyAssignmentOperator() .addHandleConstructorFromBinding() .addHandleConstructorFromImplicitBinding(); } diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index 90794eb69ef46..f2a3a74931a6a 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -56,6 +56,32 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Copy constructor + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (const hlsl::[[RESOURCE]] &)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: AlwaysInlineAttr + +// operator= + +// CHECK: CXXMethodDecl {{.*}} operator= 'hlsl::[[RESOURCE]] &(const hlsl::[[RESOURCE]] &)' +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: AlwaysInlineAttr + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index e028936e397ac..23ed410a8efce 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -103,6 +103,32 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Copy constructor + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (const hlsl::[[RESOURCE]] &)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: AlwaysInlineAttr + +// operator= + +// CHECK: CXXMethodDecl {{.*}} operator= 'hlsl::[[RESOURCE]] &(const hlsl::[[RESOURCE]] &)' +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: AlwaysInlineAttr + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 02c8cf86c8c8b..4e3cdeab74b31 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -78,6 +78,32 @@ RESOURCE Buffer; // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this // CHECK-NEXT: AlwaysInlineAttr +// Copy constructor + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (const hlsl::[[RESOURCE]] &)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: AlwaysInlineAttr + +// operator= + +// CHECK: CXXMethodDecl {{.*}} operator= 'hlsl::[[RESOURCE]] &(const hlsl::[[RESOURCE]] &)' +// CHECK-NEXT: ParmVarDecl {{.*}} other 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: DeclRefExpr {{.*}} 'const hlsl::[[RESOURCE]]' ParmVar {{.*}} 'other' 'const hlsl::[[RESOURCE]] &' +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: AlwaysInlineAttr + // Constructor from binding // CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl index 75d9fb8582b3d..116de8eb857a4 100644 --- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl +++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl @@ -26,9 +26,9 @@ void fb(CustomResource a) { CustomResource b = a; } -// CHECK: define hidden void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %a) -// CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %agg.tmp) -// CHECK: declare hidden void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4) +// CHECK: define hidden void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef %a) +// CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef %{{.*}}) +// CHECK: declare hidden void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr dead_on_return noundef) void foo2(RWBuffer buf); void fc(RWBuffer a) { @@ -44,9 +44,9 @@ struct MyStruct { int2 i; }; -// CHECK: define hidden void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4 %a) -// CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4 %agg.tmp) -// CHECK: declare hidden void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4) +// CHECK: define hidden void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef %a) +// CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef %{{.*}}) +// CHECK: declare hidden void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr dead_on_return noundef) void foo3(StructuredBuffer buf); void fe(StructuredBuffer a) { diff --git a/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl b/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl index db0388e41eae9..76ea87fd534c1 100644 --- a/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl +++ b/clang/test/CodeGenHLSL/debug/rwbuffer_debug_info.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s -debug-info-kind=standalone -dwarf-version=4 | FileCheck %s -// CHECK: [[DWTag:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWBuffer", +// CHECK: [[DWTag:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWBuffer", +// CHECK: [[thisType:![0-9]+]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[DWTag]], size: 32) // CHECK: [[RWBuffer:![0-9]+]] = distinct !DISubprogram(name: "RWBuffer", // CHECK-SAME: scope: [[DWTag]] // CHECK: [[FirstThis:![0-9]+]] = !DILocalVariable(name: "this", arg: 1, scope: [[RWBuffer]], type: [[thisType:![0-9]+]] -// CHECK: [[thisType]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[DWTag]], size: 32) RWBuffer Out : register(u7, space4); [numthreads(8,1,1)] diff --git a/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl b/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl index 60238cbf8eff5..0c96b73ac6cb1 100644 --- a/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl +++ b/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl @@ -31,7 +31,7 @@ uint Find(Node SortedTree[MAX], uint key) { } // CHECK: Function Attrs:{{.*}}norecurse -// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %encodedTree, i32 noundef %maxDepth) [[Attr:\#[0-9]+]] +// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr dead_on_return noundef %encodedTree, i32 noundef %maxDepth) [[Attr:\#[0-9]+]] // CHECK: ret i1 // Initialize tree with given buffer // Imagine the inout works diff --git a/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl index 9b5602f9f67ef..7956e40de1438 100644 --- a/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl +++ b/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-compute -finclude-default-header \ // RUN: -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s +// https://github.com/llvm/llvm-project/issues/156786 +// XFAIL: * + // This test verifies handling of multi-dimensional local arrays of resources // when used as a function argument and local variable. @@ -29,19 +32,35 @@ float foo(RWBuffer Arr[2][2]) { // CHECK-NEXT: entry: [numthreads(4,1,1)] void main() { -// CHECK-NEXT: %L = alloca [2 x [2 x %"class.hlsl::RWBuffer"]], align 4 -// CHECK-NEXT: %[[Tmp:.*]] = alloca [2 x [2 x %"class.hlsl::RWBuffer"]], align 4 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %L, ptr align 4 @_ZL1A, i32 4, i1 false) -// CHECK-NEXT: %[[Ptr1:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %L, i32 1 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr1]], ptr align 4 @_ZL1B, i32 4, i1 false) -// CHECK-NEXT: %[[Ptr2:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %L, i32 1 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr2]], ptr align 4 @_ZL1A, i32 4, i1 false) -// CHECK-NEXT: %[[Ptr3:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %[[Ptr2]], i32 1 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr3]], ptr align 4 @_ZL1B, i32 4, i1 false) +// CHECK: %L = alloca [2 x [2 x %"class.hlsl::RWBuffer"]], align 4 +// CHECK: %[[ref_tmp:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp1:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp2:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp3:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp4:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp5:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp6:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[ref_tmp7:.*]] = alloca %"class.hlsl::RWBuffer", align 4 +// CHECK: %[[agg_tmp:.*]] = alloca [2 x [2 x %"class.hlsl::RWBuffer"]], align 4 +// CHECK: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp]], ptr {{.*}} @_ZL1A) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp1]], ptr {{.*}} %[[ref_tmp]]) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp2]], ptr {{.*}} @_ZL1B) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp3]], ptr {{.*}} %[[ref_tmp2]]) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp4]], ptr {{.*}} @_ZL1A) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp5]], ptr {{.*}} %[[ref_tmp4]]) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp6]], ptr {{.*}} @_ZL1B) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[ref_tmp7]], ptr {{.*}} %[[ref_tmp6]]) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %L, ptr {{.*}} %[[ref_tmp1]]) +// CHECK-NEXT: %[[arrayinit_element:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %L, i32 1 +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[arrayinit_element]], ptr {{.*}} %[[ref_tmp3]]) +// CHECK-NEXT: %[[arrayinit_element8:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %L, i32 1 +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[arrayinit_element8]], ptr {{.*}} %[[ref_tmp5]]) +// CHECK-NEXT: %[[arrayinit_element9:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %[[arrayinit_element8]], i32 1 +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[arrayinit_element9]], ptr {{.*}} %[[ref_tmp7]]) RWBuffer L[2][2] = { { A, B }, { A, B } }; -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp]], ptr align 4 %L, i32 16, i1 false) -// CHECK-NEXT: %[[ReturnedValue:.*]] = call {{.*}}float @_Z3fooA2_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[Tmp]]) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[agg_tmp]], ptr align 4 %L, i32 16, i1 false) +// CHECK-NEXT: %[[ReturnedValue:.*]] = call {{.*}}float @_Z3fooA2_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[agg_tmp]]) // CHECK-NEXT: %[[OutBufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr {{.*}} @_ZL3Out, i32 noundef 0) // CHECK-NEXT: store float %[[ReturnedValue]], ptr %[[OutBufPtr]], align 4 // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl index d1645fdd48e92..9e31f4f150c52 100644 --- a/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl +++ b/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl @@ -22,11 +22,11 @@ void main() { RWBuffer Second[4]; // Verify initialization of First array from an initialization list -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %First, ptr align 4 @_ZL1A, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %First, ptr {{.*}} @_ZL1A) // CHECK-NEXT: %[[Ptr1:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %First, i32 1 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr1]], ptr align 4 @_ZL1B, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[Ptr1]], ptr {{.*}} @_ZL1B) // CHECK-NEXT: %[[Ptr2:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %First, i32 2 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr2]], ptr align 4 @_ZL1C, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIfEC1ERKS1_(ptr {{.*}} %[[Ptr2]], ptr {{.*}} @_ZL1C) // Verify default initialization of Second array, which means there is a loop iterating // over the array elements and calling the default constructor for each @@ -43,7 +43,7 @@ void main() { // Initialize First[2] with C // CHECK: %[[Ptr3:.*]] = getelementptr inbounds [4 x %"class.hlsl::RWBuffer"], ptr %Second, i32 0, i32 2 -// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Ptr3]], ptr align 4 @_ZL1C, i32 4, i1 false) +// CHECK: call {{.*}} @_ZN4hlsl8RWBufferIfEaSERKS1_(ptr {{.*}} %[[Ptr3]], ptr {{.*}} @_ZL1C) Second[2] = C; // NOTE: _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer diff --git a/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl index 8bc3f04d774ca..21ca3f4a98f99 100644 --- a/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl +++ b/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl @@ -20,7 +20,7 @@ RWBuffer Y : register(u1); void SomeFn(RWBuffer B[2], uint Idx, int Val0) { // CHECK-NEXT: %[[B_0_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %B, i32 0, i32 0 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[B_0_Ptr]], ptr align 4 @_ZL1Y, i32 4, i1 false) +// CHECK-NEXT: call {{.*}} @_ZN4hlsl8RWBufferIiEaSERKS1_(ptr {{.*}} %[[B_0_Ptr]], ptr {{.*}} @_ZL1Y) B[0] = Y; // NOTE: _ZN4hlsl8RWBufferIiEixEj is the subscript operator for RWBuffer @@ -43,9 +43,9 @@ void main(uint GI : SV_GroupIndex) { // CHECK-NEXT: store i32 %GI, ptr %GI.addr, align 4 // Initialization of array A with resources X and Y -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %A, ptr align 4 @_ZL1X, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1ERKS1_(ptr {{.*}} %A, ptr {{.*}} @_ZL1X) // CHECK-NEXT: %[[A_1_Ptr:.*]] = getelementptr inbounds %"class.hlsl::RWBuffer", ptr %A, i32 1 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[A_1_Ptr]], ptr align 4 @_ZL1Y, i32 4, i1 false) +// CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1ERKS1_(ptr {{.*}} %[[A_1_Ptr]], ptr {{.*}} @_ZL1Y) RWBuffer A[2] = {X, Y}; // Verify that SomeFn is called with a local copy of the array A diff --git a/clang/test/SemaHLSL/Language/InitLists.hlsl b/clang/test/SemaHLSL/Language/InitLists.hlsl index 3607dfd8aedbc..a02b6f9d5a767 100644 --- a/clang/test/SemaHLSL/Language/InitLists.hlsl +++ b/clang/test/SemaHLSL/Language/InitLists.hlsl @@ -121,6 +121,5 @@ void Err2(RWBuffer B) { // expected-note@#ContainsResource{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'vector' (vector of 2 'int' values) to 'const ContainsResource &' for 1st argument}} // expected-note@#ContainsResource{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'vector' (vector of 2 'int' values) to 'ContainsResource &&' for 1st argument}} -// These notes refer to the RWBuffer constructors that do not have source locations -// expected-note@*{{candidate constructor (the implicit copy constructor) not viable}} -// expected-note@*{{candidate constructor (the implicit move constructor) not viable}} +// This note refers to the RWBuffer copy constructor that do not have a source locations +// expected-note@*{{candidate constructor not viable}}