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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to