From 8829cec25fe77cadbd99dcf7bbbce4969eb5704a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 9 Apr 2010 01:14:31 +0000 Subject: [PATCH] fix a SCCP miscompilation that could happen when a forced constant is changed to a constant, we would end up adding the instruction to the wrong worklist, preventing it from being properly revisited. This fixes rdar://7832370 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100837 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SCCP.cpp | 13 +++- test/Transforms/SCCP/undef-resolve.ll | 95 +++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/SCCP/undef-resolve.ll diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 4f09bee53a8..59cdee652dc 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -317,7 +317,10 @@ private: void markConstant(LatticeVal &IV, Value *V, Constant *C) { if (!IV.markConstant(C)) return; DEBUG(dbgs() << "markConstant: " << *C << ": " << *V << '\n'); - InstWorkList.push_back(V); + if (IV.isOverdefined()) + OverdefinedInstWorkList.push_back(V); + else + InstWorkList.push_back(V); } void markConstant(Value *V, Constant *C) { @@ -327,9 +330,13 @@ private: void markForcedConstant(Value *V, Constant *C) { assert(!V->getType()->isStructTy() && "Should use other method"); - ValueState[V].markForcedConstant(C); + LatticeVal &IV = ValueState[V]; + IV.markForcedConstant(C); DEBUG(dbgs() << "markForcedConstant: " << *C << ": " << *V << '\n'); - InstWorkList.push_back(V); + if (IV.isOverdefined()) + OverdefinedInstWorkList.push_back(V); + else + InstWorkList.push_back(V); } diff --git a/test/Transforms/SCCP/undef-resolve.ll b/test/Transforms/SCCP/undef-resolve.ll new file mode 100644 index 00000000000..d2f3d0206d7 --- /dev/null +++ b/test/Transforms/SCCP/undef-resolve.ll @@ -0,0 +1,95 @@ +; RUN: opt %s -sccp -S | FileCheck %s +; rdar://7832370 +; Check that lots of stuff doesn't get turned into undef. + +define i32 @main() nounwind readnone ssp { +init: + br label %control.outer.outer + +control.outer.loopexit.us-lcssa: ; preds = %control + br label %control.outer.loopexit + +control.outer.loopexit: ; preds = %control.outer.loopexit.us-lcssa.us, %control.outer.loopexit.us-lcssa + br label %control.outer.outer.backedge + +control.outer.outer: ; preds = %control.outer.outer.backedge, %init + %switchCond.0.ph.ph = phi i32 [ 2, %init ], [ 3, %control.outer.outer.backedge ] ; [#uses=2] + %i.0.ph.ph = phi i32 [ undef, %init ], [ %i.0.ph.ph.be, %control.outer.outer.backedge ] ; [#uses=1] + %tmp4 = icmp eq i32 %i.0.ph.ph, 0 ; [#uses=1] + br i1 %tmp4, label %control.outer.outer.split.us, label %control.outer.outer.control.outer.outer.split_crit_edge + +control.outer.outer.control.outer.outer.split_crit_edge: ; preds = %control.outer.outer + br label %control.outer + +control.outer.outer.split.us: ; preds = %control.outer.outer + br label %control.outer.us + +control.outer.us: ; preds = %bb3.us, %control.outer.outer.split.us + %A.0.ph.us = phi i32 [ %switchCond.0.us, %bb3.us ], [ 4, %control.outer.outer.split.us ] ; [#uses=2] + %switchCond.0.ph.us = phi i32 [ %A.0.ph.us, %bb3.us ], [ %switchCond.0.ph.ph, %control.outer.outer.split.us ] ; [#uses=1] + br label %control.us + +bb3.us: ; preds = %control.us + br label %control.outer.us + +bb0.us: ; preds = %control.us + br label %control.us + +; CHECK: control.us: ; preds = %bb0.us, %control.outer.us +; CHECK-NEXT: %switchCond.0.us = phi i32 +; CHECK-NEXT: switch i32 %switchCond.0.us +control.us: ; preds = %bb0.us, %control.outer.us + %switchCond.0.us = phi i32 [ %A.0.ph.us, %bb0.us ], [ %switchCond.0.ph.us, %control.outer.us ] ; [#uses=2] + switch i32 %switchCond.0.us, label %control.outer.loopexit.us-lcssa.us [ + i32 0, label %bb0.us + i32 1, label %bb1.us-lcssa.us + i32 3, label %bb3.us + i32 4, label %bb4.us-lcssa.us + ] + +control.outer.loopexit.us-lcssa.us: ; preds = %control.us + br label %control.outer.loopexit + +bb1.us-lcssa.us: ; preds = %control.us + br label %bb1 + +bb4.us-lcssa.us: ; preds = %control.us + br label %bb4 + +control.outer: ; preds = %bb3, %control.outer.outer.control.outer.outer.split_crit_edge + %A.0.ph = phi i32 [ %nextId17, %bb3 ], [ 4, %control.outer.outer.control.outer.outer.split_crit_edge ] ; [#uses=1] + %switchCond.0.ph = phi i32 [ 0, %bb3 ], [ %switchCond.0.ph.ph, %control.outer.outer.control.outer.outer.split_crit_edge ] ; [#uses=1] + br label %control + +control: ; preds = %bb0, %control.outer + %switchCond.0 = phi i32 [ %A.0.ph, %bb0 ], [ %switchCond.0.ph, %control.outer ] ; [#uses=2] + switch i32 %switchCond.0, label %control.outer.loopexit.us-lcssa [ + i32 0, label %bb0 + i32 1, label %bb1.us-lcssa + i32 3, label %bb3 + i32 4, label %bb4.us-lcssa + ] + +bb4.us-lcssa: ; preds = %control + br label %bb4 + +bb4: ; preds = %bb4.us-lcssa, %bb4.us-lcssa.us + br label %control.outer.outer.backedge + +control.outer.outer.backedge: ; preds = %bb4, %control.outer.loopexit + %i.0.ph.ph.be = phi i32 [ 1, %bb4 ], [ 0, %control.outer.loopexit ] ; [#uses=1] + br label %control.outer.outer + +bb3: ; preds = %control + %nextId17 = add i32 %switchCond.0, -2 ; [#uses=1] + br label %control.outer + +bb0: ; preds = %control + br label %control + +bb1.us-lcssa: ; preds = %control + br label %bb1 + +bb1: ; preds = %bb1.us-lcssa, %bb1.us-lcssa.us + ret i32 0 +} -- 2.34.1