aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2012-05-05 10:59:22 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2012-05-05 10:59:22 +0300
commit4ecad771dd276d6c518d679b3e13c58b45737b8c (patch)
tree8d0572d604c2f2a46fc172d68dceeb1635b87c47 /gcc/fortran/simplify.c
parent68ee9c0807fd3c9a66c649aa7bd3bebacfb0dff0 (diff)
downloadgcc-4ecad771dd276d6c518d679b3e13c58b45737b8c.zip
gcc-4ecad771dd276d6c518d679b3e13c58b45737b8c.tar.gz
gcc-4ecad771dd276d6c518d679b3e13c58b45737b8c.tar.bz2
PR 49010,24518 MOD/MODULO fixes.
gcc/fortran: 2012-05-05 Janne Blomqvist <jb@gcc.gnu.org> PR fortran/49010 PR fortran/24518 * intrinsic.texi (MOD, MODULO): Mention sign and magnitude of result. * simplify.c (gfc_simplify_mod): Use mpfr_fmod. (gfc_simplify_modulo): Likewise, use copysign to fix the result if zero. * trans-intrinsic.c (gfc_conv_intrinsic_mod): Remove fallback as builtin_fmod is always available. For modulo, call copysign to fix the result when signed zeros are enabled. testsuite: 2012-05-05 Janne Blomqvist <jb@gcc.gnu.org> PR fortran/49010 PR fortran/24518 * gfortran.dg/mod_sign0_1.f90: New test. * gfortran.dg/mod_large_1.f90: New test. From-SVN: r187191
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 706dab4..1578db1 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -4222,7 +4222,6 @@ gfc_expr *
gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
{
gfc_expr *result;
- mpfr_t tmp;
int kind;
if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
@@ -4254,12 +4253,8 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
}
gfc_set_model_kind (kind);
- mpfr_init (tmp);
- mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
- mpfr_trunc (tmp, tmp);
- mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
- mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
- mpfr_clear (tmp);
+ mpfr_fmod (result->value.real, a->value.real, p->value.real,
+ GFC_RND_MODE);
break;
default:
@@ -4274,7 +4269,6 @@ gfc_expr *
gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
{
gfc_expr *result;
- mpfr_t tmp;
int kind;
if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
@@ -4308,12 +4302,17 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
}
gfc_set_model_kind (kind);
- mpfr_init (tmp);
- mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
- mpfr_floor (tmp, tmp);
- mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
- mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
- mpfr_clear (tmp);
+ mpfr_fmod (result->value.real, a->value.real, p->value.real,
+ GFC_RND_MODE);
+ if (mpfr_cmp_ui (result->value.real, 0) != 0)
+ {
+ if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
+ mpfr_add (result->value.real, result->value.real, p->value.real,
+ GFC_RND_MODE);
+ }
+ else
+ mpfr_copysign (result->value.real, result->value.real,
+ p->value.real, GFC_RND_MODE);
break;
default: