diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2012-09-30 12:43:37 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2012-09-30 12:43:37 +0000 |
commit | 6cacae8bf9597b8124cd40aedc189c04484e1990 (patch) | |
tree | b20a92a4aa5ad64f3ea61a4d87113972fae44363 /lib/CodeGen | |
parent | 615c3dda26323dc1b07333e060a64c2471b74d9e (diff) |
CodeGen: Copy tail padding when we're not dealing with a trivial copy assign or move assign operator.
This fixes a regression from r162254, the optimizer has problems reasoning
about the smaller memcpy as it's often not safe to widen a store but making it
smaller is.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164917 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 15 |
3 files changed, 25 insertions, 7 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index c9ffc19a8b..200b43aa6d 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -1274,7 +1274,8 @@ LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType Ty, bool isVolatile, - CharUnits alignment) { + CharUnits alignment, + bool isAssignment) { assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); if (getContext().getLangOpts().CPlusPlus) { @@ -1303,9 +1304,13 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, // implementation handles this case safely. If there is a libc that does not // safely handle this, we can add a target hook. - // Get data size and alignment info for this aggregate. - std::pair<CharUnits, CharUnits> TypeInfo = - getContext().getTypeInfoDataSizeInChars(Ty); + // Get data size and alignment info for this aggregate. If this is an + // assignment don't copy the tail padding. Otherwise copying it is fine. + std::pair<CharUnits, CharUnits> TypeInfo; + if (isAssignment) + TypeInfo = getContext().getTypeInfoDataSizeInChars(Ty); + else + TypeInfo = getContext().getTypeInfoInChars(Ty); if (alignment.isZero()) alignment = TypeInfo.second; diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 7276440a47..16311963b3 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -241,7 +241,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, // We don't like to generate the trivial copy/move assignment operator // when it isn't necessary; just produce the proper effect here. llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateCopy(This, RHS, CE->getType()); + EmitAggregateAssign(This, RHS, CE->getType()); return RValue::get(This); } @@ -378,7 +378,7 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, MD->isTrivial()) { llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress(); QualType Ty = E->getType(); - EmitAggregateCopy(This, Src, Ty); + EmitAggregateAssign(This, Src, Ty); return RValue::get(This); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fc930ec158..4a0c35bd82 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1653,13 +1653,26 @@ public: void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit); + /// EmitAggregateCopy - Emit an aggrate assignment. + /// + /// The difference to EmitAggregateCopy is that tail padding is not copied. + /// This is required for correctness when assigning non-POD structures in C++. + void EmitAggregateAssign(llvm::Value *DestPtr, llvm::Value *SrcPtr, + QualType EltTy, bool isVolatile=false, + CharUnits Alignment = CharUnits::Zero()) { + EmitAggregateCopy(DestPtr, SrcPtr, EltTy, isVolatile, Alignment, true); + } + /// EmitAggregateCopy - Emit an aggrate copy. /// /// \param isVolatile - True iff either the source or the destination is /// volatile. + /// \param isAssignment - If false, allow padding to be copied. This often + /// yields more efficient. void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy, bool isVolatile=false, - CharUnits Alignment = CharUnits::Zero()); + CharUnits Alignment = CharUnits::Zero(), + bool isAssignment = false); /// StartBlock - Start new block named N. If insert block is a dummy block /// then reuse it. |