Fix PR1938 by forcing the code that uses an undefined value to branch one
authorChris Lattner <sabre@nondot.org>
Mon, 28 Jan 2008 00:32:30 +0000 (00:32 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 28 Jan 2008 00:32:30 +0000 (00:32 +0000)
way or the other.  Rewriting the code itself prevents subsequent analysis
passes from making contradictory conclusions about the code that could
cause an infeasible path to be made feasible.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46427 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/SCCP.cpp
test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll [new file with mode: 0644]

index d5c98fc4955d0ad6efb6d4042e765fb5a9bb4bfe..07e70099769bfeb15bb90b5f6c6f1e89a5760ce4 100644 (file)
@@ -1313,15 +1313,30 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
       continue;
     }
     
-    // If the edge to the first successor isn't thought to be feasible yet, mark
-    // it so now.
-    if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(0))))
+    // If the edge to the second successor isn't thought to be feasible yet,
+    // mark it so now.  We pick the second one so that this goes to some
+    // enumerated value in a switch instead of going to the default destination.
+    if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(1))))
       continue;
     
     // Otherwise, it isn't already thought to be feasible.  Mark it as such now
     // and return.  This will make other blocks reachable, which will allow new
     // values to be discovered and existing ones to be moved in the lattice.
-    markEdgeExecutable(BB, TI->getSuccessor(0));
+    markEdgeExecutable(BB, TI->getSuccessor(1));
+    
+    // This must be a conditional branch of switch on undef.  At this point,
+    // force the old terminator to branch to the first successor.  This is
+    // required because we are now influencing the dataflow of the function with
+    // the assumption that this edge is taken.  If we leave the branch condition
+    // as undef, then further analysis could think the undef went another way
+    // leading to an inconsistent set of conclusions.
+    if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
+      BI->setCondition(ConstantInt::getFalse());
+    } else {
+      SwitchInst *SI = cast<SwitchInst>(TI);
+      SI->setCondition(SI->getCaseValue(1));
+    }
+    
     return true;
   }
 
diff --git a/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll b/test/Transforms/SCCP/2008-01-27-UndefCorrelate.ll
new file mode 100644 (file)
index 0000000..18ab5e8
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llvm-as < %s | opt -sccp | llvm-dis | grep undef | count 1
+; PR1938
+
+define i32 @main() {
+entry:
+       br label %bb
+
+bb:
+       %indvar = phi i32 [ 0, %entry ], [ %k, %bb.backedge ]
+       %k = add i32 %indvar, 1
+       br i1 undef, label %cond_true, label %cond_false
+
+cond_true:
+       %tmp97 = icmp slt i32 %k, 10
+       br i1 %tmp97, label %bb.backedge, label %bb12
+
+bb.backedge:
+       br label %bb
+
+cond_false:
+       %tmp9 = icmp slt i32 %k, 10
+       br i1 %tmp9, label %bb.backedge, label %bb12
+
+bb12:
+       %tmp14 = icmp eq i32 %k, 10
+       br i1 %tmp14, label %cond_next18, label %cond_true17
+
+cond_true17:
+       tail call void @abort( )
+       unreachable
+
+cond_next18:
+       ret i32 0
+}
+
+declare void @abort()