diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2018-10-19 08:33:52 +0000 |
---|---|---|
committer | Ilya Leoshkevich <iii@gcc.gnu.org> | 2018-10-19 08:33:52 +0000 |
commit | 3664a0f184ad90a0aa65b473d180debce6402ab0 (patch) | |
tree | 2a03e07a844a678431b3cd5b040e01907a9e0480 /gcc/lra-constraints.c | |
parent | ba9a8625b0a7eddb237d140e89ddb78afd1e3539 (diff) | |
download | gcc-3664a0f184ad90a0aa65b473d180debce6402ab0.zip gcc-3664a0f184ad90a0aa65b473d180debce6402ab0.tar.gz gcc-3664a0f184ad90a0aa65b473d180debce6402ab0.tar.bz2 |
lra: fix spill_hard_reg_in_range clobber check
FROM..TO range might contain NOTE_INSN_DELETED insns, for which the
corresponding entries in lra_insn_recog_data[] are NULLs. Example from
the problematic code from PR87596:
(note 148 154 68 7 NOTE_INSN_DELETED)
lra_insn_recog_data[] is used directly only when the insn in question
is taken from insn_bitmap, which is not the case here. In other
situations lra_get_insn_recog_data () guarded by INSN_P () or other
stricter predicate are used. So we need to do this here as well.
A tiny detail worth noting: I put the INSN_P () check before the
insn_bitmap check, because I believe that insn_bitmap can contain only
real insns anyway.
gcc/ChangeLog:
2018-10-19 Ilya Leoshkevich <iii@linux.ibm.com>
PR rtl-optimization/87596
* lra-constraints.c (spill_hard_reg_in_range): Use INSN_P () +
lra_get_insn_recog_data () instead of lra_insn_recog_data[]
for instructions in FROM..TO range.
gcc/testsuite/ChangeLog:
2018-10-19 Ilya Leoshkevich <iii@linux.ibm.com>
PR rtl-optimization/87596
* gcc.target/i386/pr87596.c: New test.
From-SVN: r265306
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 774d1ff..3cbe046 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -5696,12 +5696,15 @@ spill_hard_reg_in_range (int regno, enum reg_class rclass, rtx_insn *from, rtx_i continue; for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn)) { - lra_insn_recog_data_t id = lra_insn_recog_data[uid = INSN_UID (insn)]; - struct lra_static_insn_data *static_id = id->insn_static_data; + struct lra_static_insn_data *static_id; struct lra_insn_reg *reg; - if (bitmap_bit_p (&lra_reg_info[hard_regno].insn_bitmap, uid)) + if (!INSN_P (insn)) + continue; + if (bitmap_bit_p (&lra_reg_info[hard_regno].insn_bitmap, + INSN_UID (insn))) break; + static_id = lra_get_insn_recog_data (insn)->insn_static_data; for (reg = static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->regno == hard_regno) break; |