summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2010-07-12 11:54:45 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2010-07-12 11:54:45 +0000
commit35473faa5056aa3888ac20091f76fece02367f44 (patch)
tree241dff03b0e0134af63f22816e1b3fd4ff8fa229 /llvm/lib/Transforms
parentf9610827ced751eddcbf1b6f9db2abc987b24c53 (diff)
downloadbcm5719-llvm-35473faa5056aa3888ac20091f76fece02367f44.tar.gz
bcm5719-llvm-35473faa5056aa3888ac20091f76fece02367f44.zip
instcombine: fold (x & y) | (~x & z) and (x & y) ^ (~x & z) into ((y ^ z) & x) ^ z which is one instruction shorter. (PR6773)
before: %and = and i32 %y, %x %neg = xor i32 %x, -1 %and4 = and i32 %z, %neg %xor = xor i32 %and4, %and after: %xor1 = xor i32 %z, %y %and2 = and i32 %xor1, %x %xor = xor i32 %and2, %z llvm-svn: 108136
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 8586054fce0..3bfeba11cc2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1584,6 +1584,14 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
if ((match(A, m_Not(m_Specific(B))) &&
match(D, m_Not(m_Specific(C)))))
return BinaryOperator::CreateXor(C, B);
+
+ // (A & ~C) | (B & C) -> ((B ^ A) & C) ^ A
+ if (Op0->hasOneUse() && Op1->hasOneUse() &&
+ match(C, m_Not(m_Specific(D)))) {
+ Value *Xor = Builder->CreateXor(B, A, "xor");
+ Value *And = Builder->CreateAnd(Xor, D, "and");
+ return BinaryOperator::CreateXor(And, A);
+ }
}
// (X >> Z) | (Y >> Z) -> (X|Y) >> Z for all shifts.
@@ -1920,6 +1928,15 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
return BinaryOperator::CreateAnd(NewOp, X);
}
}
+
+ // (A & ~C) ^ (B & C) -> ((B ^ A) & C) ^ A
+ if (Op0->hasOneUse() && Op1->hasOneUse() &&
+ match(Op0I, m_And(m_Value(A), m_Not(m_Value(D)))) &&
+ match(Op1I, m_And(m_Value(B), m_Value(D)))) {
+ Value *Xor = Builder->CreateXor(B, A, "xor");
+ Value *And = Builder->CreateAnd(Xor, D, "and");
+ return BinaryOperator::CreateXor(And, A);
+ }
}
// (icmp1 A, B) ^ (icmp2 A, B) --> (icmp3 A, B)
OpenPOWER on IntegriCloud