OSDN Git Service

2010-05-04 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 May 2010 09:53:28 +0000 (09:53 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 04:58:21 +0000 (13:58 +0900)
PR tree-optimization/43949
* tree-vrp.c (extract_range_from_binary_expr): Only handle
TRUNC_MOD_EXPR.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159020 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-vrp.c

index 30f3ea1..4195d9d 100644 (file)
@@ -1,3 +1,9 @@
+2010-05-04  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43949
+       * tree-vrp.c (extract_range_from_binary_expr): Only handle
+       TRUNC_MOD_EXPR.
+
 2010-04-26  Jason Merrill  <jason@redhat.com>
 
        * c.opt (-fstrict-enums): New.
index 83ff665..8cac4df 100644 (file)
@@ -2084,9 +2084,6 @@ extract_range_from_binary_expr (value_range_t *vr,
       && code != EXACT_DIV_EXPR
       && code != ROUND_DIV_EXPR
       && code != TRUNC_MOD_EXPR
-      && code != FLOOR_MOD_EXPR
-      && code != CEIL_MOD_EXPR
-      && code != ROUND_MOD_EXPR
       && code != RSHIFT_EXPR
       && code != MIN_EXPR
       && code != MAX_EXPR
@@ -2156,9 +2153,6 @@ extract_range_from_binary_expr (value_range_t *vr,
       && code != EXACT_DIV_EXPR
       && code != ROUND_DIV_EXPR
       && code != TRUNC_MOD_EXPR
-      && code != FLOOR_MOD_EXPR
-      && code != CEIL_MOD_EXPR
-      && code != ROUND_MOD_EXPR
       && (vr0.type == VR_VARYING
          || vr1.type == VR_VARYING
          || vr0.type != vr1.type
@@ -2509,27 +2503,30 @@ extract_range_from_binary_expr (value_range_t *vr,
            }
        }
     }
-  else if (code == TRUNC_MOD_EXPR
-          || code == FLOOR_MOD_EXPR
-          || code == CEIL_MOD_EXPR
-          || code == ROUND_MOD_EXPR)
+  else if (code == TRUNC_MOD_EXPR)
     {
       bool sop = false;
-      if (vr0.type == VR_ANTI_RANGE
-         || vr1.type != VR_RANGE
+      if (vr1.type != VR_RANGE
          || symbolic_range_p (&vr1)
-         || range_includes_zero_p (&vr1))
+         || range_includes_zero_p (&vr1)
+         || vrp_val_is_min (vr1.min))
        {
          set_value_range_to_varying (vr);
          return;
        }
       type = VR_RANGE;
-      max = int_const_binop (MINUS_EXPR, vr1.max, integer_one_node, 0);
-      if (vrp_expr_computes_nonnegative (op0, &sop)
-         && vrp_expr_computes_nonnegative (op1, &sop) && !sop)
-       min = build_int_cst (TREE_TYPE (vr1.max), 0);
+      /* Compute MAX <|vr1.min|, |vr1.max|> - 1.  */
+      max = fold_unary_to_constant (ABS_EXPR, TREE_TYPE (vr1.min), vr1.min);
+      if (tree_int_cst_lt (max, vr1.max))
+       max = vr1.max;
+      max = int_const_binop (MINUS_EXPR, max, integer_one_node, 0);
+      /* If the dividend is non-negative the modulus will be
+        non-negative as well.  */
+      if (TYPE_UNSIGNED (TREE_TYPE (max))
+         || (vrp_expr_computes_nonnegative (op0, &sop) && !sop))
+       min = build_int_cst (TREE_TYPE (max), 0);
       else
-       min = fold_unary (NEGATE_EXPR, TREE_TYPE (max), max);
+       min = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (max), max);
     }
   else if (code == MINUS_EXPR)
     {