From: Jakub Jelinek Date: Mon, 17 Jul 2017 09:10:23 +0000 (+0200) Subject: re PR tree-optimization/81365 (GCC miscompiles swap) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e8dd1313132e5aaa4c66b0bd2135919707dc45b6;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92f7c7f2e9b..2f29824f915 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-07-17 Jakub Jelinek + + 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 PR 80929 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67ffc3ef502..141d035cf6d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-07-17 Jakub Jelinek + PR tree-optimization/81365 + * g++.dg/torture/pr81365.C: New test. + PR tree-optimization/81396 * gcc.dg/tree-ssa/pr81396.c: New test. diff --git a/gcc/testsuite/g++.dg/torture/pr81365.C b/gcc/testsuite/g++.dg/torture/pr81365.C new file mode 100644 index 00000000000..fde5e503df9 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr81365.C @@ -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 (); +} diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index 8f8c1336c02..7dcb9ee49a4 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -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. */