re PR rtl-optimization/87305 (Segfault in end_hard_regno in setup_live_pseudos_and_sp...
authorVladimir Makarov <vmakarov@redhat.com>
Thu, 10 Jan 2019 21:02:50 +0000 (21:02 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Thu, 10 Jan 2019 21:02:50 +0000 (21:02 +0000)
2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/87305
* lra-assigns.c
(setup_live_pseudos_and_spill_after_risky_transforms): Check
allocation for big endian pseudos used as paradoxical subregs and
spill them if it is wrong.
* lra-constraints.c (lra_constraints): Add a comment.

2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/87305
* gcc.target/aarch64/pr87305.c: New.

From-SVN: r267823

gcc/ChangeLog
gcc/lra-assigns.c
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr87305.c [new file with mode: 0644]

index a0276f28834af0cfb7fe243ac133fb29d86f510c..6bbcfa6aa87c2d6784fe8a61eea32bb1bac70737 100644 (file)
@@ -1,3 +1,12 @@
+2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/87305
+       * lra-assigns.c
+       (setup_live_pseudos_and_spill_after_risky_transforms): Check
+       allocation for big endian pseudos used as paradoxical subregs and
+       spill them if it is wrong.
+       * lra-constraints.c (lra_constraints): Add a comment.
+
 2019-01-10  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88792
index 131280452463d2bcefb529e0aa38f6bcc81b7133..5a4e1eb93dc8f3c54b760ff462c13aa766d20b18 100644 (file)
@@ -1146,12 +1146,12 @@ static void
 setup_live_pseudos_and_spill_after_risky_transforms (bitmap
                                                     spilled_pseudo_bitmap)
 {
-  int p, i, j, n, regno, hard_regno;
+  int p, i, j, n, regno, hard_regno, biggest_nregs, nregs_diff;
   unsigned int k, conflict_regno;
   poly_int64 offset;
   int val;
   HARD_REG_SET conflict_set;
-  machine_mode mode;
+  machine_mode mode, biggest_mode;
   lra_live_range_t r;
   bitmap_iterator bi;
   int max_regno = max_reg_num ();
@@ -1166,8 +1166,26 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
   for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
     if ((pic_offset_table_rtx == NULL_RTX
         || i != (int) REGNO (pic_offset_table_rtx))
-       && reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
-      sorted_pseudos[n++] = i;
+       && (hard_regno = reg_renumber[i]) >= 0 && lra_reg_info[i].nrefs > 0)
+      {
+       biggest_mode = lra_reg_info[i].biggest_mode;
+       biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
+       nregs_diff = (biggest_nregs
+                     - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (i)));
+       enum reg_class rclass = lra_get_allocno_class (i);
+
+       if (WORDS_BIG_ENDIAN
+           && (hard_regno - nregs_diff < 0
+               || !TEST_HARD_REG_BIT (reg_class_contents[rclass],
+                                      hard_regno - nregs_diff)))
+         {
+           /* Hard registers of paradoxical sub-registers are out of
+              range of pseudo register class.  Spill the pseudo.  */
+           reg_renumber[i] = -1;
+           continue;
+         }
+       sorted_pseudos[n++] = i;
+      }
   qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
   if (pic_offset_table_rtx != NULL_RTX
       && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
@@ -1206,10 +1224,11 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
            || hard_regno != reg_renumber[conflict_regno])
          {
            int conflict_hard_regno = reg_renumber[conflict_regno];
-           machine_mode biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
-           int biggest_nregs = hard_regno_nregs (conflict_hard_regno,
-                                                 biggest_mode);
-           int nregs_diff
+           
+           biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
+           biggest_nregs = hard_regno_nregs (conflict_hard_regno,
+                                             biggest_mode);
+           nregs_diff
              = (biggest_nregs
                 - hard_regno_nregs (conflict_hard_regno,
                                     PSEUDO_REGNO_MODE (conflict_regno)));
index 4f434e5332ff55cbc3ea54cda2b34c71b42e45f9..c08ad9a8964e880ae11ae196ab933b1d9ef4f20c 100644 (file)
@@ -4739,7 +4739,9 @@ lra_constraints (bool first_p)
   else
     /* On the first iteration we should check IRA assignment
        correctness.  In rare cases, the assignments can be wrong as
-       early clobbers operands are ignored in IRA.  */
+       early clobbers operands are ignored in IRA or usages of
+       paradoxical sub-registers are not taken into account by
+       IRA.  */
     lra_risky_transformations_p = first_p;
   new_insn_uid_start = get_max_uid ();
   new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
index ef231a2ac203bedfe9a6619f0c5f419f1e1760df..33dd6300d840da1db5fc691a2ce940cfd088d836 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/87305
+       * gcc.target/aarch64/pr87305.c: New.
+
 2019-01-10  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88792
diff --git a/gcc/testsuite/gcc.target/aarch64/pr87305.c b/gcc/testsuite/gcc.target/aarch64/pr87305.c
new file mode 100644 (file)
index 0000000..8beaa91
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -mbig-endian -w" } */
+
+int cc;
+
+void
+rc (__int128 *oi)
+{
+  __int128 qz = (__int128)2 << cc;
+
+  if (qz != 0)
+    {
+      if (cc != 0)
+        {
+          __int128 zp = 1;
+
+          for (;;)
+            {
+              unsigned __int128 *ar = &cc;
+              int y5;
+
+              if (oi != 0)
+                {
+ y3:
+                  zp = *oi + *ar;
+                }
+
+              y5 = (cc + 1) == ((*ar /= *oi) << ((zp >>= 128) / cc));
+              qz += !!y5 ? 1 : qz == (*ar ^ zp + 1);
+              ++*oi;
+            }
+        }
+      else
+        ++qz;
+    }
+
+  goto y3;
+}