[v2] lra: fix spill_hard_reg_in_range clobber check

Message ID 20181017181452.42584-1-iii@linux.ibm.com
State New
Headers show
Series
  • [v2] lra: fix spill_hard_reg_in_range clobber check
Related show

Commit Message

Ilya Leoshkevich Oct. 17, 2018, 6:14 p.m.
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

-- 
2.19.0

Comments

Jeff Law Oct. 18, 2018, 5:05 p.m. | #1
On 10/17/18 12:14 PM, Ilya Leoshkevich wrote:
> 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.

OK.
jeff

Patch

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;
+    }
+}