https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120046
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Assignee|rguenth at gcc dot gnu.org |unassigned at gcc dot
gnu.org
Status|ASSIGNED |NEW
CC| |jakub at gcc dot gnu.org
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
So w/o GCSE we still have after RA:
;; basic block 4
(insn 16 15 49 4 (set (reg:DI 0 ax [orig:102 D.2980 ] [102])
(reg/v:DI 3 bx [orig:103 j ] [103])) "t.c":12:12 99 {*movdi_internal}
(expr_list:REG_EQUAL (const_int 5000000000 [0x12a05f200])
(nil)))
(jump_insn 49 16 50 4 (set (pc)
(label_ref 38)) "t.c":12:12 1491 {jump}
(nil)
-> 38)
but then cross-jumping comes along (341r.jump2) and does
Splitting bb 8 before 1 insns
changing bb of uid 62
unscanned insn
changing bb of uid 37
from 8 to 10
Cross jumping from bb 4 to bb 8; 1 common insns
changing bb of uid 63
unscanned insn
changing bb of uid 16
from 4 to 11
changing bb of uid 49
from 4 to 11
scanning new insn with uid = 65.
deleting insn with uid = 49.
deleting insn with uid = 16.
deleting block 11
I suppose the "common instruction" is
;; basic block 8
...
(insn 37 36 38 8 (set (reg:DI 0 ax [orig:102 D.2980 ] [102])
(const_int 0 [0])) "t.c":21:10 99 {*movdi_internal}
(expr_list:REG_EQUAL (const_int 5000000000 [0x12a05f200])
(nil)))
;; succ: 9 [always] count:37860610 (estimated locally, freq 0.3332)
(FALLTHRU) t.c:21:10
where I note the bogus REG_EQUAL note which comes from fwprop1 which does
propagating insn 5 into insn 37, replacing:
(set (reg:DI 102 [ D.2980 ])
(reg/v:DI 103 [ j ]))
successfully matched this instruction to *movdi_internal:
(set (reg:DI 102 [ D.2980 ])
(const_int 5000000000 [0x12a05f200]))
-fno-forward-propagate fixes the execution failure.
I think forwprop is correct but then CSE2 comes along and transforms this to
(insn 37 36 38 9 (set (reg:DI 102 [ D.2980 ])
(const_int 0 [0])) "t.c":21:10 99 {*movdi_internal}
(expr_list:REG_DEAD (reg/v:DI 103 [ j ])
(expr_list:REG_EQUAL (const_int 5000000000 [0x12a05f200])
(nil))))
there isn't any hint in the dumps on what CSE actually does, but I think
it correctly propagates
(insn 13 12 14 3 (set (reg:CCZ 17 flags)
(compare:CCZ (reg/v:DI 103 [ j ])
(const_int 0 [0]))) "t.c":11:6 12 {*cmpdi_ccno_1}
(expr_list:REG_DEAD (reg/v:DI 103 [ j ])
(nil)))
(jump_insn 14 13 15 3 (set (pc)
(if_then_else (eq (reg:CCZ 17 flags)
(const_int 0 [0]))
(label_ref 19)
(pc))) "t.c":11:6 1490 {*jcc}
(expr_list:REG_DEAD (reg:CCZ 17 flags)
(int_list:REG_BR_PROB 1034442873 (nil)))
-> 19)
along the edge to BB 9. But it definitely fails to clear the REG_EQUAL
note and this note may be then wrong in the first place (thus a
forwprop bug?!). The code is actually unreachable, so the fallout
in cross-jumping is where it goes wrong.