diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2012-05-05 10:59:22 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2012-05-05 10:59:22 +0300 |
commit | 4ecad771dd276d6c518d679b3e13c58b45737b8c (patch) | |
tree | 8d0572d604c2f2a46fc172d68dceeb1635b87c47 /gcc/fortran/simplify.c | |
parent | 68ee9c0807fd3c9a66c649aa7bd3bebacfb0dff0 (diff) | |
download | gcc-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.c | 27 |
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: |