[PATCH] D114729: [InstCombine] try to fold 'or' into 'mul' operand

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 29 11:24:06 PST 2021


spatel created this revision.
spatel added reviewers: RKSimon, lebedev.ri, OmerAviram.
Herald added subscribers: hiraditya, mcrosier.
spatel requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

or (mul X, C), X --> mul X, C+1  (when the multiply has no common bits with X)

We already have this fold if the pattern ends in 'add', but we can miss it if the 'add' becomes 'or' via another no-common-bits transform:

This is part of fixing:
http://llvm.org/PR49055
...but it won't make a difference on that example yet.

https://alive2.llvm.org/ce/z/Vrmoeb


https://reviews.llvm.org/D114729

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/or.ll


Index: llvm/test/Transforms/InstCombine/or.ll
===================================================================
--- llvm/test/Transforms/InstCombine/or.ll
+++ llvm/test/Transforms/InstCombine/or.ll
@@ -1445,8 +1445,7 @@
 define i32 @mul_no_common_bits(i32 %p) {
 ; CHECK-LABEL: @mul_no_common_bits(
 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
-; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 24
-; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[X]], 25
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %x = and i32 %p, 7
@@ -1458,8 +1457,7 @@
 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
 ; CHECK-LABEL: @mul_no_common_bits_commute(
 ; CHECK-NEXT:    [[X:%.*]] = and <2 x i12> [[P:%.*]], <i12 1, i12 1>
-; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw <2 x i12> [[X]], <i12 14, i12 14>
-; CHECK-NEXT:    [[R:%.*]] = or <2 x i12> [[X]], [[M]]
+; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <2 x i12> [[X]], <i12 15, i12 15>
 ; CHECK-NEXT:    ret <2 x i12> [[R]]
 ;
   %x = and <2 x i12> %p, <i12 1, i12 1>
@@ -1468,6 +1466,8 @@
   ret <2 x i12> %r
 }
 
+; negative test - probably not good to create an extra mul
+
 define i32 @mul_no_common_bits_uses(i32 %p) {
 ; CHECK-LABEL: @mul_no_common_bits_uses(
 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
@@ -1482,3 +1482,18 @@
   %r = or i32 %m, %x
   ret i32 %r
 }
+
+; negative test - %x and %m may have set 3rd bit
+
+define i32 @mul_common_bits(i32 %p) {
+; CHECK-LABEL: @mul_common_bits(
+; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
+; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 12
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %x = and i32 %p, 7
+  %m = mul i32 %x, 12
+  %r = or i32 %m, %x
+  ret i32 %r
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2622,6 +2622,12 @@
     return BinaryOperator::CreateXor(Or, ConstantInt::get(Ty, *CV));
   }
 
+  // or (mul X, CV), X --> mul X, CV+1
+  if (match(&I,
+            m_c_Or(m_OneUse(m_Mul(m_Value(X), m_APInt(CV))), m_Deferred(X))))
+    if (haveNoCommonBitsSet(Op0, Op1, DL))
+      return BinaryOperator::CreateMul(X, ConstantInt::get(Ty, *CV + 1));
+
   // (A & C) | (B & D)
   Value *A, *B, *C, *D;
   if (match(Op0, m_And(m_Value(A), m_Value(C))) &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114729.390420.patch
Type: text/x-patch
Size: 2483 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211129/f4366055/attachment.bin>


More information about the llvm-commits mailing list