aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/InstructionSimplify.cpp23
-rw-r--r--lib/Target/README.txt12
-rw-r--r--test/Transforms/InstCombine/select.ll10
3 files changed, 31 insertions, 14 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index b49b4d0c6a..1955802cc6 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -252,8 +252,27 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
break;
}
}
-
-
+
+ // If the comparison is with the result of a select instruction, check whether
+ // comparing with either branch of the select always yields the same value.
+ if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS)) {
+ // Make sure the select is on the LHS.
+ if (!isa<SelectInst>(LHS)) {
+ std::swap(LHS, RHS);
+ Pred = CmpInst::getSwappedPredicate(Pred);
+ }
+ SelectInst *SI = cast<SelectInst>(LHS);
+ // Now that we have "icmp select(cond, TV, FV), RHS", analyse it.
+ // Does "icmp TV, RHS" simplify?
+ if (Value *TCmp = SimplifyICmpInst(Pred, SI->getTrueValue(), RHS, TD))
+ // It does! Does "icmp FV, RHS" simplify?
+ if (Value *FCmp = SimplifyICmpInst(Pred, SI->getFalseValue(), RHS, TD))
+ // It does! If they simplified to the same value, then use it as the
+ // result of the original comparison.
+ if (TCmp == FCmp)
+ return TCmp;
+ }
+
return 0;
}
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 55c08173d2..e63df536ae 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -1963,15 +1963,3 @@ bb3: ; preds = %entry
ret i32 %b
}
//===---------------------------------------------------------------------===//
-We should fold this code into "ret i1 false" since neither %zero nor %one can
-ever be null pointers.
-
-define i1 @foo(i1 %cond) {
- %zero = alloca i32
- %one = alloca i32
-
- %ptr = select i1 %cond, i32* %zero, i32* %one
- %isnull = icmp eq i32* %ptr, null
- ret i1 %isnull
-}
-//===---------------------------------------------------------------------===//
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 246a7bc597..c641339cbb 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -470,3 +470,13 @@ define i32 @test37(i32 %x) {
; CHECK: or i32 {{.*}}, 1
; CHECK: ret
}
+
+define i1 @test38(i1 %cond) {
+ %zero = alloca i32
+ %one = alloca i32
+ %ptr = select i1 %cond, i32* %zero, i32* %one
+ %isnull = icmp eq i32* %ptr, null
+ ret i1 %isnull
+; CHECK: @test38
+; CHECK: ret i1 false
+}