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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is with fill_always_executed_in which works outer-to-inner loop and
does not re-consider blocks of inner loops iff its header is always executed
in an outer loop.  So it correctly computes the division is executed for
all outer loop iterations, but what's relevant for the hoisting is that
it's executed for all iterations of all loops of the nest involved.

I will see if the improvement to inner loop handling can be fixed.  Sth
as simple as the following does, but this might increase compile-time
a lot since we then process all inner loops again.  Testing this nevertheless.

diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index b9b1d92b518..27f53436ca1 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -3569,10 +3569,13 @@ fill_always_executed_in_1 (class loop *loop, sbitmap
contains_call)

       while (1)
        {
-         if (dump_enabled_p ())
-           dump_printf (MSG_NOTE, "BB %d is always executed in loop %d\n",
-                        last->index, loop->num);
-         SET_ALWAYS_EXECUTED_IN (last, loop);
+         if (last->loop_father == loop)
+           {
+             if (dump_enabled_p ())
+               dump_printf (MSG_NOTE, "BB %d is always executed in loop %d\n",
+                            last->index, loop->num);
+             SET_ALWAYS_EXECUTED_IN (last, loop);
+           }
          if (last == loop->header)
            break;
          last = get_immediate_dominator (CDI_DOMINATORS, last);

Reply via email to