From 5cb8610d3a8f8849a4bb6a0f81a2934484d6a15a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 15 Nov 2023 12:24:46 +0100 Subject: tree-optimization/112282 - wrong-code with ifcvt hoisting The following avoids hoisting of invariants from conditionally executed parts of an if-converted loop. That now makes a difference since we perform bitfield lowering even when we do not actually if-convert the loop. if-conversion deals with resetting flow-sensitive info when necessary already. PR tree-optimization/112282 * tree-if-conv.cc (ifcvt_hoist_invariants): Only hoist from the loop header. * gcc.dg/torture/pr112282.c: New testcase. --- gcc/tree-if-conv.cc | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'gcc/tree-if-conv.cc') diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 0190cf2..0bde281 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -3468,30 +3468,28 @@ ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt) static void ifcvt_hoist_invariants (class loop *loop, edge pe) { + /* Only hoist from the now unconditionally executed part of the loop. */ + basic_block bb = loop->header; gimple_stmt_iterator hoist_gsi = {}; - unsigned int num_blocks = loop->num_nodes; - basic_block *body = get_loop_body (loop); - for (unsigned int i = 0; i < num_blocks; ++i) - for (gimple_stmt_iterator gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);) - { - gimple *stmt = gsi_stmt (gsi); - if (ifcvt_can_hoist (loop, pe, stmt)) - { - /* Once we've hoisted one statement, insert other statements - after it. */ - gsi_remove (&gsi, false); - if (hoist_gsi.ptr) - gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT); - else - { - gsi_insert_on_edge_immediate (pe, stmt); - hoist_gsi = gsi_for_stmt (stmt); - } - continue; - } - gsi_next (&gsi); - } - free (body); + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) + { + gimple *stmt = gsi_stmt (gsi); + if (ifcvt_can_hoist (loop, pe, stmt)) + { + /* Once we've hoisted one statement, insert other statements + after it. */ + gsi_remove (&gsi, false); + if (hoist_gsi.ptr) + gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT); + else + { + gsi_insert_on_edge_immediate (pe, stmt); + hoist_gsi = gsi_for_stmt (stmt); + } + continue; + } + gsi_next (&gsi); + } } /* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff its -- cgit v1.1