diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2018-04-30 17:59:33 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2018-04-30 17:59:33 +0000 |
commit | aa4faec114db654772b245f5f875d47ca14666d7 (patch) | |
tree | 7012d647db62dc8461472d59427006e29a2d66f3 /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
parent | b7ae4ef82b45916f9fc2a4408caf69e04bec9a60 (diff) | |
download | bcm5719-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/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 16 |
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; } |