re PR tree-optimization/64454 (optimize (x%5)%5)
authorMarc Glisse <marc.glisse@inria.fr>
Sat, 9 May 2015 15:40:05 +0000 (17:40 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Sat, 9 May 2015 15:40:05 +0000 (15:40 +0000)
2015-05-09  Marc Glisse  <marc.glisse@inria.fr>

PR tree-optimization/64454
gcc/
* tree-vrp.c (extract_range_from_binary_expr_1) <TRUNC_MOD_EXPR>:
Rewrite.
gcc/testsuite/
* gcc.dg/tree-ssa/vrp97.c: New file.
* gcc.dg/vect/slp-perm-7.c: Update.

From-SVN: r222970

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp97.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/slp-perm-7.c
gcc/tree-vrp.c

index 7f5bd82d9b324b79738d05e320bcd13f5016ad3b..3a56037814da1b2005eebdb28019ee258a629012 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-09  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR tree-optimization/64454
+       * tree-vrp.c (extract_range_from_binary_expr_1) <TRUNC_MOD_EXPR>:
+       Rewrite.
+
 2015-05-08  Jason Merrill  <jason@redhat.com>
 
        * bitmap.c, c/c-aux-info.c, cfg.c, cfghooks.c, cgraph.c,
index d3beeb9ce9f803dceb21587124d47146ecab6c33..53fd15206fc05b06f8264ee70258a9ba3c5eb82a 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-09  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR tree-optimization/64454
+       * gcc.dg/tree-ssa/vrp97.c: New file.
+       * gcc.dg/vect/slp-perm-7.c: Update.
+
 2015-05-09  Andre Vehreschild  <vehre@gmx.de>
 
        PR fortran/65894
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp97.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp97.c
new file mode 100644 (file)
index 0000000..3805ca9
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR tree-optimization/64454 */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int f(int a, int b)
+{
+    if (a < -3 || a > 13) __builtin_unreachable();
+    if (b < -6 || b > 9) __builtin_unreachable();
+    int c = a % b;
+    return c >= -3 && c <= 8;
+}
+
+int g(int a, int b)
+{
+  int c = a % b;
+  return c != -__INT_MAX__ - 1;
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
index 6291096f001524c0b0ca9a6a83e850838db4c2b1..9eff25e2f2771d2ecd9daa14f1155586a845f001 100644 (file)
@@ -70,7 +70,7 @@ int main (int argc, const char* argv[])
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect"  { target vect_perm } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
 
index 6744a91f6e9844bc410b4c76efd72ba1047bec74..c0b381df648a6d3bcbfbc95c9fe574d1dc0f8dbf 100644 (file)
@@ -3196,26 +3196,60 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
     }
   else if (code == TRUNC_MOD_EXPR)
     {
-      if (vr1.type != VR_RANGE
-         || range_includes_zero_p (vr1.min, vr1.max) != 0
-         || vrp_val_is_min (vr1.min))
+      if (range_is_null (&vr1))
        {
-         set_value_range_to_varying (vr);
+         set_value_range_to_undefined (vr);
          return;
        }
+      /* ABS (A % B) < ABS (B) and either
+        0 <= A % B <= A or A <= A % B <= 0.  */
       type = VR_RANGE;
-      /* Compute MAX <|vr1.min|, |vr1.max|> - 1.  */
-      max = fold_unary_to_constant (ABS_EXPR, expr_type, vr1.min);
-      if (tree_int_cst_lt (max, vr1.max))
-       max = vr1.max;
-      max = int_const_binop (MINUS_EXPR, max, build_int_cst (TREE_TYPE (max), 1));
-      /* If the dividend is non-negative the modulus will be
-        non-negative as well.  */
-      if (TYPE_UNSIGNED (expr_type)
-         || value_range_nonnegative_p (&vr0))
-       min = build_int_cst (TREE_TYPE (max), 0);
+      signop sgn = TYPE_SIGN (expr_type);
+      unsigned int prec = TYPE_PRECISION (expr_type);
+      wide_int wmin, wmax, tmp;
+      wide_int zero = wi::zero (prec);
+      wide_int one = wi::one (prec);
+      if (vr1.type == VR_RANGE && !symbolic_range_p (&vr1))
+       {
+         wmax = wi::sub (vr1.max, one);
+         if (sgn == SIGNED)
+           {
+             tmp = wi::sub (wi::minus_one (prec), vr1.min);
+             wmax = wi::smax (wmax, tmp);
+           }
+       }
       else
-       min = fold_unary_to_constant (NEGATE_EXPR, expr_type, max);
+       {
+         wmax = wi::max_value (prec, sgn);
+         /* X % INT_MIN may be INT_MAX.  */
+         if (sgn == UNSIGNED)
+           wmax = wmax - one;
+       }
+
+      if (sgn == UNSIGNED)
+       wmin = zero;
+      else
+       {
+         wmin = -wmax;
+         if (vr0.type == VR_RANGE && TREE_CODE (vr0.min) == INTEGER_CST)
+           {
+             tmp = vr0.min;
+             if (wi::gts_p (tmp, zero))
+               tmp = zero;
+             wmin = wi::smax (wmin, tmp);
+           }
+       }
+
+      if (vr0.type == VR_RANGE && TREE_CODE (vr0.max) == INTEGER_CST)
+       {
+         tmp = vr0.max;
+         if (sgn == SIGNED && wi::neg_p (tmp))
+           tmp = zero;
+         wmax = wi::min (wmax, tmp, sgn);
+       }
+
+      min = wide_int_to_tree (expr_type, wmin);
+      max = wide_int_to_tree (expr_type, wmax);
     }
   else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
     {