summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2018-04-30 17:59:33 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2018-04-30 17:59:33 +0000
commitaa4faec114db654772b245f5f875d47ca14666d7 (patch)
tree7012d647db62dc8461472d59427006e29a2d66f3 /llvm/lib
parentb7ae4ef82b45916f9fc2a4408caf69e04bec9a60 (diff)
downloadbcm5719-llvm-aa4faec114db654772b245f5f875d47ca14666d7.tar.gz
bcm5719-llvm-aa4faec114db654772b245f5f875d47ca14666d7.zip
[InstCombine] Unfold masked merge with constant mask
Summary: As discussed in D45733, we want to do this in InstCombine. https://rise4fun.com/Alive/LGk Reviewers: spatel, craig.topper Reviewed By: spatel Subscribers: chandlerc, xbolva00, llvm-commits Differential Revision: https://reviews.llvm.org/D45867 llvm-svn: 331205
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 5d9e6abf629..e389af2a2e3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2412,14 +2412,19 @@ Value *InstCombiner::foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
}
/// If we have a masked merge, in the canonical form of:
+/// (assuming that A only has one use.)
/// | A | |B|
/// ((x ^ y) & M) ^ y
/// | D |
/// * If M is inverted:
/// | D |
/// ((x ^ y) & ~M) ^ y
-/// If A has one use, and, we want to canonicalize it to non-inverted mask:
+/// We can canonicalize by swapping the final xor operand
+/// to eliminate the 'not' of the mask.
/// ((x ^ y) & M) ^ x
+/// * If M is a constant, and D has one use, we transform to 'and' / 'or' ops
+/// because that shortens the dependency chain and improves analysis:
+/// (x & M) | (y & ~M)
static Instruction *visitMaskedMerge(BinaryOperator &I,
InstCombiner::BuilderTy &Builder) {
Value *B, *X, *D;
@@ -2438,6 +2443,15 @@ static Instruction *visitMaskedMerge(BinaryOperator &I,
return BinaryOperator::CreateXor(NewA, X);
}
+ Constant *C;
+ if (D->hasOneUse() && match(M, m_Constant(C))) {
+ // Unfold.
+ Value *LHS = Builder.CreateAnd(X, C);
+ Value *NotC = Builder.CreateNot(C);
+ Value *RHS = Builder.CreateAnd(B, NotC);
+ return BinaryOperator::CreateOr(LHS, RHS);
+ }
+
return nullptr;
}
OpenPOWER on IntegriCloud