[llvm] f7ab70c - [InstCombine] reduce disguised mul+add factorization

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 24 13:03:46 PDT 2022


Author: Sanjay Patel
Date: 2022-08-24T16:02:12-04:00
New Revision: f7ab70cf8df6117312a2b76588269b9a1269a620

URL: https://github.com/llvm/llvm-project/commit/f7ab70cf8df6117312a2b76588269b9a1269a620
DIFF: https://github.com/llvm/llvm-project/commit/f7ab70cf8df6117312a2b76588269b9a1269a620.diff

LOG: [InstCombine] reduce disguised mul+add factorization

~(A * C1) + A --> (A * (1 - C1)) - 1

This is a non-obvious mix of bitwise logic and math:
https://alive2.llvm.org/ce/z/U7ACVT

The pattern may be produced by Negator from the more typical
code seen in issue #57255.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/add.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 8dfe72e36b728..b02405c067f55 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1426,6 +1426,20 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
     return BinaryOperator::CreateAnd(Dec, Not);
   }
 
+  // Disguised reassociation/factorization:
+  // ~(A * C1) + A
+  // ((A * -C1) - 1) + A
+  // ((A * -C1) + A) - 1
+  // (A * (1 - C1)) - 1
+  if (match(&I,
+            m_c_Add(m_OneUse(m_Not(m_OneUse(m_Mul(m_Value(A), m_APInt(C1))))),
+                    m_Deferred(A)))) {
+    Type *Ty = I.getType();
+    Constant *NewMulC = ConstantInt::get(Ty, 1 - *C1);
+    Value *NewMul = Builder.CreateMul(A, NewMulC);
+    return BinaryOperator::CreateAdd(NewMul, ConstantInt::getAllOnesValue(Ty));
+  }
+
   // TODO(jingyue): Consider willNotOverflowSignedAdd and
   // willNotOverflowUnsignedAdd to reduce the number of invocations of
   // computeKnownBits.

diff  --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 85995dd16847b..81e2dadc143a8 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -1825,9 +1825,8 @@ define i8 @mul_add_common_factor_use(i8 %x, i8 %y) {
 
 define i8 @not_mul(i8 %x) {
 ; CHECK-LABEL: @not_mul(
-; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
-; CHECK-NEXT:    [[PLUSX:%.*]] = add nsw i8 [[NOT]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[X:%.*]], -41
+; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[TMP1]], -1
 ; CHECK-NEXT:    ret i8 [[PLUSX]]
 ;
   %mul = mul nsw i8 %x, 42
@@ -1839,9 +1838,8 @@ define i8 @not_mul(i8 %x) {
 define <2 x i8> @not_mul_commute(<2 x i8> %p) {
 ; CHECK-LABEL: @not_mul_commute(
 ; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw <2 x i8> [[X]], <i8 -42, i8 -42>
-; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i8> [[MUL]], <i8 -1, i8 -1>
-; CHECK-NEXT:    [[PLUSX:%.*]] = add nuw <2 x i8> [[X]], [[NOT]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i8> [[X]], <i8 43, i8 43>
+; CHECK-NEXT:    [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], <i8 -1, i8 -1>
 ; CHECK-NEXT:    ret <2 x i8> [[PLUSX]]
 ;
   %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
@@ -1851,6 +1849,23 @@ define <2 x i8> @not_mul_commute(<2 x i8> %p) {
   ret <2 x i8> %plusx
 }
 
+; negative test - need common operand
+
+define i8 @not_mul_wrong_op(i8 %x, i8 %y) {
+; CHECK-LABEL: @not_mul_wrong_op(
+; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
+; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[NOT]], [[Y:%.*]]
+; CHECK-NEXT:    ret i8 [[PLUSX]]
+;
+  %mul = mul i8 %x, 42
+  %not = xor i8 %mul, -1
+  %plusx = add i8 %not, %y
+  ret i8 %plusx
+}
+
+; negative test - avoid creating an extra mul
+
 define i8 @not_mul_use1(i8 %x) {
 ; CHECK-LABEL: @not_mul_use1(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42
@@ -1866,6 +1881,8 @@ define i8 @not_mul_use1(i8 %x) {
   ret i8 %plusx
 }
 
+; negative test - too many instructions
+
 define i8 @not_mul_use2(i8 %x) {
 ; CHECK-LABEL: @not_mul_use2(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42


        


More information about the llvm-commits mailing list