Skip to content

Commit

Permalink
[PR97978] LRA: Permit temporary allocation incorrectness after hard r…
Browse files Browse the repository at this point in the history
…eg 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.
  • Loading branch information
vnmakarov committed Jan 6, 2021
1 parent abb1b60 commit 15a47f4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
9 changes: 5 additions & 4 deletions gcc/lra-assigns.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions gcc/lra-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 5 additions & 0 deletions gcc/lra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 22 additions & 0 deletions gcc/testsuite/gcc.target/i386/pr97978.c
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 15a47f4

Please sign in to comment.