OSDN Git Service

* tree-vrp.c (extract_range_from_binary_expr) <BIT_AND_EXPR>: If
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jul 2010 06:58:42 +0000 (06:58 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jul 2010 06:58:42 +0000 (06:58 +0000)
both ranges are range_int_cst_p with non-negative minimum,
try harder to derive smaller range.

* gcc.dg/tree-ssa/vrp50.c: New test.
* gcc.dg/vect/slp-perm-4.c (main): Make sure loop isn't vectorized.

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

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

index 73d21e6..e8e4f1b 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * tree-vrp.c (extract_range_from_binary_expr) <BIT_AND_EXPR>: If
+       both ranges are range_int_cst_p with non-negative minimum,
+       try harder to derive smaller range.
+
 2010-07-09  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * genrecog.c: Include diagnostic-core.h before toplev.h.
index 52a54e9..f6e5b37 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/tree-ssa/vrp50.c: New test.
+       * gcc.dg/vect/slp-perm-4.c (main): Make sure loop isn't vectorized.
+
 2010-07-08  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/44649
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp50.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp50.c
new file mode 100644 (file)
index 0000000..bf21672
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int
+foo (unsigned int i, unsigned int j)
+{
+  i &= 15;
+  j &= 15;
+  i += 1024;
+  j += 2048;
+  i &= j;
+  return i < 16;
+}
+
+int
+bar (int i)
+{
+  int c = 2;
+  c &= i > 6;
+  return c == 0;
+}
+
+int baz (int x, int y)
+{
+  x &= 15;
+  y &= 15;
+  x += 4;
+  y += 16;
+  x &= y;
+  return x < 20;
+}
+
+/* { dg-final { scan-tree-dump "Folding predicate i_\[^\n\r\]* to 1" "vrp1" } } */
+/* { dg-final { scan-tree-dump "Folding predicate c_\[^\n\r\]* to 1" "vrp1" } } */
+/* { dg-final { scan-tree-dump "Folding predicate x_\[^\n\r\]* to 1" "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
index 867dfd4..858cecf 100644 (file)
@@ -69,6 +69,7 @@ int main (int argc, const char* argv[])
       if (input[i] > 200)
         abort();
       output[i] = 0;
+      __asm__ volatile ("");
     }
 
   foo (input, output);
index 0867e4c..2aac9ac 100644 (file)
@@ -2578,6 +2578,58 @@ extract_range_from_binary_expr (value_range_t *vr,
 
       if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p)
        min = max = int_const_binop (code, vr0.max, vr1.max, 0);
+      else if (range_int_cst_p (&vr0)
+              && range_int_cst_p (&vr1)
+              && tree_int_cst_sgn (vr0.min) >= 0
+              && tree_int_cst_sgn (vr1.min) >= 0)
+       {
+         double_int vr0_mask = tree_to_double_int (vr0.min);
+         double_int vr1_mask = tree_to_double_int (vr1.min);
+         double_int maxd, diff;
+         tree mask;
+
+         min = build_int_cst (expr_type, 0);
+         /* Compute non-zero bits mask from both ranges.  */
+         if (!vr0_int_cst_singleton_p)
+           {
+             maxd = tree_to_double_int (vr0.max);
+             diff = double_int_sub (maxd, vr0_mask);
+             if (diff.high)
+               {
+                 diff.low = ~(unsigned HOST_WIDE_INT)0;
+                 diff.high = ((HOST_WIDE_INT) 2
+                              << floor_log2 (diff.high)) - 1;
+               }
+             else
+               diff.low = ((HOST_WIDE_INT) 2 << floor_log2 (diff.low)) - 1;
+             vr0_mask = double_int_ior (vr0_mask,
+                                        double_int_ior (maxd, diff));
+           }
+         if (!vr1_int_cst_singleton_p)
+           {
+             maxd = tree_to_double_int (vr1.max);
+             diff = double_int_sub (maxd, vr1_mask);
+             if (diff.high)
+               {
+                 diff.low = ~(unsigned HOST_WIDE_INT)0;
+                 diff.high = ((HOST_WIDE_INT) 2
+                              << floor_log2 (diff.high)) - 1;
+               }
+             else
+               diff.low = ((HOST_WIDE_INT) 2 << floor_log2 (diff.low)) - 1;
+             vr1_mask = double_int_ior (vr1_mask,
+                                        double_int_ior (maxd, diff));
+           }
+         mask = double_int_to_tree (expr_type,
+                                    double_int_and (vr0_mask, vr1_mask));
+         max = vr0.max;
+         if (tree_int_cst_lt (vr1.max, max))
+           max = vr1.max;
+         if (!TREE_OVERFLOW (mask)
+             && tree_int_cst_lt (mask, max)
+             && tree_int_cst_sgn (mask) >= 0)
+           max = mask;
+       }
       else if (vr0_int_cst_singleton_p
               && tree_int_cst_sgn (vr0.max) >= 0)
        {