diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-01-05 03:04:57 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-01-05 03:04:57 +0000 |
| commit | 17c7c030c208b95a2fa7494423238e364cfdb554 (patch) | |
| tree | 871efa0dd8bc31a05691e101714657112d1a9b0e /llvm/lib/Transforms/Scalar/InstructionCombining.cpp | |
| parent | 130fff0d0352d697eed6d4c0972abbe5afd4aa03 (diff) | |
| download | bcm5719-llvm-17c7c030c208b95a2fa7494423238e364cfdb554.tar.gz bcm5719-llvm-17c7c030c208b95a2fa7494423238e364cfdb554.zip | |
fold things like a^b != c^a -> b != c. This implements InstCombine/xor.ll:test27
llvm-svn: 32893
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index aba50dca3e7..c1a331faecb 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5173,30 +5173,51 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { } if (I.isEquality()) { - Value *A, *B; - if (match(Op0, m_Xor(m_Value(A), m_Value(B))) && - (A == Op1 || B == Op1)) { - // (A^B) == A -> B == 0 - Value *OtherVal = A == Op1 ? B : A; - return new ICmpInst(I.getPredicate(), OtherVal, - Constant::getNullValue(A->getType())); - } else if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && - (A == Op0 || B == Op0)) { + Value *A, *B, *C, *D; + if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) { + if (A == Op1 || B == Op1) { // (A^B) == A -> B == 0 + Value *OtherVal = A == Op1 ? B : A; + return new ICmpInst(I.getPredicate(), OtherVal, + Constant::getNullValue(A->getType())); + } + + if (match(Op1, m_Xor(m_Value(C), m_Value(D)))) { + // A^c1 == C^c2 --> A == C^(c1^c2) + if (ConstantInt *C1 = dyn_cast<ConstantInt>(B)) + if (ConstantInt *C2 = dyn_cast<ConstantInt>(D)) + if (Op1->hasOneUse()) { + Constant *NC = ConstantExpr::getXor(C1, C2); + Instruction *Xor = BinaryOperator::createXor(C, NC, "tmp"); + return new ICmpInst(I.getPredicate(), A, + InsertNewInstBefore(Xor, I)); + } + + // A^B == A^D -> B == D + if (A == C) return new ICmpInst(I.getPredicate(), B, D); + if (A == D) return new ICmpInst(I.getPredicate(), B, C); + if (B == C) return new ICmpInst(I.getPredicate(), A, D); + if (B == D) return new ICmpInst(I.getPredicate(), A, C); + } + } + + if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && + (A == Op0 || B == Op0)) { // A == (A^B) -> B == 0 Value *OtherVal = A == Op0 ? B : A; return new ICmpInst(I.getPredicate(), OtherVal, Constant::getNullValue(A->getType())); - } else if (match(Op0, m_Sub(m_Value(A), m_Value(B))) && A == Op1) { + } + if (match(Op0, m_Sub(m_Value(A), m_Value(B))) && A == Op1) { // (A-B) == A -> B == 0 return new ICmpInst(I.getPredicate(), B, Constant::getNullValue(B->getType())); - } else if (match(Op1, m_Sub(m_Value(A), m_Value(B))) && A == Op0) { + } + if (match(Op1, m_Sub(m_Value(A), m_Value(B))) && A == Op0) { // A == (A-B) -> B == 0 return new ICmpInst(I.getPredicate(), B, Constant::getNullValue(B->getType())); } - Value *C, *D; // (X&Z) == (Y&Z) -> (X^Y) & Z == 0 if (Op0->hasOneUse() && Op1->hasOneUse() && match(Op0, m_And(m_Value(A), m_Value(B))) && |

