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" } } */