Index: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp @@ -1902,13 +1902,17 @@ // 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)) { + // 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(); + ResolvedUndefs = true; + } } bool MadeChanges = false; Index: llvm/trunk/test/Transforms/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll =================================================================== --- llvm/trunk/test/Transforms/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll +++ llvm/trunk/test/Transforms/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll @@ -0,0 +1,43 @@ +; RUN: opt < %s -ipsccp -S | FileCheck %s + +; CHECK-LABEL: @testf( +; CHECK: ret i32 undef +; +define internal i32 @testf() { +entry: + br i1 undef, label %if.then, label %if.end + +if.then: ; preds = %entry, %if.then + br label %if.end + +if.end: ; preds = %if.then1, %entry + ret i32 10 +} + +; CHECK-LABEL: @test1( +; CHECK: ret i32 undef +; +define internal i32 @test1() { +entry: + br label %if.then + +if.then: ; preds = %entry, %if.then + %call = call i32 @testf() + %res = icmp eq i32 %call, 10 + br i1 %res, label %ret1, label %ret2 + +ret1: ; preds = %if.then, %entry + ret i32 99 + +ret2: ; preds = %if.then, %entry + ret i32 0 +} + +; CHECK-LABEL: @main( +; CHECK-NEXT: %res = call i32 @test1() +; CHECK-NEXT: ret i32 99 +; +define i32 @main() { + %res = call i32 @test1() + ret i32 %res +} Index: llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll =================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll +++ llvm/trunk/test/Transforms/SCCP/ipsccp-basic.ll @@ -247,13 +247,14 @@ ; CHECK: ret i64 0 } -define void @test11b() { +define i64 @test11b() { %call1 = call i64 @test11a() %call2 = call i64 @llvm.ctpop.i64(i64 %call1) - ret void -; CHECK-LABEL: define void @test11b + ret i64 %call2 +; CHECK-LABEL: define i64 @test11b ; CHECK: %[[call1:.*]] = call i64 @test11a() -; CHECK: %[[call2:.*]] = call i64 @llvm.ctpop.i64(i64 0) +; CHECK-NOT: call i64 @llvm.ctpop.i64 +; CHECK-NEXT: ret i64 0 } declare i64 @llvm.ctpop.i64(i64)