re PR tree-optimization/81365 (GCC miscompiles swap)
PR tree-optimization/81365 * tree-ssa-phiprop.c (propagate_with_phi): When considering hoisting aggregate moves onto bb predecessor edges, make sure there are no loads that could alias the lhs in between the start of bb and the loads from *phi. * g++.dg/torture/pr81365.C: New test. From-SVN: r250261
This commit is contained in:
parent
764eec6cf5
commit
e8dd131313
4 changed files with 76 additions and 1 deletions
|
@ -1,3 +1,11 @@
|
|||
2017-07-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/81365
|
||||
* tree-ssa-phiprop.c (propagate_with_phi): When considering hoisting
|
||||
aggregate moves onto bb predecessor edges, make sure there are no
|
||||
loads that could alias the lhs in between the start of bb and the
|
||||
loads from *phi.
|
||||
|
||||
2017-07-17 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR 80929
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
2017-07-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/81365
|
||||
* g++.dg/torture/pr81365.C: New test.
|
||||
|
||||
PR tree-optimization/81396
|
||||
* gcc.dg/tree-ssa/pr81396.c: New test.
|
||||
|
||||
|
|
39
gcc/testsuite/g++.dg/torture/pr81365.C
Normal file
39
gcc/testsuite/g++.dg/torture/pr81365.C
Normal file
|
@ -0,0 +1,39 @@
|
|||
// PR tree-optimization/81365
|
||||
// { dg-do run }
|
||||
|
||||
struct A { unsigned a; };
|
||||
|
||||
struct B {
|
||||
B (const A *x)
|
||||
{
|
||||
__builtin_memcpy (b, x, 3 * sizeof (A));
|
||||
__builtin_memcpy (c, x + 3, sizeof (A));
|
||||
__builtin_memset (c + 1, 0, sizeof (A));
|
||||
}
|
||||
bool
|
||||
foo (unsigned x)
|
||||
{
|
||||
A *it = c;
|
||||
if (it->a == x || (++it)->a == x)
|
||||
{
|
||||
A t(b[0]);
|
||||
b[0] = *it;
|
||||
*it = t;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
A b[3];
|
||||
A c[2];
|
||||
};
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
A x[] = { 4, 8, 12, 18 };
|
||||
B y(x);
|
||||
if (!y.foo (18))
|
||||
__builtin_abort ();
|
||||
if (!y.foo (4))
|
||||
__builtin_abort ();
|
||||
}
|
|
@ -327,7 +327,7 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
|
|||
if (!dominated_by_p (CDI_POST_DOMINATORS,
|
||||
bb, gimple_bb (use_stmt)))
|
||||
continue;
|
||||
|
||||
|
||||
/* Check whether this is a load of *ptr. */
|
||||
if (!(is_gimple_assign (use_stmt)
|
||||
&& gimple_assign_rhs_code (use_stmt) == MEM_REF
|
||||
|
@ -356,6 +356,9 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
|
|||
insert aggregate copies on the edges instead. */
|
||||
if (!is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
|
||||
{
|
||||
if (!gimple_vdef (use_stmt))
|
||||
goto next;
|
||||
|
||||
/* As we replicate the lhs on each incoming edge all
|
||||
used SSA names have to be available there. */
|
||||
if (! for_each_index (gimple_assign_lhs_ptr (use_stmt),
|
||||
|
@ -363,6 +366,28 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
|
|||
get_immediate_dominator (CDI_DOMINATORS,
|
||||
gimple_bb (phi))))
|
||||
goto next;
|
||||
|
||||
gimple *vuse_stmt;
|
||||
imm_use_iterator vui;
|
||||
use_operand_p vuse_p;
|
||||
/* In order to move the aggregate copies earlier, make sure
|
||||
there are no statements that could read from memory
|
||||
aliasing the lhs in between the start of bb and use_stmt.
|
||||
As we require use_stmt to have a VDEF above, loads after
|
||||
use_stmt will use a different virtual SSA_NAME. */
|
||||
FOR_EACH_IMM_USE_FAST (vuse_p, vui, vuse)
|
||||
{
|
||||
vuse_stmt = USE_STMT (vuse_p);
|
||||
if (vuse_stmt == use_stmt)
|
||||
continue;
|
||||
if (!dominated_by_p (CDI_DOMINATORS,
|
||||
gimple_bb (vuse_stmt), bb))
|
||||
continue;
|
||||
if (ref_maybe_used_by_stmt_p (vuse_stmt,
|
||||
gimple_assign_lhs (use_stmt)))
|
||||
goto next;
|
||||
}
|
||||
|
||||
phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
|
||||
|
||||
/* Remove old stmt. The phi is taken care of by DCE. */
|
||||
|
|
Loading…
Add table
Reference in a new issue