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.

Reply via email to