https://github.com/s-perron created https://github.com/llvm/llvm-project/pull/156075
The wrapper used to hold the handle for resource type has just the default copy constructor and assignment operator. This causes clang to insert memcpys when it does an assignment of a resource type. The memcpy then cause optimizations to fail when the memcpy is turned into a load and store of an i64. To fix this, we should define copying of a resource type by adding the operator= and copy constructor. Partially fixes #154669 >From cfaf08898c046baaa41cb1cbe75ed9682da8bc1f Mon Sep 17 00:00:00 2001 From: Steven Perron <stevenper...@google.com> Date: Fri, 29 Aug 2025 13:40:55 -0400 Subject: [PATCH] [HLSL] Add copy assignment and construtor to resource types The wrapper used to hold the handle for resource type has just the default copy constructor and assignment operator. This causes clang to insert memcpys when it does an assignment of a resource type. The memcpy then cause optimizations to fail when the memcpy is turned into a load and store of an i64. To fix this, we should define copying of a resource type by adding the operator= and copy constructor. Partially fixes #154669 --- clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 69 +++++++++++++++++++ clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 + clang/lib/Sema/HLSLExternalSemaSource.cpp | 2 + 3 files changed, 73 insertions(+) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 806800cb7b213..6c39fe504d3f3 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -676,6 +676,75 @@ 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; + + BuiltinTypeMethodBuilder Builder(*this, "", AST.VoidTy, false, true); + Builder.addParam("other", ConstRecordRefType); + Builder.ensureCompleteDecl(); + + ParmVarDecl *OtherParam = Builder.Method->getParamDecl(0); + + Expr *OtherDeclRef = DeclRefExpr::Create( + AST, NestedNameSpecifierLoc(), SourceLocation(), OtherParam, false, + DeclarationNameInfo(OtherParam->getDeclName(), SourceLocation()), + ConstRecordType, VK_LValue); + + FieldDecl *HandleField = getResourceHandleField(); + Expr *OtherHandleMemberExpr = MemberExpr::CreateImplicit( + AST, OtherDeclRef, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + + return Builder.assign(PH::Handle, OtherHandleMemberExpr).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); + BuiltinTypeMethodBuilder Builder(*this, Name, RecordRefType, false, false); + Builder.addParam("other", ConstRecordRefType); + Builder.ensureCompleteDecl(); + + ParmVarDecl *OtherParam = Builder.Method->getParamDecl(0); + Expr *OtherDeclRef = DeclRefExpr::Create( + AST, NestedNameSpecifierLoc(), SourceLocation(), OtherParam, false, + DeclarationNameInfo(OtherParam->getDeclName(), SourceLocation()), + ConstRecordType, VK_LValue); + + FieldDecl *HandleField = getResourceHandleField(); + Expr *OtherHandleMemberExpr = MemberExpr::CreateImplicit( + AST, OtherDeclRef, false, HandleField, HandleField->getType(), VK_LValue, + OK_Ordinary); + + Builder.assign(PH::Handle, OtherHandleMemberExpr); + + // return *this; + CXXThisExpr *This = CXXThisExpr::Create( + AST, SourceLocation(), Builder.Method->getFunctionObjectParameterType(), + true); + Builder.StmtsList.push_back(This); + + return Builder.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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits