This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH v2] lra: fix spill_hard_reg_in_range clobber check
- From: Ilya Leoshkevich <iii at linux dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: vmakarov at gcc dot gnu dot org, asolokha at gmx dot com, bergner at vnet dot ibm dot com, krebbel at linux dot ibm dot com, rdapp at linux dot ibm dot com, Ilya Leoshkevich <iii at linux dot ibm dot com>
- Date: Wed, 17 Oct 2018 20:14:52 +0200
- Subject: [PATCH v2] lra: fix spill_hard_reg_in_range clobber check
Boostrapped and regtested on x86_64-redhat-linux.
Changes since v1:
* Added the missing INSN_P () check.
* Rewrote the commit message.
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-16 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-16 Ilya Leoshkevich <iii@linux.ibm.com>
PR rtl-optimization/87596
* gcc.target/i386/pr87596.c: New test.
---
gcc/lra-constraints.c | 9 ++++++---
gcc/testsuite/gcc.target/i386/pr87596.c | 16 ++++++++++++++++
2 files changed, 22 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr87596.c
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 774d1ff3aaa..3cbe0465a87 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;
diff --git a/gcc/testsuite/gcc.target/i386/pr87596.c b/gcc/testsuite/gcc.target/i386/pr87596.c
new file mode 100644
index 00000000000..764708b694a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87596.c
@@ -0,0 +1,16 @@
+/* LRA corner case which triggered a segfault. */
+/* Reduced testcase by Arseny Solokha. */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O1 -fschedule-insns -ftrapv -funroll-all-loops -fno-tree-dominator-opts -fno-tree-loop-im" } */
+
+void
+wh (__int128 *ku)
+{
+ unsigned int *dp;
+
+ while (*ku < 1)
+ {
+ *dp <<= 32; /* { dg-warning "left shift count >= width of type" } */
+ ++*ku;
+ }
+}
--
2.19.0