Commit 60d340ef by Tobias Burnus Committed by Tobias Burnus

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
parent 0f158db0
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
......
......@@ -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
......
......@@ -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:
......
......@@ -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;
}
......
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.
......
! { 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
! { 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment