diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-07-09 08:58:42 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-07-09 08:58:42 +0200 |
commit | ac2856486dd4f460c7cdb0db6a027df6010fee49 (patch) | |
tree | eb7d0b98a599a0401264449c3b05d3acece12741 | |
parent | 79a3f089cc926c3355c93a3f01db1f02ba7a9e04 (diff) | |
download | gcc-ac2856486dd4f460c7cdb0db6a027df6010fee49.zip gcc-ac2856486dd4f460c7cdb0db6a027df6010fee49.tar.gz gcc-ac2856486dd4f460c7cdb0db6a027df6010fee49.tar.bz2 |
tree-vrp.c (extract_range_from_binary_expr): If both ranges are range_int_cst_p with non-negative minimum...
* 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.
* gcc.dg/tree-ssa/vrp50.c: New test.
* gcc.dg/vect/slp-perm-4.c (main): Make sure loop isn't vectorized.
From-SVN: r161984
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp50.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/slp-perm-4.c | 1 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 52 |
5 files changed, 100 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73d21e6..e8e4f1b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52a54e9..f6e5b37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..bf21672 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp50.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-4.c b/gcc/testsuite/gcc.dg/vect/slp-perm-4.c index 867dfd4..858cecf 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-4.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-4.c @@ -69,6 +69,7 @@ int main (int argc, const char* argv[]) if (input[i] > 200) abort(); output[i] = 0; + __asm__ volatile (""); } foo (input, output); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 0867e4c..2aac9ac 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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) { |