[PR116587][LRA]: Fix last chance reload pseudo allocation

On i686 PR116587 test compilation resulted in LRA failure to find
registers for a reload insn pseudo.  The insn requires 6 regs for 4
reload insn pseudos where two of them require 2 regs each.  But we
have only 5 free regs as sp is a fixed reg, bp is fixed because of
-fno-omit-frame-pointer, bx is assigned to pic_offset_table_pseudo
because of -fPIC.  LRA spills pic_offset_table_pseudo as the last
chance approach to allocate registers to the reload pseudo.  Although
it makes 2 free registers for the unallocated reload pseudo requiring
also 2 regs, the pseudo still can not be allocated as the 2 free regs
are disjoint.  The patch spills all pseudos conflicting with the
unallocated reload pseudo including already allocated reload insn
pseudos, then standard LRA code allocates spilled pseudos requiring
more one register first and avoid situation of the disjoint regs for
reload pseudos requiring more one reg.

gcc/ChangeLog:

	PR target/116587
	* lra-assigns.cc (find_all_spills_for): Consider all pseudos whose
	classes intersect given pseudo class.

gcc/testsuite/ChangeLog:

	PR target/116587
	* gcc.target/i386/pr116587.c: New test.
This commit is contained in:
Vladimir N. Makarov 2024-11-20 14:25:41 -05:00
parent 87f0136fa4
commit 56fc6a6d9e
2 changed files with 28 additions and 8 deletions

View File

@ -1362,14 +1362,7 @@ find_all_spills_for (int regno)
{
if (live_pseudos_reg_renumber[r2->regno] >= 0
&& ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
&& rclass_intersect_p[regno_allocno_class_array[r2->regno]]
&& ((int) r2->regno < lra_constraint_new_regno_start
|| bitmap_bit_p (&lra_inheritance_pseudos, r2->regno)
|| bitmap_bit_p (&lra_split_regs, r2->regno)
|| bitmap_bit_p (&lra_optional_reload_pseudos, r2->regno)
/* There is no sense to consider another reload
pseudo if it has the same class. */
|| regno_allocno_class_array[r2->regno] != rclass))
&& rclass_intersect_p[regno_allocno_class_array[r2->regno]])
sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
}
}

View File

@ -0,0 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fPIC -mstackrealign -mavx512f -fharden-control-flow-redundancy -fno-omit-frame-pointer -mbmi -fkeep-gc-roots-live" } */
typedef __UINT64_TYPE__ a;
int b;
struct c {
a d;
};
extern char e[];
int f;
void g();
char *h(struct c *i, a d) {
while (b) {
if ((i->d & d) == i->d) {
if (f)
g();
g();
d &= ~i->d;
}
++i;
}
if (d)
g();
if (f)
return "";
return e;
}