]> gcc.gnu.org Git - gcc.git/commitdiff
(fold, case *_{DIV,MOD}_EXPR): When using distributive law, take care
authorRichard Kenner <kenner@gcc.gnu.org>
Wed, 8 Dec 1993 10:46:16 +0000 (05:46 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 8 Dec 1993 10:46:16 +0000 (05:46 -0500)
when C2 is negative.

From-SVN: r6194

gcc/fold-const.c

index 27f6baba92197999b35830e6f9fc218f676003ff..6821c0635b97a737c8965d16df91a7f6dd7acb7d 100644 (file)
@@ -3922,7 +3922,7 @@ fold (expr)
         where C1 % C3 == 0 or C3 % C1 == 0.  We can simplify these
         expressions, which often appear in the offsets or sizes of
         objects with a varying size.  Only deal with positive divisors
-        and multiplicands. 
+        and multiplicands.   If C2 is negative, we must have C2 % C3 == 0.
 
         Look for NOPs and SAVE_EXPRs inside.  */
 
@@ -3942,7 +3942,10 @@ fold (expr)
              && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
            c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0);
          else if (TREE_CODE (xarg0) == MINUS_EXPR
-                  && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
+                  && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST
+                  /* If we are doing this computation unsigned, the negate
+                     is incorrect.  */
+                  && ! TREE_UNSIGNED (type))
            {
              c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1)));
              xarg0 = TREE_OPERAND (xarg0, 0);
@@ -3959,7 +3962,10 @@ fold (expr)
              && (integer_zerop (const_binop (TRUNC_MOD_EXPR,
                                              TREE_OPERAND (xarg0, 1), arg1, 1))
                  || integer_zerop (const_binop (TRUNC_MOD_EXPR, arg1,
-                                                TREE_OPERAND (xarg0, 1), 1))))
+                                                TREE_OPERAND (xarg0, 1), 1)))
+             && (tree_int_cst_lt (integer_zero_node, c2)
+                 || integer_zerop (const_binop (TRUNC_MOD_EXPR, c2,
+                                                arg1, 1))))
            {
              tree outer_div = integer_one_node;
              tree c1 = TREE_OPERAND (xarg0, 1);
@@ -4020,7 +4026,8 @@ fold (expr)
              && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
            c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0);
          else if (TREE_CODE (xarg0) == MINUS_EXPR
-                  && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
+                  && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST
+                  && ! TREE_UNSIGNED (type))
            {
              c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1)));
              xarg0 = TREE_OPERAND (xarg0, 0);
@@ -4032,7 +4039,8 @@ fold (expr)
              && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST
              && integer_zerop (const_binop (TRUNC_MOD_EXPR,
                                             TREE_OPERAND (xarg0, 1),
-                                            arg1, 1)))
+                                            arg1, 1))
+             && tree_int_cst_lt (integer_zero_node, c2))
            /* The result is (C2%C3).  */
            return omit_one_operand (type, const_binop (code, c2, arg1, 1),
                                     TREE_OPERAND (xarg0, 0));
This page took 0.071986 seconds and 5 git commands to generate.