[PATCH] D105013: [InstCombine] try to fold the expression "(A & ~B) + B" to "A ^ B"
Yifeng Dong via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 28 04:41:42 PDT 2021
dongAxis1944 created this revision.
Herald added a subscriber: hiraditya.
dongAxis1944 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Summary
Since llvm will generate the following ir:
define i32 @and_to_xor1(i32 %0, i32 %1) local_unnamed_addr #0 {
%3 = shl nsw i32 %0, 1
%4 = mul nsw i32 %1, %0
%5 = xor i32 %4, -1
%6 = and i32 %3, %5
%7 = add nsw i32 %6, %4
ret i32 %7
}
but InstCombine can not simplify this code shape.
So I use this patch to achieve this.
Test Plan:
check-llvm
https://reviews.llvm.org/D105013
Files:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/test/Transforms/InstCombine/and-to-xor.ll
Index: llvm/test/Transforms/InstCombine/and-to-xor.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/and-to-xor.ll
@@ -0,0 +1,28 @@
+; Try to fold (A & ~B) + B to A ^ B
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; CHECK: define i32 @and_to_xor1(i32 %0, i32 %1) local_unnamed_addr
+; CHECK-NOT: %{{[0-9]+}} = xor i32 %{{[0-9]+}}, -1
+; CHECK-NOT: %{{[0-9]+}} = and i32 %{{[0-9]+}}, %{{[0-9]+}}
+; CHECK: %{{[0-9]+}} = xor i32 %{{[0-9]+}}, %{{[0-9]+}}
+define i32 @and_to_xor1(i32 %0, i32 %1) local_unnamed_addr #0 {
+ %3 = shl nsw i32 %0, 1
+ %4 = mul nsw i32 %1, %0
+ %5 = xor i32 %4, -1
+ %6 = and i32 %3, %5
+ %7 = add nsw i32 %6, %4
+ ret i32 %7
+}
+
+; CHECK: define i32 @and_to_xor2(i32 %0, i32 %1)
+; CHECK-NOT: %{{[0-9]+}} = xor i32 %{{[0-9]+}}, -1
+; CHECK-NOT: %{{[0-9]+}} = and i32 %{{[0-9]+}}, %{{[0-9]+}}
+; CHECK: %{{[0-9]+}} = xor i32 %{{[0-9]+}}, %{{[0-9]+}}
+define i32 @and_to_xor2(i32 %0, i32 %1) local_unnamed_addr #0 {
+ %3 = shl nsw i32 %0, 1
+ %4 = mul nsw i32 %1, %0
+ %5 = xor i32 %4, -1
+ %6 = and i32 %3, %5
+ %7 = add nsw i32 %4, %6
+ ret i32 %7
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineInternal.h
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -620,6 +620,7 @@
Instruction *foldBinOpIntoSelectOrPhi(BinaryOperator &I);
Instruction *foldAddWithConstant(BinaryOperator &Add);
+ Instruction *foldAddWithXor(BinaryOperator &Add);
/// Try to rotate an operation below a PHI node, using PHI nodes for
/// its operands.
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -861,6 +861,18 @@
return nullptr;
}
+// fold (A & ~B) + B to A ^ B
+Instruction *InstCombinerImpl::foldAddWithXor(BinaryOperator &Add) {
+ Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
+ Value *A = nullptr;
+ if (match(Op0, m_c_And(m_Not(m_Specific(Op1)), m_Value(A))))
+ return BinaryOperator::CreateXor(A, Op1);
+
+ if (match(Op1, m_c_And(m_Not(m_Specific(Op0)), m_Value(A))))
+ return BinaryOperator::CreateXor(Op0, A);
+ return nullptr;
+}
+
Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
Constant *Op1C;
@@ -1309,6 +1321,9 @@
if (Instruction *X = foldNoWrapAdd(I, Builder))
return X;
+ if (Instruction *X = foldAddWithXor(I))
+ return X;
+
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
Type *Ty = I.getType();
if (Ty->isIntOrIntVectorTy(1))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105013.354844.patch
Type: text/x-patch
Size: 2850 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210628/1ad2767d/attachment.bin>
More information about the llvm-commits
mailing list