diff options
author | Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de> | 2004-12-27 18:13:07 +0100 |
---|---|---|
committer | Tobias Schlüter <tobi@gcc.gnu.org> | 2004-12-27 18:13:07 +0100 |
commit | e98a8b5b621c4c9be4cc5efa38cf34ff14e27d67 (patch) | |
tree | 9ab5af294501132cc7f07c24458d26d441ed96c0 /gcc/fortran | |
parent | 201a97b4799fd44526a65abbcc2621f7d27766f7 (diff) | |
download | gcc-e98a8b5b621c4c9be4cc5efa38cf34ff14e27d67.zip gcc-e98a8b5b621c4c9be4cc5efa38cf34ff14e27d67.tar.gz gcc-e98a8b5b621c4c9be4cc5efa38cf34ff14e27d67.tar.bz2 |
re PR libfortran/19032 (modulo generates wrong result for divisor 1 and -1)
fortran/
PR fortran/19032
* trans-intrinsic.c (gfc_conv_intrinsic_mod): Update comment
in front of function to match the standard. Correct handling
of MODULO.
testsuite/
PR fortran/19032
* gfortran.dg/intrinsic_modulo_1.f90: New.
* gfortran.fortran-torture/execute/intrinsic_mod_ulo.f90: Add
tests with divisor -1.
From-SVN: r92645
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 31 |
2 files changed, 20 insertions, 26 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d1b20a7..7654b04 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,8 +1,3 @@ -2004-12-27 Andrew Pinski <pinskia@physics.uc.edu> - - * trans-expr.c (gfc_conv_cst_int_power): Only check for - flag_unsafe_math_optimizations if we have a float type. - 2004-12-27 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> * trans-intrinsic.c (gfc_conv_intrinsic_ishft): Change to @@ -11,6 +6,16 @@ 4 bytes bits. Convert 2nd and 3rd argument to 4 bytes. Convert result if width(arg 1) < 4 bytes. Call fold. + PR fortran/19032 + * trans-intrinsic.c (gfc_conv_intrinsic_mod): Update comment + in front of function to match the standard. Correct handling + of MODULO. + +2004-12-27 Andrew Pinski <pinskia@physics.uc.edu> + + * trans-expr.c (gfc_conv_cst_int_power): Only check for + flag_unsafe_math_optimizations if we have a float type. + 2004-12-23 Steven G. Kargl <kargls@comcast.net> * gfortran.texi: Fix typo. diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 56def1a..455dfb8 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -771,8 +771,8 @@ gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both) se->expr = fold (build2 (COMPLEX_EXPR, type, real, imag)); } -/* Remainder function MOD(A, P) = A - INT(A / P) * P. - MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */ +/* Remainder function MOD(A, P) = A - INT(A / P) * P + MODULO(A, P) = A - FLOOR (A / P) * P */ /* TODO: MOD(x, 0) */ static void @@ -783,7 +783,6 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo) tree type; tree itype; tree tmp; - tree zero; tree test; tree test2; mpfr_t huge; @@ -798,7 +797,10 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo) { case BT_INTEGER: /* Integer case is easy, we've got a builtin op. */ - se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2); + if (modulo) + se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2); + else + se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2); break; case BT_REAL: @@ -821,7 +823,10 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo) test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2); itype = gfc_get_int_type (expr->ts.kind); - tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR); + if (modulo) + tmp = build_fix_expr (&se->pre, tmp, itype, FIX_FLOOR_EXPR); + else + tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR); tmp = convert (type, tmp); tmp = build3 (COND_EXPR, type, test2, tmp, arg); tmp = build2 (MULT_EXPR, type, tmp, arg2); @@ -832,22 +837,6 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo) default: gcc_unreachable (); } - - if (modulo) - { - zero = gfc_build_const (type, integer_zero_node); - /* Build !(A > 0 .xor. P > 0). */ - test = build2 (GT_EXPR, boolean_type_node, arg, zero); - test2 = build2 (GT_EXPR, boolean_type_node, arg2, zero); - test = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2); - test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test); - /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */ - test2 = build2 (EQ_EXPR, boolean_type_node, arg, zero); - test = build2 (TRUTH_OR_EXPR, boolean_type_node, test, test2); - - se->expr = build3 (COND_EXPR, type, test, se->expr, - build2 (PLUS_EXPR, type, se->expr, arg2)); - } } /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */ |