On Fri, 30 Sep 2016, Andrew Pinski wrote:

> On Thu, Sep 29, 2016 at 8:23 PM, Richard Biener <rguent...@suse.de> wrote:
> > On Thu, 29 Sep 2016, Richard Biener wrote:
> >
> >> On Wed, 28 Sep 2016, Joseph Myers wrote:
> >>
> >> > On Wed, 28 Sep 2016, Richard Biener wrote:
> >> >
> >> > > Index: gcc/testsuite/gcc.dg/pr55152.c
> >> > > ===================================================================
> >> > > --- gcc/testsuite/gcc.dg/pr55152.c        (revision 0)
> >> > > +++ gcc/testsuite/gcc.dg/pr55152.c        (working copy)
> >> > > @@ -0,0 +1,13 @@
> >> > > +/* { dg-do compile } */
> >> > > +/* { dg-options "-O -ffinite-math-only -fstrict-overflow 
> >> > > -fdump-tree-optimized" } */
> >> > > +
> >> > > +double g (double a)
> >> > > +{
> >> > > +  return (a>=-a)?a:-a;
> >> >
> >> > You should need -fno-signed-zeros for this (that is, for the
> >> > transformation to MAX_EXPR), not -ffinite-math-only.  For a == -0, that
> >> > function should return -0, but abs would produce +0.
> >>
> >> This means that tree-ssa-phiopt.c has a bug:
> >>
> >> static bool
> >> minmax_replacement (basic_block cond_bb, basic_block middle_bb,
> >>                     edge e0, edge e1, gimple *phi,
> >>                     tree arg0, tree arg1)
> >> {
> >> ...
> >>   /* The optimization may be unsafe due to NaNs.  */
> >>   if (HONOR_NANS (type))
> >>     return false;
> >>
> >> and it should check HONOR_SIGNED_ZEROS as well.
> >>
> >> I'll fix that as a followup.
> >
> > Committed as follows.
> >
> > Bootstrapped / tested on x86_64-unknown-linux-gnu.
> >
> > Richard.
> >
> > 2016-09-29  Richard Biener  <rguent...@suse.de>
> >
> >         PR middle-end/55152
> >         * match.pd: Add max(a,-a) -> abs(a) pattern.
> 
> 
> Hmm, shouldn't we also do "min(a, -a) -> - abs(a)" ?

Possibly.  Though then for FP we also want - abs (a) -> copysign (a, -1).

Testing the following.

Richard.

2016-10-04  Richard Biener  <rguent...@suse.de>

        PR middle-end/55152
        * match.pd (- abs (x) -> copysign (x, -1)): New pattern.
        (min(a,-a) -> -abs(a)): Likewise.

        * gcc.dg/pr55152-2.c: New testcase.

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 240738)
+++ gcc/match.pd        (working copy)
@@ -782,6 +782,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (simplify
  (abs tree_expr_nonnegative_p@0)
  @0)
+/* - abs (x) -> copysign (x, -1).  */
+(simplify
+ (negate (abs @0))
+ (if (SCALAR_FLOAT_TYPE_P (type))
+  (switch
+   (if (types_match (type, float_type_node))
+    (BUILT_IN_COPYSIGNF @0 { build_minus_one_cst (type); }))
+   (if (types_match (type, double_type_node))
+    (BUILT_IN_COPYSIGN @0 { build_minus_one_cst (type); }))
+   (if (types_match (type, long_double_type_node))
+    (BUILT_IN_COPYSIGNL @0 { build_minus_one_cst (type); })))))
 
 /* A few cases of fold-const.c negate_expr_p predicate.  */
 (match negate_expr_p
@@ -1291,6 +1302,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && (! ANY_INTEGRAL_TYPE_P (type)
          || TYPE_OVERFLOW_UNDEFINED (type)))
   (abs @0)))
+/* min(a,-a) -> -abs(a).  */
+(simplify
+ (min:c @0 (negate @0))
+ (if (TREE_CODE (type) != COMPLEX_TYPE
+      && (! ANY_INTEGRAL_TYPE_P (type)
+         || TYPE_OVERFLOW_UNDEFINED (type)))
+  (negate (abs @0))))
 (simplify
  (min @0 @1)
  (switch
Index: gcc/testsuite/gcc.dg/pr55152-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr55152-2.c    (revision 0)
+++ gcc/testsuite/gcc.dg/pr55152-2.c    (working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ffinite-math-only -fno-signed-zeros -fstrict-overflow 
-fdump-tree-optimized" } */
+
+double g (double a)
+{
+  return (a<-a)?a:-a;
+}
+int f(int a)
+{
+  return (a<-a)?a:-a;
+}
+
+/* { dg-final { scan-tree-dump-times "ABS_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "copysign" 1 "optimized" } } */

Reply via email to