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:
parent
0f158db0bf
commit
60d340efa7
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue