aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2021-01-06 14:48:53 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2021-01-06 16:13:30 -0500
commit15a47f437d2ba320aa9cb72986812f115498dbf9 (patch)
tree07efc4b7b1aaef24877b44d0ec6d48533cec9d98 /gcc
parentabb1b6058c09a7c0430d9bf019466ada07ca7b40 (diff)
downloadgcc-15a47f437d2ba320aa9cb72986812f115498dbf9.zip
gcc-15a47f437d2ba320aa9cb72986812f115498dbf9.tar.gz
gcc-15a47f437d2ba320aa9cb72986812f115498dbf9.tar.bz2
[PR97978] LRA: Permit temporary allocation incorrectness after hard reg split.
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/lra-assigns.c9
-rw-r--r--gcc/lra-int.h1
-rw-r--r--gcc/lra.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97978.c22
4 files changed, 33 insertions, 4 deletions
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 9335e4c..c6a941f 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -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
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 75ba656..1b8f7b6 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -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;
diff --git a/gcc/lra.c b/gcc/lra.c
index 380a21a..aa49de6 100644
--- 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
index 0000000..263bca8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97978.c
@@ -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);
+}