http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51505

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ebotcazou at gcc dot
                   |                            |gnu.org, jakub at gcc dot
                   |                            |gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-12-13 
08:29:00 UTC ---
Reload is innocent here.
IMHO the problem is that we have a REG_EQUAL note that refers to dead pseudos,
perhaps DF should just remove such notes?  Or it might be combiner fault.
Before combine we have:
(insn 30 2 5 2 (set (reg/v:QI 59 [ i ])
        (const_int 0 [0])) pr51505.c:14 -1
     (nil))

(insn 5 30 6 2 (set (reg:SI 60 [ D.1713 ])
        (sign_extend:SI (reg/v:QI 59 [ i ]))) pr51505.c:14 130 {extendqisi2}
     (expr_list:REG_DEAD (reg/v:QI 59 [ i ])
        (nil)))
...
(insn 10 9 11 2 (set (reg:DI 70 [ D.1713 ])
        (sign_extend:DI (reg:SI 60 [ D.1713 ]))) pr51505.c:14 124
{*extendsidi2_rex64}
     (expr_list:REG_DEAD (reg:SI 60 [ D.1713 ])
        (nil)))

(insn 11 10 12 2 (parallel [
            (set (reg:QI 71)
                (and:QI (reg:QI 68)
                    (mem/s/j:QI (plus:DI (plus:DI (reg/f:DI 20 frame)
                                (reg:DI 70 [ D.1713 ]))
                            (const_int -768 [0xfffffffffffffd00])) [0 s2.a S1
A8])))
            (clobber (reg:CC 17 flags))
        ]) pr51505.c:14 383 {*andqi_1}
     (expr_list:REG_DEAD (reg:DI 70 [ D.1713 ])
        (expr_list:REG_DEAD (reg:QI 68)
            (expr_list:REG_UNUSED (reg:CC 17 flags)
                (nil)))))

(insn 12 11 13 2 (set (mem/s/j:QI (plus:DI (plus:DI (reg/f:DI 20 frame)
                    (reg:DI 66 [ D.1713 ]))
                (const_int -1024 [0xfffffffffffffc00])) [0 e S1 A8])
        (reg:QI 71)) pr51505.c:14 66 {*movqi_internal}
     (expr_list:REG_DEAD (reg:QI 71)
        (expr_list:REG_DEAD (reg:DI 66 [ D.1713 ])
            (expr_list:REG_EQUAL (and:QI (reg:QI 68)
                    (mem/s/j:QI (plus:DI (plus:DI (reg/f:DI 20 frame)
                                (reg:DI 70 [ D.1713 ]))
                            (const_int -768 [0xfffffffffffffd00])) [0 s2.a S1
A8]))
                (nil)))))

Note REG_DEAD before insn 12 which uses pseudo 70 in its REG_EQUAL note.
Then during combine we decide to change mode of pseudo 70 from DImode to QImode
and just change it, thinking we've adjusted all places where it was used, but
in fact we adjust the content of the REG_EQUAL note to (and:QI (reg:QI 68)
(mem:QI (plus:DI (plus:DI (reg:DI 20) (reg:QI 70)) (const_int -768)))).
And of course, as this is not valid RTL, when reload attempts to use the
REG_EQUAL note it ICEs.  Now the combiner changing of pseudo 70 happens I think
when i3 is insn 12, i2 is insn 11 and i1 is insn 10, so in theory the combiner
should be able to do the adjustment of the REG_EQUAL note in there too, but I
wonder if similar mode transformation couldn't happen also when just working on
i3 where the pseudo is dead and some insns that feed it, with the REG_EQUAL
note being in some subsequent insns - then I doubt it would be able to do that.

Eric, what do you think about this?

Reply via email to