+2018-06-01 Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR tree-optimization/85989
+ * gimple-ssa-backprop.c (backprop::m_visited_phis): New member
+ variable.
+ (backprop::intersect_uses): Check it when deciding whether this
+ is a backedge reference.
+ (backprop::process_block): Add each phi to m_visited_phis
+ after visiting it, then clear it at the end.
+
2018-06-01 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (vect_dr_stmt): New function.
post-order walk. */
auto_sbitmap m_visited_blocks;
+ /* A bitmap of phis that we have finished processing in the initial
+ post-order walk, excluding those from blocks mentioned in
+ M_VISITED_BLOCKS. */
+ auto_bitmap m_visited_phis;
+
/* A worklist of SSA names whose definitions need to be reconsidered. */
auto_vec <tree, 64> m_worklist;
{
if (is_gimple_debug (stmt))
continue;
- if (is_a <gphi *> (stmt)
- && !bitmap_bit_p (m_visited_blocks, gimple_bb (stmt)->index))
+ gphi *phi = dyn_cast <gphi *> (stmt);
+ if (phi
+ && !bitmap_bit_p (m_visited_blocks, gimple_bb (phi)->index)
+ && !bitmap_bit_p (m_visited_phis,
+ SSA_NAME_VERSION (gimple_phi_result (phi))))
{
/* Skip unprocessed phis. */
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "[BACKEDGE] ");
print_generic_expr (dump_file, var);
fprintf (dump_file, " in ");
- print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
}
}
else
}
for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi);
gsi_next (&gpi))
- process_var (gimple_phi_result (gpi.phi ()));
+ {
+ tree result = gimple_phi_result (gpi.phi ());
+ process_var (result);
+ bitmap_set_bit (m_visited_phis, SSA_NAME_VERSION (result));
+ }
+ bitmap_clear (m_visited_phis);
}
/* Delete the definition of VAR, which has no uses. */
--- /dev/null
+/* { dg-do run } */
+
+#define N 9
+
+void __attribute__((noipa))
+f (double x, double y, double *res)
+{
+ y = -y;
+ for (int i = 0; i < N; ++i)
+ {
+ double tmp = y;
+ y = x;
+ x = tmp;
+ res[i] = i;
+ }
+ res[N] = y * y;
+ res[N + 1] = x;
+}
+
+int
+main (void)
+{
+ double res[N + 2];
+ f (10, 20, res);
+ for (int i = 0; i < N; ++i)
+ if (res[i] != i)
+ __builtin_abort ();
+ if (res[N] != 100 || res[N + 1] != -20)
+ __builtin_abort ();
+ return 0;
+}