Fix PR43419: pow->sqrt not honoring signed zeros

Richard Guenther richard.guenther@gmail.com
Thu Mar 18 16:42:00 GMT 2010


On Thu, Mar 18, 2010 at 3:51 PM, Michael Matz <matz@suse.de> wrote:
> Hello,
>
> On Thu, 18 Mar 2010, Michael Matz wrote:
>
>> > According to N1256, F.9.4.4:
>> >
>> >   pow(±0, y) returns +0 for y > 0 and not an odd integer.
>> >
>> > So, pow(-0.0, 0.5) should return +0. But sqrt(-0.0) should return -0
>> > according to the IEEE 754 standard (and F.9.4.5 from ISO C99).
>>
>> But unfortunately you are right, this expansion can only be done for
>> -fno-signed-zeros.
>
> Like so.
>
> Regstrapping on x86_64-linux in progress, it's not a regression from 4.4
> but fairly low risk, so okay for trunk if that passes?

Ok.

Thanks,
Richard.

>
> Ciao,
> Michael.
> --
>        PR middle-end/43419
>        * builtins.c (expand_builtin_pow): Don't transform pow(x, 0.5)
>        into sqrt(x) if we need to preserve signed zeros.
>
> testsuite/
>        * gcc.dg/pr43419.c: New testcase.
>
> Index: builtins.c
> ===================================================================
> --- builtins.c  (revision 157518)
> +++ builtins.c  (working copy)
> @@ -2980,7 +2980,10 @@ expand_builtin_pow (tree exp, rtx target
>          && ((flag_unsafe_math_optimizations
>               && optimize_insn_for_speed_p ()
>               && powi_cost (n/2) <= POWI_MAX_MULTS)
> -             || n == 1))
> +             /* Even the c==0.5 case can not be done unconditionally
> +                when we need to preserve signed zeros, as
> +                pow (-0, 0.5) is +0, while sqrt(-0) is -0.  */
> +             || (!HONOR_SIGNED_ZEROS (mode) && n == 1)))
>        {
>          tree call_expr = build_call_nofold (fn, 1, narg0);
>          /* Use expand_expr in case the newly built call expression
> Index: testsuite/gcc.dg/pr43419.c
> ===================================================================
> --- testsuite/gcc.dg/pr43419.c  (revision 0)
> +++ testsuite/gcc.dg/pr43419.c  (revision 0)
> @@ -0,0 +1,19 @@
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +/* { dg-add-options ieee } */
> +#include <math.h>
> +
> +extern void abort (void);
> +void __attribute__((noinline)) f (double x)
> +{
> +  double pluszero = pow (x, 0.5);
> +  double minuszero = sqrt (x);
> +  if (signbit (pluszero) == signbit (minuszero))
> +    abort ();
> +}
> +
> +int main(void)
> +{
> +  f (-0.0);
> +  return 0;
> +}



More information about the Gcc-patches mailing list