[llvm] r338059 - [InstCombine] fold udiv with common factor from muls with nuw

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 26 12:22:41 PDT 2018


Author: spatel
Date: Thu Jul 26 12:22:41 2018
New Revision: 338059

URL: http://llvm.org/viewvc/llvm-project?rev=338059&view=rev
Log:
[InstCombine] fold udiv with common factor from muls with nuw

Unfortunately, sdiv isn't as simple because of UB due to overflow.

This fold is mentioned in PR38239:
https://bugs.llvm.org/show_bug.cgi?id=38239

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/trunk/test/Transforms/InstCombine/div.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=338059&r1=338058&r2=338059&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Thu Jul 26 12:22:41 2018
@@ -973,6 +973,21 @@ Instruction *InstCombiner::visitUDiv(Bin
   if (Instruction *NarrowDiv = narrowUDivURem(I, Builder))
     return NarrowDiv;
 
+  // If the udiv operands are non-overflowing multiplies with a common operand,
+  // then eliminate the common factor:
+  // (A * B) / (A * X) --> B / X (and commuted variants)
+  // TODO: The code would be reduced if we had m_c_NUWMul pattern matching.
+  // TODO: If -reassociation handled this generally, we could remove this.
+  Value *A, *B;
+  if (match(Op0, m_NUWMul(m_Value(A), m_Value(B)))) {
+    if (match(Op1, m_NUWMul(m_Specific(A), m_Value(X))) ||
+        match(Op1, m_NUWMul(m_Value(X), m_Specific(A))))
+      return BinaryOperator::CreateUDiv(B, X);
+    if (match(Op1, m_NUWMul(m_Specific(B), m_Value(X))) ||
+        match(Op1, m_NUWMul(m_Value(X), m_Specific(B))))
+      return BinaryOperator::CreateUDiv(A, X);
+  }
+
   // (LHS udiv (select (select (...)))) -> (LHS >> (select (select (...))))
   SmallVector<UDivFoldAction, 6> UDivActions;
   if (visitUDivOperand(Op0, Op1, I, UDivActions))

Modified: llvm/trunk/test/Transforms/InstCombine/div.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/div.ll?rev=338059&r1=338058&r2=338059&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/div.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/div.ll Thu Jul 26 12:22:41 2018
@@ -688,9 +688,7 @@ define <2 x i8> @div_factor_unsigned_vec
 
 define i8 @udiv_common_factor(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @udiv_common_factor(
-; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
+; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[C]]
 ;
   %a = mul nuw i8 %z, %x
@@ -701,9 +699,7 @@ define i8 @udiv_common_factor(i8 %x, i8
 
 define <2 x i8> @udiv_common_factor_commute1_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
 ; CHECK-LABEL: @udiv_common_factor_commute1_vec(
-; CHECK-NEXT:    [[A:%.*]] = mul nuw <2 x i8> [[X:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = mul nuw <2 x i8> [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[C]]
 ;
   %a = mul nuw <2 x i8> %x, %z
@@ -714,9 +710,7 @@ define <2 x i8> @udiv_common_factor_comm
 
 define i8 @udiv_common_factor_commute2(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @udiv_common_factor_commute2(
-; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[X:%.*]], [[Z:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Y:%.*]], [[Z]]
-; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
+; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[C]]
 ;
   %a = mul nuw i8 %x, %z
@@ -727,9 +721,7 @@ define i8 @udiv_common_factor_commute2(i
 
 define i8 @udiv_common_factor_commute3(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @udiv_common_factor_commute3(
-; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[Z:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Y:%.*]], [[Z]]
-; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
+; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[C]]
 ;
   %a = mul nuw i8 %z, %x




More information about the llvm-commits mailing list