This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]