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

--- Comment #12 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Looking at this again after nearly 2 years.

At ud-dce things are actually not in bad shape:

(insn 7 4 8 2 (set (reg:SI 141)
        (const_int 1 [0x1])) "j.c":2:20 278 {*movsi_internal}
     (nil))
(insn 8 7 10 2 (set (reg:DI 142)
        (sign_extend:DI (ashift:SI (reg:SI 141)
                (subreg:QI (reg/v:DI 138 [ rs2 ]) 0)))) "j.c":2:20 314
{ashlsi3_extend}
     (expr_list:REG_DEAD (reg:SI 141)
        (expr_list:REG_DEAD (reg/v:DI 138 [ rs2 ])
            (expr_list:REG_EQUAL (sign_extend:DI (ashift:SI (const_int 1 [0x1])
                        (subreg:QI (reg/v:DI 138 [ rs2 ]) 0)))
                (nil)))))
(insn 10 8 12 2 (set (reg:DI 143)
        (not:DI (reg:DI 142))) "j.c":2:17 115 {one_cmpldi2}
     (expr_list:REG_DEAD (reg:DI 142)
        (nil)))
(insn 12 10 13 2 (set (reg:DI 145)
        (and:DI (reg/v:DI 137 [ rs1 ])
            (reg:DI 143))) "j.c":2:15 106 {*anddi3}
     (expr_list:REG_DEAD (reg:DI 143)
        (expr_list:REG_DEAD (reg/v:DI 137 [ rs1 ])
            (nil))))
(insn 13 12 18 2 (set (reg:DI 146)
        (sign_extend:DI (subreg:SI (reg:DI 145) 0))) "j.c":2:15 discrim 1 127
{*extendsidi2_internal}
     (expr_list:REG_DEAD (reg:DI 145)
        (nil)))
(insn 18 13 19 2 (set (reg/i:DI 10 a0)
        (reg:DI 146)) "j.c":3:1 277 {*movdi_64bit}
     (expr_list:REG_DEAD (reg:DI 146)
        (nil)))

insn 13 is critical.  It essentially says we only care about the low 32 bits of
(reg:DI 145).   But we lose that info during the combination steps:

Trying 12 -> 13:
   12: r145:DI=~r142:DI&r147:DI
      REG_DEAD r142:DI
      REG_DEAD r147:DI
   13: r146:DI=sign_extend(r145:DI#0)
      REG_DEAD r145:DI
Successfully matched this instruction:
(set (reg:DI 146)
    (and:DI (not:DI (reg:DI 142))
        (reg:DI 147 [ rs1 ])))

Which makes sense on many levels.  But after that combination we have literally
no chance to generate the code we want as it makes bits 32..63 as set by insn 8
live.

One idea would be to have ext-dce eliminate the sign extension at insn 8.  I
think I tried that in another context a year or so ago.  But that does seem
like a necessary step to break the logjam we've got with this kind of code.

Reply via email to