Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -1902,13 +1902,15 @@ // Solve for constants. bool ResolvedUndefs = true; + Solver.Solve(); while (ResolvedUndefs) { - Solver.Solve(); - LLVM_DEBUG(dbgs() << "RESOLVING UNDEFS\n"); ResolvedUndefs = false; for (Function &F : M) - ResolvedUndefs |= Solver.ResolvedUndefsIn(F); + if (Solver.ResolvedUndefsIn(F)) { + Solver.Solve(); + ResolvedUndefs = true; + } } bool MadeChanges = false; Index: test/Transforms/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll =================================================================== --- /dev/null +++ test/Transforms/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll @@ -0,0 +1,39 @@ +; RUN: opt < %s -S -ipsccp | FileCheck %s + +; We re-run the solver each time we resolved an undef in a function. This allows +; us to find the constant return value of @testf before resolving undefs in +; @test1. +define internal i1 @testf() { +; CHECK-LABEL: define internal i1 @testf( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[IF_END3:%.*]] +; CHECK: if.end3: +; CHECK-NEXT: ret i1 undef +; +entry: + br i1 undef, label %if.then1, label %if.end3 + +if.then1: ; preds = %if.end + br label %if.end3 + +if.end3: ; preds = %if.then1, %entry + ret i1 true +} + +define void @test1() { +; CHECK-LABEL: @test1( +; CHECK-LABEL: if.then: +; CHECK: call i1 @testf() +; CHECK-NEXT: br i1 true, label %if.end, label %if.then +; +entry: + br label %if.then +if.then: ; preds = %entry, %if.then + %foo = phi i32 [ 0, %entry], [ %next, %if.then] + %next = add i32 %foo, 1 + %call = call i1 @testf() + br i1 %call, label %if.end, label %if.then + +if.end: ; preds = %if.then, %entry + ret void +} Index: test/Transforms/SCCP/ipsccp-basic.ll =================================================================== --- test/Transforms/SCCP/ipsccp-basic.ll +++ test/Transforms/SCCP/ipsccp-basic.ll @@ -253,7 +253,7 @@ ret void ; CHECK-LABEL: define void @test11b ; CHECK: %[[call1:.*]] = call i64 @test11a() -; CHECK: %[[call2:.*]] = call i64 @llvm.ctpop.i64(i64 0) +; CHECK-NOT: call i64 @llvm.ctpop.i64 } declare i64 @llvm.ctpop.i64(i64)