kparzysz updated this revision to Diff 94699.
kparzysz added a comment.
Do not stop the check for unions at the first MemberExpr (unless it's a union).
Repository:
rL LLVM
https://reviews.llvm.org/D31885
Files:
lib/CodeGen/CGExpr.cpp
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -1011,66 +1011,101 @@
/// type of the same size of the lvalue's type. If the lvalue has a variable
/// length type, this is not possible.
///
+
+/// Hacks to remove TBAA information from LValues that represent union members.
+/// The TBAA in the current form does not work for union members: the aliasing
+/// information emitted in such cases may be incorrect (leading to incorrect
+/// optimizations).
+static bool isUnionAccess(const Expr *E) {
+ switch (E->getStmtClass()) {
+ case Stmt::MemberExprClass: {
+ const Expr *BE = cast<const MemberExpr>(E)->getBase();
+ if (BE->getType()->isUnionType())
+ return true;
+ return isUnionAccess(BE);
+ }
+ case Stmt::ImplicitCastExprClass:
+ return isUnionAccess(cast<const ImplicitCastExpr>(E)->getSubExpr());
+ case Stmt::ArraySubscriptExprClass:
+ return isUnionAccess(cast<const ArraySubscriptExpr>(E)->getBase());
+ default:
+ break;
+ }
+ return false;
+}
+
+static LValue ClearTBAA(LValue &&LV, bool Reset) {
+ if (Reset)
+ LV.setTBAAInfo(nullptr);
+ return LV;
+}
+
LValue CodeGenFunction::EmitLValue(const Expr *E) {
+ bool R = CGM.shouldUseTBAA() && isUnionAccess(E);
ApplyDebugLocation DL(*this, E);
switch (E->getStmtClass()) {
- default: return EmitUnsupportedLValue(E, "l-value expression");
+ default: return ClearTBAA(EmitUnsupportedLValue(E, "l-value expression"), R);
case Expr::ObjCPropertyRefExprClass:
llvm_unreachable("cannot emit a property reference directly");
case Expr::ObjCSelectorExprClass:
- return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
+ return ClearTBAA(EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E)), R);
case Expr::ObjCIsaExprClass:
- return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
+ return ClearTBAA(EmitObjCIsaExpr(cast<ObjCIsaExpr>(E)), R);
case Expr::BinaryOperatorClass:
- return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
+ return ClearTBAA(EmitBinaryOperatorLValue(cast<BinaryOperator>(E)), R);
case Expr::CompoundAssignOperatorClass: {
QualType Ty = E->getType();
if (const AtomicType *AT = Ty->getAs<AtomicType>())
Ty = AT->getValueType();
+ const auto *CA = cast<CompoundAssignOperator>(E);
if (!Ty->isAnyComplexType())
- return EmitCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
- return EmitComplexCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
+ return ClearTBAA(EmitCompoundAssignmentLValue(CA), R);
+ return ClearTBAA(EmitComplexCompoundAssignmentLValue(CA), R);
}
case Expr::CallExprClass:
case Expr::CXXMemberCallExprClass:
case Expr::CXXOperatorCallExprClass:
case Expr::UserDefinedLiteralClass:
- return EmitCallExprLValue(cast<CallExpr>(E));
+ return ClearTBAA(EmitCallExprLValue(cast<CallExpr>(E)), R);
case Expr::VAArgExprClass:
- return EmitVAArgExprLValue(cast<VAArgExpr>(E));
+ return ClearTBAA(EmitVAArgExprLValue(cast<VAArgExpr>(E)), R);
case Expr::DeclRefExprClass:
- return EmitDeclRefLValue(cast<DeclRefExpr>(E));
+ return ClearTBAA(EmitDeclRefLValue(cast<DeclRefExpr>(E)), R);
case Expr::ParenExprClass:
- return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
- case Expr::GenericSelectionExprClass:
- return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr());
+ return ClearTBAA(EmitLValue(cast<ParenExpr>(E)->getSubExpr()), R);
+ case Expr::GenericSelectionExprClass: {
+ const auto *GS = cast<GenericSelectionExpr>(E);
+ return ClearTBAA(EmitLValue(GS->getResultExpr()), R);
+ }
case Expr::PredefinedExprClass:
- return EmitPredefinedLValue(cast<PredefinedExpr>(E));
+ return ClearTBAA(EmitPredefinedLValue(cast<PredefinedExpr>(E)), R);
case Expr::StringLiteralClass:
- return EmitStringLiteralLValue(cast<StringLiteral>(E));
+ return ClearTBAA(EmitStringLiteralLValue(cast<StringLiteral>(E)), R);
case Expr::ObjCEncodeExprClass:
- return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
+ return ClearTBAA(EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E)), R);
case Expr::PseudoObjectExprClass:
- return EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E));
+ return ClearTBAA(EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E)), R);
case Expr::InitListExprClass:
- return EmitInitListLValue(cast<InitListExpr>(E));
+ return ClearTBAA(EmitInitListLValue(cast<InitListExpr>(E)), R);
case Expr::CXXTemporaryObjectExprClass:
case Expr::CXXConstructExprClass:
- return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
- case Expr::CXXBindTemporaryExprClass:
- return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
+ return ClearTBAA(EmitCXXConstructLValue(cast<CXXConstructExpr>(E)), R);
+ case Expr::CXXBindTemporaryExprClass: {
+ const auto *BT = cast<CXXBindTemporaryExpr>(E);
+ return ClearTBAA(EmitCXXBindTemporaryLValue(BT), R);
+ }
case Expr::CXXUuidofExprClass:
- return EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E));
+ return ClearTBAA(EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E)), R);
case Expr::LambdaExprClass:
- return EmitLambdaLValue(cast<LambdaExpr>(E));
+ return ClearTBAA(EmitLambdaLValue(cast<LambdaExpr>(E)), R);
case Expr::ExprWithCleanupsClass: {
const auto *cleanups = cast<ExprWithCleanups>(E);
enterFullExpression(cleanups);
RunCleanupsScope Scope(*this);
- LValue LV = EmitLValue(cleanups->getSubExpr());
+ LValue LV = ClearTBAA(EmitLValue(cleanups->getSubExpr()), R);
if (LV.isSimple()) {
// Defend against branches out of gnu statement expressions surrounded by
// cleanups.
@@ -1086,54 +1121,66 @@
}
case Expr::CXXDefaultArgExprClass:
- return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
+ return ClearTBAA(EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr()), R);
case Expr::CXXDefaultInitExprClass: {
CXXDefaultInitExprScope Scope(*this);
- return EmitLValue(cast<CXXDefaultInitExpr>(E)->getExpr());
+ return ClearTBAA(EmitLValue(cast<CXXDefaultInitExpr>(E)->getExpr()), R);
}
case Expr::CXXTypeidExprClass:
- return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
+ return ClearTBAA(EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E)), R);
case Expr::ObjCMessageExprClass:
- return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
+ return ClearTBAA(EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E)), R);
case Expr::ObjCIvarRefExprClass:
- return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
+ return ClearTBAA(EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E)), R);
case Expr::StmtExprClass:
- return EmitStmtExprLValue(cast<StmtExpr>(E));
+ return ClearTBAA(EmitStmtExprLValue(cast<StmtExpr>(E)), R);
case Expr::UnaryOperatorClass:
- return EmitUnaryOpLValue(cast<UnaryOperator>(E));
+ return ClearTBAA(EmitUnaryOpLValue(cast<UnaryOperator>(E)), R);
case Expr::ArraySubscriptExprClass:
- return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
+ return ClearTBAA(EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E)), R);
case Expr::OMPArraySectionExprClass:
- return EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E));
- case Expr::ExtVectorElementExprClass:
- return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
+ return ClearTBAA(EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E)), R);
+ case Expr::ExtVectorElementExprClass: {
+ const auto *EVE = cast<ExtVectorElementExpr>(E);
+ return ClearTBAA(EmitExtVectorElementExpr(EVE), R);
+ }
case Expr::MemberExprClass:
- return EmitMemberExpr(cast<MemberExpr>(E));
- case Expr::CompoundLiteralExprClass:
- return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
- case Expr::ConditionalOperatorClass:
- return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
- case Expr::BinaryConditionalOperatorClass:
- return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E));
+ return ClearTBAA(EmitMemberExpr(cast<MemberExpr>(E)), R);
+ case Expr::CompoundLiteralExprClass: {
+ const auto *CL = cast<CompoundLiteralExpr>(E);
+ return ClearTBAA(EmitCompoundLiteralLValue(CL), R);
+ }
+ case Expr::ConditionalOperatorClass: {
+ const auto *CO = cast<ConditionalOperator>(E);
+ return ClearTBAA(EmitConditionalOperatorLValue(CO), R);
+ }
+ case Expr::BinaryConditionalOperatorClass: {
+ const auto *BCO = cast<BinaryConditionalOperator>(E);
+ return ClearTBAA(EmitConditionalOperatorLValue(BCO), R);
+ }
case Expr::ChooseExprClass:
- return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr());
+ return ClearTBAA(EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr()), R);
case Expr::OpaqueValueExprClass:
- return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E));
- case Expr::SubstNonTypeTemplateParmExprClass:
- return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
+ return ClearTBAA(EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E)), R);
+ case Expr::SubstNonTypeTemplateParmExprClass: {
+ const auto *STP = cast<SubstNonTypeTemplateParmExpr>(E);
+ return ClearTBAA(EmitLValue(STP->getReplacement()), R);
+ }
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
case Expr::CXXFunctionalCastExprClass:
case Expr::CXXStaticCastExprClass:
case Expr::CXXDynamicCastExprClass:
case Expr::CXXReinterpretCastExprClass:
case Expr::CXXConstCastExprClass:
case Expr::ObjCBridgedCastExprClass:
- return EmitCastLValue(cast<CastExpr>(E));
+ return ClearTBAA(EmitCastLValue(cast<CastExpr>(E)), R);
- case Expr::MaterializeTemporaryExprClass:
- return EmitMaterializeTemporaryExpr(cast<MaterializeTemporaryExpr>(E));
+ case Expr::MaterializeTemporaryExprClass: {
+ const auto *MT = cast<MaterializeTemporaryExpr>(E);
+ return ClearTBAA(EmitMaterializeTemporaryExpr(MT), R);
+ }
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits