[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.
This commit is contained in:
Vladimir N. Makarov 2021-01-06 14:48:53 -05:00
parent abb1b6058c
commit 15a47f437d
4 changed files with 33 additions and 4 deletions

View 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

View 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;

View File

@ -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);

View File

@ -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);
}