This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gfortran] Fix PR 19042
- From: Tobias Schlüter <tobias dot schlueter at physik dot uni-muenchen dot de>
- To: GCC Fortran mailing list <fortran at gcc dot gnu dot org>,patch <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 16 Dec 2004 22:08:37 +0100
- Subject: [gfortran] Fix PR 19042
We did return the wrong result for MODULO(i,-1). I fixed this by using the
compiler builtin functionality for the integer case of MODULO. Instead of
returning early, I folded the code immediately following the switch into the
BT_REAL case.
I don't know if this works correctly in the case of reals, but I didn't change
its current functionality.
Bubblestrapped and regtested, I will also amend
gfortran.fortran-torture/execute/intrinsic_mod_ulo.f90 to test the case of -1
as divisor.
OK?
- Tobi
2004-12-16 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/19042
* trans-intrinsic.c (gfc_conv_intrinsic_mod): Build FLOOR_MOD_EXPR
for MODULO of integers. Move 'if (modulo)' conditional into switch.
Index: trans-intrinsic.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-intrinsic.c,v
retrieving revision 1.34
diff -u -p -r1.34 trans-intrinsic.c
--- trans-intrinsic.c 16 Dec 2004 19:10:18 -0000 1.34
+++ trans-intrinsic.c 16 Dec 2004 21:00:13 -0000
@@ -798,7 +798,10 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc
{
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:
@@ -827,27 +830,26 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc
tmp = build2 (MULT_EXPR, type, tmp, arg2);
se->expr = build2 (MINUS_EXPR, type, arg, tmp);
mpfr_clear (huge);
+ 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));
+ }
break;
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. */