re PR tree-optimization/79666 (wrong code (SIGFPE) at -O2 on x86_64-linux-gnu (in both 32-bit and 64-bit modes))

2017-02-22  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/79666
	* tree-vrp.c (extract_range_from_binary_expr_1): Make sure
	to not symbolically negate if that may introduce undefined
	overflow.

	* gcc.dg/torture/pr79666.c: New testcase.

From-SVN: r245648
This commit is contained in:
Richard Biener 2017-02-22 12:11:27 +00:00 committed by Richard Biener
parent 8f4f841a3e
commit a9c774d2ae
4 changed files with 64 additions and 4 deletions

View File

@ -1,3 +1,10 @@
2017-02-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/79666
* tree-vrp.c (extract_range_from_binary_expr_1): Make sure
to not symbolically negate if that may introduce undefined
overflow.
2017-02-22 Martin Liska <mliska@suse.cz>
PR lto/79587

View File

@ -1,3 +1,8 @@
2017-02-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/79666
* gcc.dg/torture/pr79666.c: New testcase.
2017-02-22 Martin Liska <mliska@suse.cz>
PR lto/79587

View File

@ -0,0 +1,30 @@
/* { dg-do run } */
struct
{
unsigned a:6;
} b;
int c, e, g = 7;
signed char d, f = 6, h = -10;
void fn1 ()
{
for (; c < 9; c++)
{
if (f)
g = ~(~0 / (g ^ e));
b.a = ~0;
d = ~((h ^ b.a) & 132 & (~(f && g) | (d && 1)));
e = ~0;
if (d < 127 || f < 1)
continue;
g = 0;
}
}
int main ()
{
fn1 ();
return 0;
}

View File

@ -2631,8 +2631,17 @@ extract_range_from_binary_expr_1 (value_range *vr,
min = build_symbolic_expr (expr_type, sym_min_op0,
neg_min_op0, min);
else if (sym_min_op1)
min = build_symbolic_expr (expr_type, sym_min_op1,
neg_min_op1 ^ minus_p, min);
{
/* We may not negate if that might introduce
undefined overflow. */
if (! minus_p
|| neg_min_op1
|| TYPE_OVERFLOW_WRAPS (expr_type))
min = build_symbolic_expr (expr_type, sym_min_op1,
neg_min_op1 ^ minus_p, min);
else
min = NULL_TREE;
}
/* Likewise for the upper bound. */
if (sym_max_op0 == sym_max_op1)
@ -2641,8 +2650,17 @@ extract_range_from_binary_expr_1 (value_range *vr,
max = build_symbolic_expr (expr_type, sym_max_op0,
neg_max_op0, max);
else if (sym_max_op1)
max = build_symbolic_expr (expr_type, sym_max_op1,
neg_max_op1 ^ minus_p, max);
{
/* We may not negate if that might introduce
undefined overflow. */
if (! minus_p
|| neg_max_op1
|| TYPE_OVERFLOW_WRAPS (expr_type))
max = build_symbolic_expr (expr_type, sym_max_op1,
neg_max_op1 ^ minus_p, max);
else
max = NULL_TREE;
}
}
else
{