re PR tree-optimization/51247 (ICE in set_value_range, at tree-vrp.c:417)

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.

From-SVN: r181818
This commit is contained in:
Jakub Jelinek 2011-11-29 22:03:09 +01:00 committed by Jakub Jelinek
parent 781c528f2e
commit c360c0fb8a
4 changed files with 68 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;