summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2017-08-10 20:35:34 +0000
committerCraig Topper <craig.topper@intel.com>2017-08-10 20:35:34 +0000
commit9a6110b2d3ea6c037923aff08c21e047999c5a47 (patch)
tree6ad00a591fe320f4f8f857af817e2f8179ed699d /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
parent699ae0c173bd9f9a38523a7de354f5e9cc602ecc (diff)
downloadbcm5719-llvm-9a6110b2d3ea6c037923aff08c21e047999c5a47.tar.gz
bcm5719-llvm-9a6110b2d3ea6c037923aff08c21e047999c5a47.zip
[InstCombine] Make (X|C1)^C2 -> X^(C1^C2) iff X&~C1 == 0 work for splat vectors
This also corrects the description to match what was actually implemented. The old comment said X^(C1|C2), but it implemented X^((C1|C2)&~(C1&C2)). I believe ((C1|C2)&~(C1&C2)) is equivalent to (C1^C2). Differential Revision: https://reviews.llvm.org/D36505 llvm-svn: 310658
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp41
1 files changed, 18 insertions, 23 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index bc8b0496ec7..5a13bbce835 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2365,53 +2365,48 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
{
const APInt *RHSC;
if (match(Op1, m_APInt(RHSC))) {
- Value *V;
+ Value *X;
const APInt *C;
- if (match(Op0, m_Sub(m_APInt(C), m_Value(V)))) {
+ if (match(Op0, m_Sub(m_APInt(C), m_Value(X)))) {
// ~(c-X) == X-c-1 == X+(-c-1)
if (RHSC->isAllOnesValue()) {
Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1);
- return BinaryOperator::CreateAdd(V, NewC);
+ return BinaryOperator::CreateAdd(X, NewC);
}
if (RHSC->isSignMask()) {
// (C - X) ^ signmask -> (C + signmask - X)
Constant *NewC = ConstantInt::get(I.getType(), *C + *RHSC);
- return BinaryOperator::CreateSub(NewC, V);
+ return BinaryOperator::CreateSub(NewC, X);
}
- } else if (match(Op0, m_Add(m_Value(V), m_APInt(C)))) {
+ } else if (match(Op0, m_Add(m_Value(X), m_APInt(C)))) {
// ~(X-c) --> (-c-1)-X
if (RHSC->isAllOnesValue()) {
Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1);
- return BinaryOperator::CreateSub(NewC, V);
+ return BinaryOperator::CreateSub(NewC, X);
}
if (RHSC->isSignMask()) {
// (X + C) ^ signmask -> (X + C + signmask)
Constant *NewC = ConstantInt::get(I.getType(), *C + *RHSC);
- return BinaryOperator::CreateAdd(V, NewC);
+ return BinaryOperator::CreateAdd(X, NewC);
}
}
+
+ // (X|C1)^C2 -> X^(C1^C2) iff X&~C1 == 0
+ if (match(Op0, m_Or(m_Value(X), m_APInt(C))) &&
+ MaskedValueIsZero(X, *C, 0, &I)) {
+ Constant *NewC = ConstantInt::get(I.getType(), *C ^ *RHSC);
+ Worklist.Add(cast<Instruction>(Op0));
+ I.setOperand(0, X);
+ I.setOperand(1, NewC);
+ return &I;
+ }
}
}
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(Op1)) {
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
- if (Op0I->getOpcode() == Instruction::Or) {
- // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0
- if (MaskedValueIsZero(Op0I->getOperand(0), Op0CI->getValue(),
- 0, &I)) {
- Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHSC);
- // Anything in both C1 and C2 is known to be zero, remove it from
- // NewRHS.
- Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHSC);
- NewRHS = ConstantExpr::getAnd(NewRHS,
- ConstantExpr::getNot(CommonBits));
- Worklist.Add(Op0I);
- I.setOperand(0, Op0I->getOperand(0));
- I.setOperand(1, NewRHS);
- return &I;
- }
- } else if (Op0I->getOpcode() == Instruction::LShr) {
+ if (Op0I->getOpcode() == Instruction::LShr) {
// ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
// E1 = "X ^ C1"
BinaryOperator *E1;
OpenPOWER on IntegriCloud