summaryrefslogtreecommitdiff
path: root/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-02-03 09:37:39 +0000
committerDuncan Sands <baldrick@free.fr>2011-02-03 09:37:39 +0000
commit50ca4d37f7f3b460c6441eb5ad14625a7d86b5d9 (patch)
tree240e5626072424c8c5d65d781f4ce7420d42a605 /lib/Analysis/InstructionSimplify.cpp
parentee64684710486bf8a0cd156d0516e0a7caecfb0b (diff)
downloadllvm-50ca4d37f7f3b460c6441eb5ad14625a7d86b5d9.tar.gz
llvm-50ca4d37f7f3b460c6441eb5ad14625a7d86b5d9.tar.bz2
llvm-50ca4d37f7f3b460c6441eb5ad14625a7d86b5d9.tar.xz
Improve threading of comparisons over select instructions (spotted by my
auto-simplifier). This has a big impact on Ada code, but not much else. Unfortunately the impact is mostly negative! This is due to PR9004 (aka SCCP failing to resolve conditional branch conditions in the destination blocks of the branch), in which simple correlated expressions are not resolved but complicated ones are, so simplifying has a bad effect! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124788 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 4b9b648aa6..156e785305 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -395,17 +395,39 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
assert(isa<SelectInst>(LHS) && "Not comparing with a select instruction!");
SelectInst *SI = cast<SelectInst>(LHS);
- // Now that we have "cmp select(cond, TV, FV), RHS", analyse it.
+ // Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
// Does "cmp TV, RHS" simplify?
if (Value *TCmp = SimplifyCmpInst(Pred, SI->getTrueValue(), RHS, TD, DT,
- MaxRecurse))
+ MaxRecurse)) {
// It does! Does "cmp FV, RHS" simplify?
if (Value *FCmp = SimplifyCmpInst(Pred, SI->getFalseValue(), RHS, TD, DT,
- MaxRecurse))
+ MaxRecurse)) {
// It does! If they simplified to the same value, then use it as the
// result of the original comparison.
if (TCmp == FCmp)
return TCmp;
+ Value *Cond = SI->getCondition();
+ // If the false value simplified to false, then the result of the compare
+ // is equal to "Cond && TCmp". This also catches the case when the false
+ // value simplified to false and the true value to true, returning "Cond".
+ if (match(FCmp, m_Zero()))
+ if (Value *V = SimplifyAndInst(Cond, TCmp, TD, DT, MaxRecurse))
+ return V;
+ // If the true value simplified to true, then the result of the compare
+ // is equal to "Cond || FCmp".
+ if (match(TCmp, m_One()))
+ if (Value *V = SimplifyOrInst(Cond, FCmp, TD, DT, MaxRecurse))
+ return V;
+ // Finally, if the false value simplified to true and the true value to
+ // false, then the result of the compare is equal to "!Cond".
+ if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
+ if (Value *V =
+ SimplifyXorInst(Cond, Constant::getAllOnesValue(Cond->getType()),
+ TD, DT, MaxRecurse))
+ return V;
+ }
+ }
+
return 0;
}