re PR fortran/40675 (Support -fnosign-zero for SIGN intrinsic for Fortran 77 compatibility)

2009-07-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/40675
        * simplify.c (gfc_simplify_sign): Handle signed zero correctly.
        * trans-intrinsic.c (gfc_conv_intrinsic_sign): Support
        -fno-sign-zero.
        * invoke.texi (-fno-sign-zero): Add text regarding SIGN
        * intrinsic.

2009-07-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/40675
        * gfortran.dg/nosigned_zero_1.f90: New test.
        * gfortran.dg/nosigned_zero_2.f90: New test.

From-SVN: r149390
This commit is contained in:
Tobias Burnus 2009-07-08 21:34:49 +02:00 committed by Tobias Burnus
parent 0f158db0bf
commit 60d340efa7
7 changed files with 95 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2009-07-08 Tobias Burnus <burnus@net-b.de>
PR fortran/40675
* simplify.c (gfc_simplify_sign): Handle signed zero correctly.
* trans-intrinsic.c (gfc_conv_intrinsic_sign): Support
-fno-sign-zero.
* invoke.texi (-fno-sign-zero): Add text regarding SIGN intrinsic.
2008-07-08 Paul Thomas <pault@gcc.gnu.org>
PR fortran/40591

View File

@ -1024,9 +1024,12 @@ really useful for use by the gfortran testsuite.
@item -fsign-zero
@opindex @code{fsign-zero}
When writing zero values, show the negative sign if the sign bit is set.
@code{fno-sign-zero} does not print the negative sign of zero values for
compatibility with F77. Default behavior is to show the negative sign.
When enabled, floating point numbers of value zero with the sign bit set
are written as negative number in formatted output and treated as
negative in the @code{SIGN} intrinsic. @code{fno-sign-zero} does not
print the negative sign of zero values and regards zero as positive
number in the @code{SIGN} intrinsic for compatibility with F77.
Default behavior is to show the negative sign.
@end table
@node Code Gen Options

View File

@ -4957,16 +4957,15 @@ gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
mpz_abs (result->value.integer, x->value.integer);
if (mpz_sgn (y->value.integer) < 0)
mpz_neg (result->value.integer, result->value.integer);
break;
case BT_REAL:
/* TODO: Handle -0.0 and +0.0 correctly on machines that support
it. */
mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
if (mpfr_sgn (y->value.real) < 0)
mpfr_neg (result->value.real, result->value.real, GFC_RND_MODE);
if (gfc_option.flag_sign_zero)
mpfr_copysign (result->value.real, x->value.real, y->value.real,
GFC_RND_MODE);
else
mpfr_setsign (result->value.real, x->value.real,
mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
break;
default:

View File

@ -1263,22 +1263,41 @@ gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_function_args (se, expr, args, 2);
if (expr->ts.type == BT_REAL)
{
tree abs;
switch (expr->ts.kind)
{
case 4:
tmp = built_in_decls[BUILT_IN_COPYSIGNF];
abs = built_in_decls[BUILT_IN_FABSF];
break;
case 8:
tmp = built_in_decls[BUILT_IN_COPYSIGN];
abs = built_in_decls[BUILT_IN_FABS];
break;
case 10:
case 16:
tmp = built_in_decls[BUILT_IN_COPYSIGNL];
abs = built_in_decls[BUILT_IN_FABSL];
break;
default:
gcc_unreachable ();
}
se->expr = build_call_expr (tmp, 2, args[0], args[1]);
/* We explicitly have to ignore the minus sign. We do so by using
result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1). */
if (!gfc_option.flag_sign_zero
&& MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
{
tree cond, zero;
zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
cond = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
se->expr = fold_build3 (COND_EXPR, TREE_TYPE (args[0]), cond,
build_call_expr (abs, 1, args[0]),
build_call_expr (tmp, 2, args[0], args[1]));
}
else
se->expr = build_call_expr (tmp, 2, args[0], args[1]);
return;
}

View File

@ -1,3 +1,9 @@
2009-07-08 Tobias Burnus <burnus@net-b.de>
PR fortran/40675
* gfortran.dg/nosigned_zero_1.f90: New test.
* gfortran.dg/nosigned_zero_2.f90: New test.
2009-07-08 Richard Guenther <rguenther@suse.de>
* gcc.dg/torture/ssa-pta-fn-1.c: Fix invalid testcase again.

View File

@ -0,0 +1,24 @@
! { dg-do run }
!
! PR fortran/40675
!
! Fortran 77 just had: "The value of a signed zero is the same as
! the value of an unsigned zero." and g77 returned for SIGN(1.0, -0.0) = 1.0
!
! Fortran 95+ has for SIGN: "Case (iv): If B is of type real and is zero,
! then ... (c) If B is negative real zero, the value of the result is -|A|".
! On architectures, where signed zeros are supported, gfortran's SIGN thus
! returns for B=-0.0 the -|A|.
!
program s
x = sign(1.,0.)
y = sign(1.,-0.)
if (x /= 1.) call abort()
if (y /= -1.) call abort()
x = 1.
y = 0.
x = sign(x, y)
y = sign(x, -y)
if (x /= 1.) call abort()
if (y /= -1.) call abort()
end program s

View File

@ -0,0 +1,25 @@
! { dg-do run }
! { dg-options "-fno-sign-zero" }
!
! PR fortran/40675
!
! Fortran 77 just had: "The value of a signed zero is the same as
! the value of an unsigned zero." and g77 returned for SIGN(1.0, -0.0) = 1.0
!
! Fortran 95+ has for SIGN: "Case (iv): If B is of type real and is zero,
! then ... (c) If B is negative real zero, the value of the result is -|A|".
! On architectures, where signed zeros are supported, gfortran's SIGN thus
! returns for B=-0.0 the -|A|.
!
program s
x = sign(1.,0.)
y = sign(1.,-0.)
if (x /= 1.) call abort()
if (y /= 1.) call abort()
x = 1.
y = 0.
x = sign(x, y)
y = sign(x, -y)
if (x /= 1.) call abort()
if (y /= 1.) call abort()
end program s