On Tue, 4 Oct 2016, Joseph Myers wrote: > On Tue, 4 Oct 2016, Richard Biener wrote: > > > On Tue, 4 Oct 2016, Joseph Myers wrote: > > > > > On Tue, 4 Oct 2016, Richard Biener wrote: > > > > > > > Possibly. Though then for FP we also want - abs (a) -> copysign (a, > > > > -1). > > > > > > For architectures such as powerpc that have a negated-abs instruction, > > > does it get properly generated from the copysign code? (The relevant > > > pattern in rs6000.md uses (neg (abs)) - is that the correct canonical RTL > > > for this?) > > > > I have no idea - given that there is no copysign RTL code I suppose > > it is the only machine independent RTL that can do this? > > > > The question would be whether the copysign optab of said targets would > > special-case the -1 case appropriately. > > Why -1? Any constant in copysign should be handled appropriately. I'd > say that (neg (abs)) is probably better as a canonical representation, so > map copysign from a constant to either (abs) or (neg (abs)) appropriately. > > Then in the case where abs is expanded with bit manipulation, (neg (abs)) > should be expanded to a single OR. I don't know whether the RTL > optimizers will map the AND / OR combination to a single OR, but if they > do then there should be no need to special-case (neg (abs)) in expansion, > and when (abs) RTL is generated a machine description's (neg (abs)) > pattern should match automatically.
Ok, that's a good point -- I'll do copysign (X, const) canonicalization to [-]abs() then. Hopefully that's a valid transform even if NaNs and signed zeros are involved. For now I've installed the requested min(a,-a)->-abs(a) pattern. Bootstrapped / tested on x86_64-unknown-linux-gnu. Richard. 2016-10-05 Richard Biener <rguent...@suse.de> PR middle-end/55152 * match.pd (min(a,-a) -> -abs(a)): New pattern. * gcc.dg/pr55152-2.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 240738) +++ gcc/match.pd (working copy) @@ -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,13 @@ +/* { 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" 2 "optimized" } } */