Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard.
2018-02-08 Richard Biener <rguent...@suse.de> PR tree-optimization/84233 * tree-ssa-phiprop.c (propagate_with_phi): Use separate changed flag instead of boguously re-using phi_inserted. * g++.dg/torture/pr84233.C: New testcase. Index: gcc/tree-ssa-phiprop.c =================================================================== --- gcc/tree-ssa-phiprop.c (revision 257445) +++ gcc/tree-ssa-phiprop.c (working copy) @@ -270,6 +270,7 @@ propagate_with_phi (basic_block bb, gphi use_operand_p arg_p, use; ssa_op_iter i; bool phi_inserted; + bool changed; tree type = NULL_TREE; if (!POINTER_TYPE_P (TREE_TYPE (ptr)) @@ -317,6 +318,7 @@ propagate_with_phi (basic_block bb, gphi /* Replace the first dereference of *ptr if there is one and if we can move the loads to the place of the ptr phi node. */ phi_inserted = false; + changed = false; FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) { gimple *def_stmt; @@ -403,7 +405,7 @@ propagate_with_phi (basic_block bb, gphi unlink_stmt_vdef (use_stmt); gsi_remove (&gsi, true); - phi_inserted = true; + changed = true; } /* Found a proper dereference. Insert a phi node if this @@ -424,6 +426,7 @@ propagate_with_phi (basic_block bb, gphi gsi_remove (&gsi, true); phi_inserted = true; + changed = true; } else { @@ -431,13 +434,14 @@ propagate_with_phi (basic_block bb, gphi load. */ gimple_assign_set_rhs1 (use_stmt, res); update_stmt (use_stmt); + changed = true; } next:; /* Continue searching for a proper dereference. */ } - return phi_inserted; + return changed; } /* Main entry for phiprop pass. */ Index: gcc/testsuite/g++.dg/torture/pr84233.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr84233.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr84233.C (working copy) @@ -0,0 +1,25 @@ +// { dg-do compile } +// { dg-additional-options "-w" } + +void a(const char *, int, const char *, const char *); +template <typename b> void c(b); +struct d { + long e; + template <typename> union f; + template <typename h> union f<h *> { + f(h *i) : j(i) {} + h *j; + long bits; + }; + static int k(volatile long &i) { return *(int *)f<volatile long *>(&i).bits; } + typedef long g; + operator g() volatile { + int l = k(e); + c(l); + } +}; +struct : d { + } m, n; +bool o; +void p() { (o ? m : n) ? (void)0 : a("", 5, "", ""); } +