[InstCombine] try to fold 'or' into 'mul' operand

or (mul X, Y), X --> mul X, (add Y, 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

Differential Revision: https://reviews.llvm.org/D114729
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 6d3b228..dc55b5a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2639,6 +2639,15 @@
     return BinaryOperator::CreateXor(Or, ConstantInt::get(Ty, *CV));
   }
 
+  // If the operands have no common bits set:
+  // or (mul X, Y), X --> add (mul X, Y), X --> mul X, (Y + 1)
+  if (match(&I,
+            m_c_Or(m_OneUse(m_Mul(m_Value(X), m_Value(Y))), m_Deferred(X))) &&
+      haveNoCommonBitsSet(Op0, Op1, DL)) {
+    Value *IncrementY = Builder.CreateAdd(Y, ConstantInt::get(Ty, 1));
+    return BinaryOperator::CreateMul(X, IncrementY);
+  }
+
   // (A & C) | (B & D)
   Value *A, *B, *C, *D;
   if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index 962ad47..869c17a 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -1446,8 +1446,8 @@
 ; CHECK-LABEL: @mul_no_common_bits(
 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
-; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]
-; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[Y]], 1
+; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X]], [[TMP1]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %x = and i32 %p1, 7
@@ -1460,8 +1460,7 @@
 define i32 @mul_no_common_bits_const_op(i32 %p) {
 ; CHECK-LABEL: @mul_no_common_bits_const_op(
 ; 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
@@ -1473,8 +1472,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 16>
-; CHECK-NEXT:    [[R:%.*]] = or <2 x i12> [[X]], [[M]]
+; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <2 x i12> [[X]], <i12 15, i12 17>
 ; CHECK-NEXT:    ret <2 x i12> [[R]]
 ;
   %x = and <2 x i12> %p, <i12 1, i12 1>
@@ -1483,8 +1481,29 @@
   ret <2 x i12> %r
 }
 
-define i32 @mul_no_common_bits_uses(i32 %p) {
+; negative test - extra use requires extra instructions
+
+define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
 ; CHECK-LABEL: @mul_no_common_bits_uses(
+; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
+; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
+; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]
+; CHECK-NEXT:    call void @use(i32 [[M]])
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %x = and i32 %p1, 7
+  %y = shl i32 %p2, 3
+  %m = mul i32 %x, %y
+  call void @use(i32 %m)
+  %r = or i32 %m, %x
+  ret i32 %r
+}
+
+; negative test - probably not good to create an extra mul
+
+define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
+; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 24
 ; CHECK-NEXT:    call void @use(i32 [[M]])
@@ -1498,6 +1517,8 @@
   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