summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-09-01 15:08:59 +0000
committerSanjay Patel <spatel@rotateright.com>2018-09-01 15:08:59 +0000
commit099b1a4b0c2513cffbc588012b1efcdcb67e3f2c (patch)
treeedb833f35542c0eaa7f481643d9b9bfe21b61c02 /llvm/lib/Transforms
parent454258671dbb8b528432073a091610f31b58b8c8 (diff)
downloadbcm5719-llvm-099b1a4b0c2513cffbc588012b1efcdcb67e3f2c.tar.gz
bcm5719-llvm-099b1a4b0c2513cffbc588012b1efcdcb67e3f2c.zip
[InstCombine] simplify code for 'or' fold
This is no-outwardly-visible-change intended, so no test. But the code is smaller and more efficient. The check for a 'not' op is intended to avoid the expensive value tracking call when it should not be necessary, and it might prevent infinite looping when we resurrect: rL300977 llvm-svn: 341280
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp41
1 files changed, 13 insertions, 28 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index e631e7396b1..7b8c1db77ce 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2156,37 +2156,22 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if (Instruction *FoldedLogic = foldBinOpIntoSelectOrPhi(I))
return FoldedLogic;
- // Given an OR instruction, check to see if this is a bswap.
if (Instruction *BSwap = MatchBSwap(I))
return BSwap;
- Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- {
- Value *A;
- const APInt *C;
- // (X^C)|Y -> (X|Y)^C iff Y&C == 0
- if (match(Op0, m_OneUse(m_Xor(m_Value(A), m_APInt(C)))) &&
- MaskedValueIsZero(Op1, *C, 0, &I)) {
- Value *NOr = Builder.CreateOr(A, Op1);
- NOr->takeName(Op0);
- return BinaryOperator::CreateXor(NOr,
- ConstantInt::get(NOr->getType(), *C));
- }
-
- // Y|(X^C) -> (X|Y)^C iff Y&C == 0
- if (match(Op1, m_OneUse(m_Xor(m_Value(A), m_APInt(C)))) &&
- MaskedValueIsZero(Op0, *C, 0, &I)) {
- Value *NOr = Builder.CreateOr(A, Op0);
- NOr->takeName(Op0);
- return BinaryOperator::CreateXor(NOr,
- ConstantInt::get(NOr->getType(), *C));
- }
+ Value *X, *Y;
+ const APInt *CV;
+ if (match(&I, m_c_Or(m_OneUse(m_Xor(m_Value(X), m_APInt(CV))), m_Value(Y))) &&
+ !CV->isAllOnesValue() && MaskedValueIsZero(Y, *CV, 0, &I)) {
+ // (X ^ C) | Y -> (X | Y) ^ C iff Y & C == 0
+ // The check for a 'not' op is for efficiency (if Y is known zero --> ~X).
+ Value *Or = Builder.CreateOr(X, Y);
+ return BinaryOperator::CreateXor(Or, ConstantInt::get(I.getType(), *CV));
}
- Value *A, *B;
-
// (A & C)|(B & D)
- Value *C = nullptr, *D = nullptr;
+ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ Value *A, *B, *C, *D;
if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
match(Op1, m_And(m_Value(B), m_Value(D)))) {
ConstantInt *C1 = dyn_cast<ConstantInt>(C);
@@ -2378,12 +2363,12 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
// be simplified by a later pass either, so we try swapping the inner/outer
// ORs in the hopes that we'll be able to simplify it this way.
// (X|C) | V --> (X|V) | C
- ConstantInt *C1;
+ ConstantInt *CI;
if (Op0->hasOneUse() && !isa<ConstantInt>(Op1) &&
- match(Op0, m_Or(m_Value(A), m_ConstantInt(C1)))) {
+ match(Op0, m_Or(m_Value(A), m_ConstantInt(CI)))) {
Value *Inner = Builder.CreateOr(A, Op1);
Inner->takeName(Op0);
- return BinaryOperator::CreateOr(Inner, C1);
+ return BinaryOperator::CreateOr(Inner, CI);
}
// Change (or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D))
OpenPOWER on IntegriCloud