diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73d21e6a52a6..e8e4f1b542fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-07-09 Jakub Jelinek + + * tree-vrp.c (extract_range_from_binary_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 * genrecog.c: Include diagnostic-core.h before toplev.h. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52a54e9da28e..f6e5b37ca6ab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-07-09 Jakub Jelinek + + * 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 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 000000000000..bf21672c61af --- /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 867dfd4aa906..858cecf0d9cb 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 0867e4c5c3ee..2aac9aca5f6d 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) {