[PR97978] LRA: Permit temporary allocation incorrectness after hard reg split.
authorVladimir N. Makarov <vmakarov@redhat.com>
Wed, 6 Jan 2021 19:48:53 +0000 (14:48 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Wed, 6 Jan 2021 21:13:30 +0000 (16:13 -0500)
LRA can crash when a hard register was split and the same hard register
was assigned on the previous assignment sub-pass.  The following
patch fixes this problem.

gcc/ChangeLog:

PR rtl-optimization/97978
* lra-int.h (lra_hard_reg_split_p): New external.
* lra.c (lra_hard_reg_split_p): New global.
(lra): Set up lra_hard_reg_split_p after splitting a hard reg.
* lra-assigns.c (lra_assign): Don't check allocation correctness
after hard reg splitting.

gcc/testsuite/ChangeLog:

PR rtl-optimization/97978
* gcc.target/i386/pr97978.c: New.

gcc/lra-assigns.c
gcc/lra-int.h
gcc/lra.c
gcc/testsuite/gcc.target/i386/pr97978.c [new file with mode: 0644]

index 9335e4c876ed2e9803fcb75d96c17df062bd31f7..c6a941fe66381ba733a0eda3f527a6c11383ed37 100644 (file)
@@ -1636,10 +1636,11 @@ lra_assign (bool &fails_p)
   bitmap_initialize (&all_spilled_pseudos, &reg_obstack);
   create_live_range_start_chains ();
   setup_live_pseudos_and_spill_after_risky_transforms (&all_spilled_pseudos);
-  if (! lra_asm_error_p && flag_checking)
-    /* Check correctness of allocation for call-crossed pseudos but
-       only when there are no asm errors as in the case of errors the
-       asm is removed and it can result in incorrect allocation.  */
+  if (! lra_hard_reg_split_p && ! lra_asm_error_p && flag_checking)
+    /* Check correctness of allocation but only when there are no hard reg
+       splits and asm errors as in the case of errors explicit insns involving
+       hard regs are added or the asm is removed and this can result in
+       incorrect allocation.  */
     for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
       if (lra_reg_info[i].nrefs != 0
          && reg_renumber[i] >= 0
index 75ba6560bcc86459d66b4496b9b37646dedd98d1..1b8f7b6ae6188379af4740c9a18ea647d4cff3b8 100644 (file)
@@ -273,6 +273,7 @@ typedef class lra_insn_recog_data *lra_insn_recog_data_t;
 
 extern FILE *lra_dump_file;
 
+extern bool lra_hard_reg_split_p;
 extern bool lra_asm_error_p;
 extern bool lra_reg_spill_p;
 
index 380a21ac2ac9ca71a8dffa11baec86469f7dfe6f..aa49de6f154f1ff90bb311b31950c69efad05ec8 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2211,6 +2211,9 @@ bitmap_head lra_subreg_reload_pseudos;
 /* File used for output of LRA debug information.  */
 FILE *lra_dump_file;
 
+/* True if we split hard reg after the last constraint sub-pass.  */
+bool lra_hard_reg_split_p;
+
 /* True if we found an asm error.  */
 bool lra_asm_error_p;
 
@@ -2359,6 +2362,7 @@ lra (FILE *f)
          if (live_p)
            lra_clear_live_ranges ();
          bool fails_p;
+         lra_hard_reg_split_p = false;
          do
            {
              /* We need live ranges for lra_assign -- so build them.
@@ -2403,6 +2407,7 @@ lra (FILE *f)
                  live_p = false;
                  if (! lra_split_hard_reg_for ())
                    break;
+                 lra_hard_reg_split_p = true;
                }
            }
          while (fails_p);
diff --git a/gcc/testsuite/gcc.target/i386/pr97978.c b/gcc/testsuite/gcc.target/i386/pr97978.c
new file mode 100644 (file)
index 0000000..263bca8
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fno-PIC" } */
+int sg;
+long int kk;
+
+void
+bp (int jz, int tj, long int li)
+{
+  if (jz == 0 || tj == 0)
+    __builtin_unreachable ();
+
+  kk = li;
+}
+
+void
+qp (void)
+{
+  ++kk;
+
+  for (;;)
+    bp (1l / sg, 0, ~0u);
+}