summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-01-05 03:04:57 +0000
committerChris Lattner <sabre@nondot.org>2007-01-05 03:04:57 +0000
commit17c7c030c208b95a2fa7494423238e364cfdb554 (patch)
tree871efa0dd8bc31a05691e101714657112d1a9b0e /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parent130fff0d0352d697eed6d4c0972abbe5afd4aa03 (diff)
downloadbcm5719-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.cpp45
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))) &&
OpenPOWER on IntegriCloud