diff options
author | Richard Biener <rguenther@suse.de> | 2023-11-15 12:24:46 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-11-15 13:09:03 +0100 |
commit | 5cb8610d3a8f8849a4bb6a0f81a2934484d6a15a (patch) | |
tree | 736cffc7be5688f3a99a4458eafa0936f9f36e05 /gcc/tree-if-conv.cc | |
parent | bcef48b59e4b4f86595929b490a8303da1239ac0 (diff) | |
download | gcc-5cb8610d3a8f8849a4bb6a0f81a2934484d6a15a.zip gcc-5cb8610d3a8f8849a4bb6a0f81a2934484d6a15a.tar.gz gcc-5cb8610d3a8f8849a4bb6a0f81a2934484d6a15a.tar.bz2 |
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.
Diffstat (limited to 'gcc/tree-if-conv.cc')
-rw-r--r-- | gcc/tree-if-conv.cc | 44 |
1 files changed, 21 insertions, 23 deletions
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 |