summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuyog Sarda <suyog.sarda@samsung.com>2014-07-22 18:30:54 +0000
committerSuyog Sarda <suyog.sarda@samsung.com>2014-07-22 18:30:54 +0000
commitb60ec909ca4d6bdd6d5a9ac8795f91b311c17cf5 (patch)
treeb386f2dba060656fbcd67590edd89e48b5829bdc
parentd64faf6cae5eae40e8cbea132b126ecb710aa9ec (diff)
downloadbcm5719-llvm-b60ec909ca4d6bdd6d5a9ac8795f91b311c17cf5.tar.gz
bcm5719-llvm-b60ec909ca4d6bdd6d5a9ac8795f91b311c17cf5.zip
Added InstCombine transform for pattern "(A & B) ^ (A ^ B) -> (A | B)"
Patch idea by Ankit Jain ! Differential Revision: http://reviews.llvm.org/D4618 llvm-svn: 213677
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/xor2.ll20
2 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index ef6a848357e..718cf29f184 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2454,6 +2454,14 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
if ((A == C && B == D) || (A == D && B == C))
return BinaryOperator::CreateXor(A, B);
}
+ // (A & B) ^ (A ^ B) -> (A | B)
+ if (match(Op0I, m_And(m_Value(A), m_Value(B))) &&
+ match(Op1I, m_Xor(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateOr(A, B);
+ // (A ^ B) ^ (A & B) -> (A | B)
+ if (match(Op0I, m_Xor(m_Value(A), m_Value(B))) &&
+ match(Op1I, m_And(m_Specific(A), m_Specific(B))))
+ return BinaryOperator::CreateOr(A, B);
}
// (A | B)^(~A) -> (A | ~B)
diff --git a/llvm/test/Transforms/InstCombine/xor2.ll b/llvm/test/Transforms/InstCombine/xor2.ll
index e7b1b1bbda8..4ae50a140e1 100644
--- a/llvm/test/Transforms/InstCombine/xor2.ll
+++ b/llvm/test/Transforms/InstCombine/xor2.ll
@@ -105,3 +105,23 @@ define i32 @test8(i32 %a, i32 %b) #0 {
; CHECK-NEXT: %1 = xor i32 %b, -1
; CHECK-NEXT: %xor = or i32 %a, %1
}
+
+; (A & B) ^ (A ^ B) -> (A | B)
+define i32 @test9(i32 %b, i32 %c) {
+ %and = and i32 %b, %c
+ %xor = xor i32 %b, %c
+ %xor2 = xor i32 %and, %xor
+ ret i32 %xor2
+; CHECK-LABEL: @test9(
+; CHECK-NEXT: %xor2 = or i32 %b, %c
+}
+
+; (A ^ B) ^ (A & B) -> (A | B)
+define i32 @test10(i32 %b, i32 %c) {
+ %xor = xor i32 %b, %c
+ %and = and i32 %b, %c
+ %xor2 = xor i32 %xor, %and
+ ret i32 %xor2
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: %xor2 = or i32 %b, %c
+}
OpenPOWER on IntegriCloud