diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-29 21:03:09 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-29 21:03:09 +0000 |
commit | 0418ac74cabf62c15e0256d50e0d232d9e3939ad (patch) | |
tree | 5587e1b6f3b377f5fb72c7b42e04089e716e597a | |
parent | 7206b04b3b0a7f97c8bc57598c86b84d70365ae6 (diff) | |
download | gcc-0418ac74cabf62c15e0256d50e0d232d9e3939ad.tar.gz |
PR tree-optimization/51247
* tree-vrp.c (extract_range_from_assert): For signed 1-bit precision
types instead of adding 1 subtract -1 and instead of subtracting 1
add -1 to avoid overflows.
* gcc.c-torture/compile/pr51247.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181818 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr51247.c | 16 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 50 |
4 files changed, 68 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 921b4f93049..3a802781fbc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-11-29 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/51247 + * tree-vrp.c (extract_range_from_assert): For signed 1-bit precision + types instead of adding 1 subtract -1 and instead of subtracting 1 + add -1 to avoid overflows. + 2011-11-29 Andrew MacLeod <amacleod@redhat.com> PR target/50123 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a5a39e3c4d1..3d695a22031 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-29 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/51247 + * gcc.c-torture/compile/pr51247.c: New test. + 2011-11-29 Andrew MacLeod <amacleod@redhat.com> PR target/50123 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51247.c b/gcc/testsuite/gcc.c-torture/compile/pr51247.c new file mode 100644 index 00000000000..16aa7f04b1a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr51247.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/51247 */ + +struct S { int s : 1; }; +int a; + +void +foo (int x, int y) +{ + struct S s; + s.s = !!y; + while (1) + { + unsigned l = 94967295; + a = x || (s.s &= l); + } +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 248bc61926f..5cbc25fcb1e 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1693,8 +1693,13 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) /* For LT_EXPR, we create the range [MIN, MAX - 1]. */ if (cond_code == LT_EXPR) { - tree one = build_int_cst (TREE_TYPE (max), 1); - max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, one); + if (TYPE_PRECISION (TREE_TYPE (max)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (max))) + max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max, + build_int_cst (TREE_TYPE (max), -1)); + else + max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, + build_int_cst (TREE_TYPE (max), 1)); if (EXPR_P (max)) TREE_NO_WARNING (max) = 1; } @@ -1728,8 +1733,13 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) /* For GT_EXPR, we create the range [MIN + 1, MAX]. */ if (cond_code == GT_EXPR) { - tree one = build_int_cst (TREE_TYPE (min), 1); - min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, one); + if (TYPE_PRECISION (TREE_TYPE (min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (min))) + min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min, + build_int_cst (TREE_TYPE (min), -1)); + else + min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, + build_int_cst (TREE_TYPE (min), 1)); if (EXPR_P (min)) TREE_NO_WARNING (min) = 1; } @@ -1915,9 +1925,19 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) min = positive_overflow_infinity (TREE_TYPE (var_vr->min)); } else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min))) - min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), - anti_max, - build_int_cst (TREE_TYPE (var_vr->min), 1)); + { + if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min))) + min = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), + anti_max, + build_int_cst (TREE_TYPE (var_vr->min), + -1)); + else + min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), + anti_max, + build_int_cst (TREE_TYPE (var_vr->min), + 1)); + } else min = fold_build_pointer_plus_hwi (anti_max, 1); max = real_max; @@ -1942,9 +1962,19 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) max = negative_overflow_infinity (TREE_TYPE (var_vr->min)); } else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min))) - max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), - anti_min, - build_int_cst (TREE_TYPE (var_vr->min), 1)); + { + if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min))) + max = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), + anti_min, + build_int_cst (TREE_TYPE (var_vr->min), + -1)); + else + max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), + anti_min, + build_int_cst (TREE_TYPE (var_vr->min), + 1)); + } else max = fold_build_pointer_plus_hwi (anti_min, -1); min = real_min; |