[llvm] r360180 - [InstCombine] allow sinking fneg operands through an FP min/max

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue May 7 11:58:07 PDT 2019


Author: spatel
Date: Tue May  7 11:58:07 2019
New Revision: 360180

URL: http://llvm.org/viewvc/llvm-project?rev=360180&view=rev
Log:
[InstCombine] allow sinking fneg operands through an FP min/max

Fundamentally/generally, we should not have to rely on bailouts/crippling of
folds. In this particular case, I think we always recognize the inverted
predicate min/max pattern, so there should not be any loss of optimization.
Codegen looks better because we are eliminating an fneg.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=360180&r1=360179&r2=360180&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue May  7 11:58:07 2019
@@ -5518,6 +5518,11 @@ Instruction *InstCombiner::visitFCmpInst
     }
   }
 
+  // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y
+  Value *X, *Y;
+  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
+    return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);
+
   // Test if the FCmpInst instruction is used exclusively by a select as
   // part of a minimum or maximum operation. If so, refrain from doing
   // any other folding. This helps out other analyses which understand
@@ -5576,12 +5581,7 @@ Instruction *InstCombiner::visitFCmpInst
   if (Instruction *R = foldFabsWithFcmpZero(I))
     return R;
 
-  Value *X, *Y;
   if (match(Op0, m_FNeg(m_Value(X)))) {
-    // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y
-    if (match(Op1, m_FNeg(m_Value(Y))))
-      return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);
-
     // fcmp pred (fneg X), C --> fcmp swap(pred) X, -C
     Constant *C;
     if (match(Op1, m_Constant(C))) {

Modified: llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll?rev=360180&r1=360179&r2=360180&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/minmax-fp.ll Tue May  7 11:58:07 2019
@@ -257,10 +257,9 @@ define double @t17(i32 %x) {
 
 define float @fneg_fmax(float %x, float %y) {
 ; CHECK-LABEL: @fneg_fmax(
-; CHECK-NEXT:    [[N1:%.*]] = fneg float [[X:%.*]]
-; CHECK-NEXT:    [[N2:%.*]] = fneg float [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan ogt float [[N1]], [[N2]]
-; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[COND]], float [[N1]], float [[N2]]
+; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan olt float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[MAX_V:%.*]] = select i1 [[COND]], float [[X]], float [[Y]]
+; CHECK-NEXT:    [[MAX:%.*]] = fneg float [[MAX_V]]
 ; CHECK-NEXT:    ret float [[MAX]]
 ;
   %n1 = fneg float %x
@@ -272,10 +271,9 @@ define float @fneg_fmax(float %x, float
 
 define <2 x float> @fsub_fmax(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @fsub_fmax(
-; CHECK-NEXT:    [[N1:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT:    [[N2:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[Y:%.*]]
-; CHECK-NEXT:    [[COND_INV:%.*]] = fcmp nnan nsz olt <2 x float> [[N1]], [[N2]]
-; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[COND_INV]], <2 x float> [[N2]], <2 x float> [[N1]]
+; CHECK-NEXT:    [[COND_INV:%.*]] = fcmp nnan nsz ogt <2 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[MAX_V:%.*]] = select <2 x i1> [[COND_INV]], <2 x float> [[Y]], <2 x float> [[X]]
+; CHECK-NEXT:    [[MAX:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[MAX_V]]
 ; CHECK-NEXT:    ret <2 x float> [[MAX]]
 ;
   %n1 = fsub <2 x float> <float -0.0, float -0.0>, %x
@@ -287,10 +285,9 @@ define <2 x float> @fsub_fmax(<2 x float
 
 define <2 x double> @fsub_fmin(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: @fsub_fmin(
-; CHECK-NEXT:    [[N1:%.*]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT:    [[N2:%.*]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[Y:%.*]]
-; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan olt <2 x double> [[N1]], [[N2]]
-; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[COND]], <2 x double> [[N1]], <2 x double> [[N2]]
+; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan ogt <2 x double> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[MAX_V:%.*]] = select <2 x i1> [[COND]], <2 x double> [[X]], <2 x double> [[Y]]
+; CHECK-NEXT:    [[MAX:%.*]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[MAX_V]]
 ; CHECK-NEXT:    ret <2 x double> [[MAX]]
 ;
   %n1 = fsub <2 x double> <double -0.0, double -0.0>, %x
@@ -302,10 +299,9 @@ define <2 x double> @fsub_fmin(<2 x doub
 
 define double @fneg_fmin(double %x, double %y) {
 ; CHECK-LABEL: @fneg_fmin(
-; CHECK-NEXT:    [[N1:%.*]] = fneg double [[X:%.*]]
-; CHECK-NEXT:    [[N2:%.*]] = fneg double [[Y:%.*]]
-; CHECK-NEXT:    [[COND_INV:%.*]] = fcmp nnan nsz ogt double [[N1]], [[N2]]
-; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[COND_INV]], double [[N2]], double [[N1]]
+; CHECK-NEXT:    [[COND_INV:%.*]] = fcmp nnan nsz olt double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[MAX_V:%.*]] = select i1 [[COND_INV]], double [[Y]], double [[X]]
+; CHECK-NEXT:    [[MAX:%.*]] = fneg double [[MAX_V]]
 ; CHECK-NEXT:    ret double [[MAX]]
 ;
   %n1 = fneg double %x




More information about the llvm-commits mailing list