lra: clear lra_insn_recog_data after simplifying a mem subreg
authorIlya Leoshkevich <iii@linux.ibm.com>
Wed, 13 Jan 2021 12:59:10 +0000 (13:59 +0100)
committerIlya Leoshkevich <iii@linux.ibm.com>
Wed, 3 Feb 2021 12:40:19 +0000 (13:40 +0100)
commit6dc82826ba61b25855e5a79f4479d009395a7299
tree1cb9b2e9837b71ff29dae84ef69b34b6aae91704
parent84110515b93a6709de24240d6658ac207db5129f
lra: clear lra_insn_recog_data after simplifying a mem subreg

Suppose we have:

    (insn (set (reg:FPRX2 70) (subreg:FPRX2 (reg/v:TF 63) 0)))

where operand_loc[0] points to r70 and operand_loc[1] points to r63.
If r63 is spilled, remove_pseudos() will change this insn to:

  (insn (set (reg:FPRX2 70)
             (subreg:FPRX2 (mem/c:TF (plus:DI (reg:DI %fp)
                                      (const_int 144))))))

This is fine so far: rtx pointed to by operand_loc[1] has been changed
from (reg) to (mem), but its slot is still under (subreg).  However,
alter_subreg() will simplify this insn to:

  (insn (set (reg:FPRX2 70)
             (mem/c:FPRX2 (plus:DI (reg:DI %fp) (const_int 144)))))

The (subreg) is gone, and therefore operand_loc[1] is no longer valid.
This will prevent process_insn_for_elimination() from updating the spill
slot offset, causing miscompilation: different instructions will refer
to the same spill slot using different offsets.

Fix by clearing all the cached data, and not just used_insn_alternative.

gcc/ChangeLog:

2021-01-13  Ilya Leoshkevich  <iii@linux.ibm.com>

* lra-spills.c (remove_pseudos): Call lra_update_insn_recog_data()
after calling alter_subreg() on a (mem).
gcc/lra-spills.c