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

Wilco <wilco at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-10-24
                 CC|                            |segher at gcc dot gnu.org,
                   |                            |wilco at gcc dot gnu.org
          Component|target                      |rtl-optimization
            Summary|GCC generates bad code with |Combine: GCC generates bad
                   |-tune=thunderx2t99          |code with
                   |                            |-tune=thunderx2t99
     Ever confirmed|0                           |1

--- Comment #1 from Wilco <wilco at gcc dot gnu.org> ---
Combine seems to do the correct thing at first, creating a ldrsw but it then
invents a spurious REG_DEAD for r83:

Successfully matched this instruction:
(set (reg:DI 83 [ _26 ])
    (sign_extend:DI (mem:SI (plus:DI (mult:DI (reg:DI 83 [ _26 ])
                    (const_int 4 [0x4]))
                (reg/f:DI 76 [ _4 ])) [8 *_7+0 S4 A32])))
Successfully matched this instruction:
(set (reg/v:SI 82 [ pD.3023 ])
    (subreg:SI (reg:DI 83 [ _26 ]) 0))
allowing combination of insns 19, 20 and 21
original costs 8 + 20 + 4 = 32
replacement costs 28 + 4 = 32
deferring rescan insn with uid = 21.
deferring deletion of insn with uid = 19.
modifying insn i2    20: r83:DI=sign_extend([r83:DI*0x4+r76:DI])
      REG_DEAD r76:DI
deferring rescan insn with uid = 20.
modifying insn i3    21: r82:SI=r83:DI#0  ** all good so far, both r82/r83 are
live
      REG_DEAD r83:DI   *** OOPS
      REG_DEAD r83:DI
      REG_DEAD r83:DI
deferring rescan insn with uid = 21.

The REG_DEAD r83 incorrect as both r82 and r83 are still live. I think it may
be due to this earlier combine:

Trying 18 -> 19:
Successfully matched this instruction:
(set (reg/f:DI 78 [ _7 ])
    (plus:DI (ashift:DI (reg:DI 83 [ _26 ])
            (const_int 2 [0x2]))
        (reg/f:DI 76 [ _4 ])))
allowing combination of insns 18 and 19
original costs 4 + 4 = 8
replacement cost 8
deferring deletion of insn with uid = 18.
modifying insn i3    19: r78:DI=r83:DI<<0x2+r76:DI
      REG_DEAD r83:DI
      REG_DEAD r76:DI
deferring rescan insn with uid = 19.

So I guess the bug is that when combining multiple instructions, dead notes
aren't removed if later instructions assign the the same register.

Reply via email to