// 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;
--- /dev/null
+; 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
+}
; 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)