diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2021-01-13 13:59:10 +0100 |
---|---|---|
committer | Ilya Leoshkevich <iii@linux.ibm.com> | 2021-02-03 13:40:19 +0100 |
commit | 6dc82826ba61b25855e5a79f4479d009395a7299 (patch) | |
tree | 1cb9b2e9837b71ff29dae84ef69b34b6aae91704 /gcc/lra-spills.c | |
parent | 84110515b93a6709de24240d6658ac207db5129f (diff) | |
download | gcc-6dc82826ba61b25855e5a79f4479d009395a7299.zip gcc-6dc82826ba61b25855e5a79f4479d009395a7299.tar.gz gcc-6dc82826ba61b25855e5a79f4479d009395a7299.tar.bz2 |
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).
Diffstat (limited to 'gcc/lra-spills.c')
-rw-r--r-- | gcc/lra-spills.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index 26f56b2..01bd825 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -431,7 +431,7 @@ remove_pseudos (rtx *loc, rtx_insn *insn) alter_subreg (loc, false); if (GET_CODE (*loc) == MEM) { - lra_get_insn_recog_data (insn)->used_insn_alternative = -1; + lra_update_insn_recog_data (insn); if (lra_dump_file != NULL) fprintf (lra_dump_file, "Memory subreg was simplified in insn #%u\n", |