https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116799
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Actually, seems loop-doloop.cc doesn't look at REG_DEAD notes, but at live out.
/* Ensure that the new sequence doesn't clobber a register that
is live at the end of the block. */
{
bitmap modified = BITMAP_ALLOC (NULL);
for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i))
note_stores (i, record_reg_sets, modified);
basic_block loop_end = desc->out_edge->src;
bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
BITMAP_FREE (modified);
if (fail)
{
if (dump_file)
fprintf (dump_file, "Doloop: doloop pattern clobbers live out\n");
return false;
}
}
Now, in loop2_init dump I still see the expected
(jump_insn 38 37 42 5 (set (pc)
(if_then_else (ltu (reg:CCU 33 %cc)
(const_int 0 [0]))
(label_ref 36)
(pc))) "pr116799.c":15:22 discrim 1 2173 {*cjump_64}
(int_list:REG_BR_PROB 1014686028 (nil))
-> 36)
;; lr out 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
;; live out 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
and
;; basic block 16, loop depth 0, count 55807731 (estimated locally, freq
0.4859), maybe hot
;; prev block 15, next block 1, flags: (REACHABLE, RTL, MODIFIED)
;; pred: 5 [5.5% (guessed)] count:55807731 (estimated locally, freq
0.4859) (FALLTHRU,LOOP_EXIT)
;; bb 16 artificial_defs: { }
;; bb 16 artificial_uses: { u-1(11){ }u-1(15){ }u-1(32){ }u-1(34){ }}
;; lr in 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
;; lr use 11 [%r11] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp]
;; lr def
;; live in 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
;; live gen
;; live kill
i.e. 33 [%cc] is live on the edge.
But loop2_invariant dump already doesn't:
(jump_insn 38 37 42 5 (set (pc)
(if_then_else (ltu (reg:CCU 33 %cc)
(const_int 0 [0]))
(label_ref 36)
(pc))) "pr116799.c":15:22 discrim 1 2173 {*cjump_64}
(int_list:REG_BR_PROB 1014686028 (nil))
-> 36)
;; succ: 3 [94.5% (guessed)] count:958878294 (estimated locally, freq
8.3480)
;; 16 [5.5% (guessed)] count:55807731 (estimated locally, freq
0.4859) (FALLTHRU,LOOP_EXIT)
;; lr out 11 [%r11] 15 [%r15] 32 [%ap] 34 [%fp] 65 68
;; live out 68
and
;; basic block 16, loop depth 0, count 55807731 (estimated locally, freq
0.4859), maybe hot
;; prev block 15, next block 1, flags: (REACHABLE, RTL, MODIFIED)
;; pred: 5 [5.5% (guessed)] count:55807731 (estimated locally, freq
0.4859) (FALLTHRU,LOOP_EXIT)
;; bb 16 artificial_defs: { }
;; bb 16 artificial_uses: { u-1(11){ }u-1(15){ }u-1(32){ }u-1(34){ }}
;; lr in 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
;; lr use 11 [%r11] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp]
;; lr def
;; live in 11 [%r11] 14 [%r14] 15 [%r15] 32 [%ap] 33 [%cc] 34 [%fp] 65 68
69
;; live gen
;; live kill
Well, it is in live in of bb16, but not in live out of bb 5.
And one can see the same state in loop-doloop.cc:
Breakpoint 5, doloop_optimize (loop=0x7fffea546260) at
../../gcc/loop-doloop.cc:802
802 bool fail = bitmap_intersect_p (df_get_live_out (loop_end),
modified);
(gdb) p debug (desc->out_edge)
<edge (5 -> 16)>
5 [5.5% (guessed)] count:5625631 (estimated locally, freq 0.0490)
(FALLTHRU,LOOP_EXIT)
$2 = void
(gdb) p debug (df_get_live_out (desc->out_edge->src))
68
$3 = void
(gdb) p debug (df_get_live_in (desc->out_edge->dest))
11, 14, 15, 32, 33, 34, 65, 68, 69
$4 = void
(gdb) p debug (modified)
33, 93
$5 = void
I.e. if one would instead check df_get_live_in of the out_edge's destination,
it would punt.
Maybe the bug is caused by the introduction of df_analyze_loop in PR38518?
I mean if a pass itself only cares about df within a loop, it might be fine,
but e.g. looking at the live_out/lr_out whether something is live on the exit
edge is not.
Certainly the change of df_get_live_out from
11, 14, 15, 32, 33, 34, 65, 68, 69
to
68
happens during df_analyze_1 called from df_analyze_loop on the loop with bb 5
header (i.e. the block whose df_get_live_out changed).
But unfortunately it isn't just loop2_invariant which uses df_analyze_loop, but
also
loop-iv.cc used by most of the loop passes.
If it was just loop2_invariant, perhaps we could just do full df_analyze at the
end of the pass, but as loop-doloop.cc will
iv_analysis_loop_init (loop);
which does that df_analyze_loop, but then wants to check the live registers in
/* Ensure that the new sequence doesn't clobber a register that
is live at the end of the block. */
{
bitmap modified = BITMAP_ALLOC (NULL);
for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i))
note_stores (i, record_reg_sets, modified);
basic_block loop_end = desc->out_edge->src;
bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
BITMAP_FREE (modified);
if (fail)
{
if (dump_file)
fprintf (dump_file, "Doloop: doloop pattern clobbers live out\n");
return false;
}
}
I'm not sure what can be done.
Perhaps doing that df_get_live_in (desc->out_edge->dest) instead would help a
little
bit (like in this case), but am not sure if it say work also if the exit edge's
destination is in some outer loop and the register use only on the exit edge of
the outer loop.