[PATCH] D118094: [InstCombine] Implementing (x & y) + ~(x | y) -> ~(x ^ y)

Chuanqi Xu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 25 02:27:46 PST 2022


ChuanqiXu updated this revision to Diff 402810.
ChuanqiXu added a comment.

Address comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118094/new/

https://reviews.llvm.org/D118094

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
  llvm/test/Transforms/InstCombine/pr53357.ll


Index: llvm/test/Transforms/InstCombine/pr53357.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/pr53357.ll
@@ -0,0 +1,61 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; Test for (x & y) + ~(x | y) -> ~(x ^ y)
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; (x & y) + ~(x | y)
+define i32 @src(i32 %0, i32 %1) {
+; CHECK-LABEL: @src(
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP1:%.*]], [[TMP0:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1
+; CHECK-NEXT:    ret i32 [[TMP4]]
+;
+  %3 = and i32 %1, %0
+  %4 = or i32 %1, %0
+  %5 = xor i32 %4, -1
+  %6 = add i32 %3, %5
+  ret i32 %6
+}
+
+; (x & y) + (~x & ~y)
+define i32 @src2(i32 %0, i32 %1) {
+; CHECK-LABEL: @src2(
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1
+; CHECK-NEXT:    ret i32 [[TMP4]]
+;
+  %3 = and i32 %1, %0
+  %4 = xor i32 %0, -1
+  %5 = xor i32 %1, -1
+  %6 = and i32 %4, %5
+  %7 = add i32 %3, %6
+  ret i32 %7
+}
+
+; ~(x | y) + (x & y)
+define i32 @src3(i32 %0, i32 %1) {
+; CHECK-LABEL: @src3(
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP1:%.*]], [[TMP0:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1
+; CHECK-NEXT:    ret i32 [[TMP4]]
+;
+  %3 = or i32 %1, %0
+  %4 = xor i32 %3, -1
+  %5 = and i32 %1, %0
+  %6 = add i32 %4, %5
+  ret i32 %6
+}
+
+; (x & y) + (~x & ~y)
+define i32 @src4(i32 %0, i32 %1) {
+; CHECK-LABEL: @src4(
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1
+; CHECK-NEXT:    ret i32 [[TMP4]]
+;
+  %3 = xor i32 %0, -1
+  %4 = xor i32 %1, -1
+  %5 = and i32 %3, %4
+  %6 = and i32 %1, %0
+  %7 = add i32 %5, %6
+  ret i32 %7
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1342,6 +1342,11 @@
       match(&I, m_BinOp(m_c_Add(m_Not(m_Value(B)), m_Value(A)), m_One())))
     return BinaryOperator::CreateSub(A, B);
 
+  // (A & B) + ~(A | B) --> ~(A ^ B)
+  if (match(&I, m_c_BinOp(m_And(m_Value(A), m_Value(B)),
+                          m_Not(m_Or(m_Value(A), m_Value(B))))))
+    return BinaryOperator::CreateNot(Builder.CreateXor(A, B));
+
   // (A + RHS) + RHS --> A + (RHS << 1)
   if (match(LHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(RHS)))))
     return BinaryOperator::CreateAdd(A, Builder.CreateShl(RHS, 1, "reass.add"));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118094.402810.patch
Type: text/x-patch
Size: 2625 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220125/693f0eb1/attachment.bin>


More information about the llvm-commits mailing list