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

2016-10-06  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/77855
	* tree-ssa-pre.c (prune_clobbered_mems): Queue exprs to remove
	instead of removing the current item while iterating over the set
	which is not safe.

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

From-SVN: r240832
This commit is contained in:
Richard Biener 2016-10-06 12:17:53 +00:00 committed by Richard Biener
parent 139dc3c651
commit b397258804
4 changed files with 74 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2016-10-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77855
* tree-ssa-pre.c (prune_clobbered_mems): Queue exprs to remove
instead of removing the current item while iterating over the set
which is not safe.
2016-10-06 James Clarke <jrtc27@jrtc27.com>
Eric Botcazou <ebotcazou@adacore.com>

View File

@ -1,3 +1,8 @@
2016-10-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77855
* gcc.dg/torture/pr77855.c: New testcase.
2016-10-06 James Clarke <jrtc27@jrtc27.com>
Eric Botcazou <ebotcazou@adacore.com>

View File

@ -0,0 +1,48 @@
/* { dg-do run } */
int a, b = 1, c, e, f, g, k, m, n, o;
char d, h, i, j, l;
char res[2];
void __attribute__ ((noinline,noclone)) fn2 ()
{
d = 2;
}
void fn3 ()
{
for (;;)
{
for (; b; b--)
{
fn2 ();
if (e)
j = 1;
if (f)
L1:
k = j | (a & l);
for (;;)
{
__builtin_snprintf (res, 2, "%d\n", d);
if (d)
break;
for (; o; o--)
for (; n;)
for (; m; m++)
;
goto L1;
}
}
g = h;
c = i;
break;
}
}
int main ()
{
fn3 ();
if (res[0] != '2')
__builtin_abort ();
return 0;
}

View File

@ -2025,9 +2025,17 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
{
bitmap_iterator bi;
unsigned i;
pre_expr to_remove = NULL;
FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{
/* Remove queued expr. */
if (to_remove)
{
bitmap_remove_from_set (set, to_remove);
to_remove = NULL;
}
pre_expr expr = expression_for_id (i);
if (expr->kind == REFERENCE)
{
@ -2041,7 +2049,7 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
block, gimple_bb (def_stmt)))
|| (gimple_bb (def_stmt) == block
&& value_dies_in_block_x (expr, block))))
bitmap_remove_from_set (set, expr);
to_remove = expr;
}
}
else if (expr->kind == NARY)
@ -2053,9 +2061,13 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
as the available expression might be after the exit point. */
if (BB_MAY_NOTRETURN (block)
&& vn_nary_may_trap (nary))
bitmap_remove_from_set (set, expr);
to_remove = expr;
}
}
/* Remove queued expr. */
if (to_remove)
bitmap_remove_from_set (set, to_remove);
}
static sbitmap has_abnormal_preds;