summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-06-27 17:53:22 +0000
committerSanjay Patel <spatel@rotateright.com>2017-06-27 17:53:22 +0000
commit7227276d4144da8310496286b314fe33f1cfa51d (patch)
treea0fe23a1fd36c2232f8a45bd50dac11d1b6accba /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
parent874bc749a20f14d6fc30e43038b3c99d6c40c4a9 (diff)
downloadbcm5719-llvm-7227276d4144da8310496286b314fe33f1cfa51d.tar.gz
bcm5719-llvm-7227276d4144da8310496286b314fe33f1cfa51d.zip
[InstCombine] canonicalize icmp predicate feeding select
This canonicalization was suggested in D33172 as a way to make InstCombine behavior more uniform. We have this transform for icmp+br, so unless there's some reason that icmp+select should be treated differently, we should do the same thing here. The benefit comes from increasing the chances of creating identical instructions. This is shown in the tests in logical-select.ll (PR32791). InstCombine doesn't fold those directly, but EarlyCSE can simplify the identical cmps, and then InstCombine can fold the selects together. The possible regression for the tests in select.ll raises questions about poison/undef: http://lists.llvm.org/pipermail/llvm-dev/2017-May/113261.html ...but that transform is just as likely to be triggered by this canonicalization as it is to be missed, so we're just pointing out a commutation deficiency in the pattern matching: https://reviews.llvm.org/rL228409 Differential Revision: https://reviews.llvm.org/D34242 llvm-svn: 306435
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 33951e66497..80c6595904e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1167,6 +1167,23 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
if (Instruction *I = canonicalizeSelectToShuffle(SI))
return I;
+ // Canonicalize a one-use integer compare with a non-canonical predicate by
+ // inverting the predicate and swapping the select operands. This matches a
+ // compare canonicalization for conditional branches.
+ // TODO: Should we do the same for FP compares?
+ CmpInst::Predicate Pred;
+ if (match(CondVal, m_OneUse(m_ICmp(Pred, m_Value(), m_Value()))) &&
+ !isCanonicalPredicate(Pred)) {
+ // Swap true/false values and condition.
+ CmpInst *Cond = cast<CmpInst>(CondVal);
+ Cond->setPredicate(CmpInst::getInversePredicate(Pred));
+ SI.setOperand(1, FalseVal);
+ SI.setOperand(2, TrueVal);
+ SI.swapProfMetadata();
+ Worklist.Add(Cond);
+ return &SI;
+ }
+
if (SelType->getScalarType()->isIntegerTy(1) &&
TrueVal->getType() == CondVal->getType()) {
if (match(TrueVal, m_One())) {
OpenPOWER on IntegriCloud