diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -1467,6 +1467,7 @@ /// This scan also checks for values that use undefs. It conservatively marks /// them as overdefined. bool SCCPSolver::ResolvedUndefsIn(Function &F) { + bool MadeChange = false; for (BasicBlock &BB : F) { if (!BBExecutable.count(&BB)) continue; @@ -1492,8 +1493,10 @@ // more precise than this but it isn't worth bothering. for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { ValueLatticeElement &LV = getStructValueState(&I, i); - if (LV.isUnknownOrUndef()) + if (LV.isUnknownOrUndef()) { markOverdefined(LV, &I); + MadeChange = true; + } } continue; } @@ -1520,7 +1523,7 @@ } markOverdefined(&I); - return true; + MadeChange = true; } // Check to see if we have a branch or switch on an undefined value. If so @@ -1537,7 +1540,8 @@ if (isa(BI->getCondition())) { BI->setCondition(ConstantInt::getFalse(BI->getContext())); markEdgeExecutable(&BB, TI->getSuccessor(1)); - return true; + MadeChange = true; + continue; } // Otherwise, it is a branch on a symbolic value which is currently @@ -1546,7 +1550,7 @@ // FIXME: Distinguish between dead code and an LLVM "undef" value. BasicBlock *DefaultSuccessor = TI->getSuccessor(1); if (markEdgeExecutable(&BB, DefaultSuccessor)) - return true; + MadeChange = true; continue; } @@ -1565,7 +1569,8 @@ if (isa(IBR->getAddress())) { IBR->setAddress(BlockAddress::get(IBR->getSuccessor(0))); markEdgeExecutable(&BB, IBR->getSuccessor(0)); - return true; + MadeChange = true; + continue; } // Otherwise, it is a branch on a symbolic value which is currently @@ -1575,7 +1580,7 @@ // we can assume the branch has undefined behavior instead. BasicBlock *DefaultSuccessor = IBR->getSuccessor(0); if (markEdgeExecutable(&BB, DefaultSuccessor)) - return true; + MadeChange = true; continue; } @@ -1590,7 +1595,8 @@ if (isa(SI->getCondition())) { SI->setCondition(SI->case_begin()->getCaseValue()); markEdgeExecutable(&BB, SI->case_begin()->getCaseSuccessor()); - return true; + MadeChange = true; + continue; } // Otherwise, it is a branch on a symbolic value which is currently @@ -1599,13 +1605,13 @@ // FIXME: Distinguish between dead code and an LLVM "undef" value. BasicBlock *DefaultSuccessor = SI->case_begin()->getCaseSuccessor(); if (markEdgeExecutable(&BB, DefaultSuccessor)) - return true; + MadeChange = true; continue; } } - return false; + return MadeChange; } static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) { @@ -1963,13 +1969,12 @@ while (ResolvedUndefs) { LLVM_DEBUG(dbgs() << "RESOLVING UNDEFS\n"); ResolvedUndefs = false; - for (Function &F : M) - if (Solver.ResolvedUndefsIn(F)) { - // We run Solve() after we resolved an undef in a function, because - // we might deduce a fact that eliminates an undef in another function. - Solver.Solve(); + for (Function &F : M) { + if (Solver.ResolvedUndefsIn(F)) ResolvedUndefs = true; - } + } + if (ResolvedUndefs) + Solver.Solve(); } bool MadeChanges = false; diff --git a/llvm/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll b/llvm/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll --- a/llvm/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll +++ b/llvm/test/Transforms/SCCP/2004-12-10-UndefBranchBug.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -sccp -S | grep "ret i32 1" +; RUN: opt < %s -sccp -S | grep "ret i32 %X" ; This function definitely returns 1, even if we don't know the direction ; of the branch. diff --git a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll --- a/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll +++ b/llvm/test/Transforms/SCCP/resolvedundefsin-tracked-fn.ll @@ -274,8 +274,9 @@ ; CHECK-SAME: (i8* [[ARG:%.*]]) ; CHECK-NEXT: bb: ; CHECK-NEXT: [[TMP:%.*]] = bitcast i8* null to i16* +; CHECK-NEXT: [[SEL:%.*]] = select i1 false, i8* null, i8* null ; CHECK-NEXT: call void @use.16(i16* [[TMP]]) -; CHECK-NEXT: call void @use.8(i8* null) +; CHECK-NEXT: call void @use.8(i8* [[SEL]]) ; CHECK-NEXT: ret void ; bb: @@ -384,7 +385,10 @@ ; CHECK-NEXT: store i32 [[MUL]], i32* @pcount, align 4 ; CHECK-NEXT: ret void ; CHECK: if.end24: -; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK-NEXT: [[CMP25474:%.*]] = icmp sgt i32 [[TMP2]], 0 +; CHECK-NEXT: br i1 [[CMP25474]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: ret void ; CHECK: for.end: ; CHECK-NEXT: ret void ;