[PATCH] D159372: [InstCombine] Fold ((A&B)^A)|((A&B)^B) to A^B
Marc Auberer via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 1 12:40:47 PDT 2023
marcauberer created this revision.
marcauberer added reviewers: GabrielRavier, RKSimon.
Herald added a subscriber: hiraditya.
Herald added a project: All.
marcauberer requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
((A & B) ^ A) | ((A & B) ^ B) -> A ^ B
((A & B) ^ B) | ((A & B) ^ A) -> A ^ B
Alive2: https://alive2.llvm.org/ce/z/i44xmq
Baseline tests: https://reviews.llvm.org/D159371
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D159372
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/or-xor-xor.ll
Index: llvm/test/Transforms/InstCombine/or-xor-xor.ll
===================================================================
--- llvm/test/Transforms/InstCombine/or-xor-xor.ll
+++ llvm/test/Transforms/InstCombine/or-xor-xor.ll
@@ -5,10 +5,7 @@
define i1 @or_xor_xor_normal_variant1(i1 %a, i1 %b) {
; CHECK-LABEL: @or_xor_xor_normal_variant1(
-; CHECK-NEXT: [[AND:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[XOR1:%.*]] = xor i1 [[AND]], [[A]]
-; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[AND]], [[B]]
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[XOR1]], [[XOR2]]
+; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%and = and i1 %a, %b
@@ -20,10 +17,7 @@
define i1 @or_xor_xor_normal_variant2(i1 %a, i1 %b) {
; CHECK-LABEL: @or_xor_xor_normal_variant2(
-; CHECK-NEXT: [[AND:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[XOR1:%.*]] = xor i1 [[AND]], [[B]]
-; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[AND]], [[A]]
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[XOR1]], [[XOR2]]
+; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%and = and i1 %a, %b
@@ -35,10 +29,7 @@
define <3 x i1> @or_xor_xor_normal_vector(<3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_xor_xor_normal_vector(
-; CHECK-NEXT: [[AND:%.*]] = and <3 x i1> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[XOR1:%.*]] = xor <3 x i1> [[AND]], [[B]]
-; CHECK-NEXT: [[XOR2:%.*]] = xor <3 x i1> [[AND]], [[A]]
-; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[XOR1]], [[XOR2]]
+; CHECK-NEXT: [[OR:%.*]] = xor <3 x i1> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%and = and <3 x i1> %a, %b
@@ -52,9 +43,7 @@
; CHECK-LABEL: @or_xor_xor_normal_multiple_uses_and(
; CHECK-NEXT: [[AND:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @use(i1 [[AND]])
-; CHECK-NEXT: [[XOR1:%.*]] = xor i1 [[AND]], [[B]]
-; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[AND]], [[A]]
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[XOR1]], [[XOR2]]
+; CHECK-NEXT: [[OR:%.*]] = xor i1 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[OR]]
;
%and = and i1 %a, %b
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3650,6 +3650,24 @@
}
}
+ {
+ // ((A & B) ^ A) | ((A & B) ^ B) -> A ^ B
+ if (match(Op0,
+ m_OneUse(m_Xor(m_And(m_Value(A), m_Value(B)), m_Deferred(A)))) &&
+ match(Op1, m_OneUse(m_Xor(m_And(m_Specific(A), m_Specific(B)),
+ m_Deferred(B))))) {
+ return BinaryOperator::CreateXor(A, B);
+ }
+
+ // ((A & B) ^ B) | ((A & B) ^ A) -> A ^ B
+ if (match(Op0,
+ m_OneUse(m_Xor(m_And(m_Value(A), m_Value(B)), m_Deferred(B)))) &&
+ match(Op1, m_OneUse(m_Xor(m_And(m_Specific(A), m_Specific(B)),
+ m_Deferred(A))))) {
+ return BinaryOperator::CreateXor(A, B);
+ }
+ }
+
if (Instruction *V =
canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159372.555460.patch
Type: text/x-patch
Size: 3203 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230901/7c7fcda9/attachment.bin>
More information about the llvm-commits
mailing list