https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67191

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, reproduced with a cross.  The assert means the DOM walk didn't visit the
definition of an operand before its use which shouldn't happen.  The use
is in a loop nested in a loop which contains the definition dominating the
nested loop entry.

Ah, so we are detecting the outer loop as not executable.  But then the DOM
walk goes to a CFG part looking like


   <bb10>
   /    \
  /     <bb11>
 <bb28>  |    \
  |     <bb20> \
  |    /        <loop exit>
 <bb13>
  |    \
  |     <other loop exit>
 <loop latch>

and for some reason it visits this in order 10, 28, 13(!) instead of
what I would expect (10, 28, 11, 20, 13).  So we don't see bb13 as
not executable and thus the assert triggers.

In domwalk the sort using the postorder number is supposed to make
sure that CFG merges inside the dominator children are visited last.
Somehow this doesn't work here and thus results in non-optimal order
for propagation.  Of course due to the CFG the children are
only 13, 28 and 11 (not 20) so there isn't a "merge" within the
children :/

In the end the assert wasn't meant to stay - it's fine if it triggers
for code that ends up being unreachable.  So the immediate fix is to
remove it but we still want to fix that dominator walk ordering issue
IMHO, which of course would make it a non-dominator walk in some sense
(walking bb11 children before completing bb10 children).

PRE uses a worklist approach and defers blocks which have unvisited
predecessors exactly to overcome this ordering issue which is bad
for propagation passes (if only for compile-time reasons).

Reply via email to