[llvm] r325648 - [InstCombine] -X / C --> X / -C for FP

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 15:51:17 PST 2018


Author: spatel
Date: Tue Feb 20 15:51:16 2018
New Revision: 325648

URL: http://llvm.org/viewvc/llvm-project?rev=325648&view=rev
Log:
[InstCombine] -X / C --> X / -C for FP

We already do this in DAGCombiner, but it should 
also be good to eliminate the fsub use in IR.

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

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=325648&r1=325647&r2=325648&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Tue Feb 20 15:51:16 2018
@@ -1285,12 +1285,18 @@ Instruction *InstCombiner::visitSDiv(Bin
   return nullptr;
 }
 
-/// Try to convert X/C into X * (1/C).
+/// Remove negation and try to convert division into multiplication.
 static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
   Constant *C;
   if (!match(I.getOperand(1), m_Constant(C)))
     return nullptr;
 
+  // -X / C --> X / -C
+  Value *X;
+  if (match(I.getOperand(0), m_FNeg(m_Value(X))))
+    return BinaryOperator::CreateWithCopiedFlags(Instruction::FDiv, X,
+                                                 ConstantExpr::getFNeg(C), &I);
+
   // If the constant divisor has an exact inverse, this is always safe. If not,
   // then we can still create a reciprocal if fast-math-flags allow it and the
   // constant is a regular number (not zero, infinite, or denormal).
@@ -1305,6 +1311,7 @@ static Instruction *foldFDivConstantDivi
   if (!RecipC->isNormalFP())
     return nullptr;
 
+  // X / C --> X * (1 / C)
   return BinaryOperator::CreateWithCopiedFlags(
       Instruction::FMul, I.getOperand(0), RecipC, &I);
 }
@@ -1345,11 +1352,11 @@ Instruction *InstCombiner::visitFDiv(Bin
                                   SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
-  if (Instruction *FMul = foldFDivConstantDivisor(I))
-    return FMul;
+  if (Instruction *R = foldFDivConstantDivisor(I))
+    return R;
 
-  if (Instruction *NewFDiv = foldFDivConstantDividend(I))
-    return NewFDiv;
+  if (Instruction *R = foldFDivConstantDividend(I))
+    return R;
 
   if (isa<Constant>(Op0))
     if (SelectInst *SI = dyn_cast<SelectInst>(Op1))

Modified: llvm/trunk/test/Transforms/InstCombine/fdiv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fdiv.ll?rev=325648&r1=325647&r2=325648&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fdiv.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll Tue Feb 20 15:51:16 2018
@@ -215,45 +215,43 @@ define <2 x float> @fneg_fneg_vec(<2 x f
 
 define float @fneg_dividend_constant_divisor(float %x) {
 ; CHECK-LABEL: @fneg_dividend_constant_divisor(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], 3.000000e+00
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret float [[DIV]]
 ;
   %neg = fsub float -0.0, %x
-  %div = fdiv float %neg, 3.0
+  %div = fdiv nsz float %neg, 3.0
   ret  float %div
 }
 
 define float @fneg_divisor_constant_dividend(float %x) {
 ; CHECK-LABEL: @fneg_divisor_constant_dividend(
 ; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv float -3.000000e+00, [[NEG]]
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan float -3.000000e+00, [[NEG]]
 ; CHECK-NEXT:    ret float [[DIV]]
 ;
   %neg = fsub float -0.0, %x
-  %div = fdiv float -3.0, %neg
+  %div = fdiv nnan float -3.0, %neg
   ret float %div
 }
 
 define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {
 ; CHECK-LABEL: @fneg_dividend_constant_divisor_vec(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[NEG]], <float 3.000000e+00, float -8.000000e+00>
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
 ; CHECK-NEXT:    ret <2 x float> [[DIV]]
 ;
   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
-  %div = fdiv <2 x float> %neg, <float 3.0, float -8.0>
+  %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>
   ret <2 x float> %div
 }
 
 define <2 x float> @fneg_divisor_constant_dividend_vec(<2 x float> %x) {
 ; CHECK-LABEL: @fneg_divisor_constant_dividend_vec(
 ; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> <float -3.000000e+00, float 5.000000e+00>, [[NEG]]
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv afn <2 x float> <float -3.000000e+00, float 5.000000e+00>, [[NEG]]
 ; CHECK-NEXT:    ret <2 x float> [[DIV]]
 ;
   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
-  %div = fdiv <2 x float> <float -3.0, float 5.0>, %neg
+  %div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg
   ret <2 x float> %div
 }
 




More information about the llvm-commits mailing list