[PATCH] D114339: [InstCombine] simplify (~A | B) ^ A --> ~( A & B)
Mehrnoosh Heidarpour via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 21 13:37:41 PST 2021
MehrHeidar created this revision.
MehrHeidar added a reviewer: foad.
Herald added a subscriber: hiraditya.
MehrHeidar requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
This bug is reported at : https://bugs.llvm.org/show_bug.cgi?id=52518
According to the Alive2, https://alive2.llvm.org/ce/z/gLrYPk, the transformation seems to be correct and -O2/-O3 does not do it.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114339
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/xor.ll
Index: llvm/test/Transforms/InstCombine/xor.ll
===================================================================
--- llvm/test/Transforms/InstCombine/xor.ll
+++ llvm/test/Transforms/InstCombine/xor.ll
@@ -1231,3 +1231,59 @@
%z = xor i32 %a, %r
ret i32 %z
}
+
+; (~A | B) ^ A --> ~(A & B)
+
+define i64 @xor_orn(i64 %a, i64 %b) {
+; CHECK-LABEL: @xor_orn(
+; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Z:%.*]] = xor i64 [[TMP1]], -1
+; CHECK-NEXT: ret i64 [[Z]]
+;
+ %nota = xor i64 %a, -1
+ %l = or i64 %nota, %b
+ %z = xor i64 %l, %a
+ ret i64 %z
+}
+
+; A ^ (~A | B) --> ~(A & B)
+
+define <4 x i8> @xor_orn_commute1(<4 x i8> %a, <4 x i8> %b) {
+; CHECK-LABEL: @xor_orn_commute1(
+; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i8> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Z:%.*]] = xor <4 x i8> [[TMP1]], <i8 -1, i8 -1, i8 -1, i8 -1>
+; CHECK-NEXT: ret <4 x i8> [[Z]]
+;
+ %nota = xor <4 x i8> %a, <i8 -1, i8 -1, i8 -1, i8 -1>
+ %l = or <4 x i8> %nota, %b
+ %z = xor <4 x i8> %a, %l
+ ret <4 x i8> %z
+}
+
+; (B | ~A) ^ A --> ~(A & B)
+
+define i32 @xor_orn_commute2(i32 %a, i32 %b) {
+; CHECK-LABEL: @xor_orn_commute2(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Z:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[Z]]
+;
+ %nota = xor i32 %a, -1
+ %l = or i32 %b, %nota
+ %z = xor i32 %l, %a
+ ret i32 %z
+}
+
+; A ^ (B | ~A) --> ~(A & B)
+
+define i67 @xor_orn_commute3(i67 %a, i67 %b) {
+; CHECK-LABEL: @xor_orn_commute3(
+; CHECK-NEXT: [[TMP1:%.*]] = and i67 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Z:%.*]] = xor i67 [[TMP1]], -1
+; CHECK-NEXT: ret i67 [[Z]]
+;
+ %nota = xor i67 %a, -1
+ %l = or i67 %b, %nota
+ %z = xor i67 %a, %l
+ ret i67 %z
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3615,6 +3615,10 @@
if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
return BinaryOperator::CreateOr(A, B);
+ // (~A | B) ^ A --> ~(A & B) -- There are 4 commuted variants.
+ if (match(&I, m_c_Xor(m_c_Or(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
+ return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
+
// (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
// TODO: Loosen one-use restriction if common operand is a constant.
Value *D;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114339.388770.patch
Type: text/x-patch
Size: 2546 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211121/9e3e5ffa/attachment.bin>
More information about the llvm-commits
mailing list