mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
[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:
parent
87f0136fa4
commit
56fc6a6d9e
@ -1362,14 +1362,7 @@ find_all_spills_for (int regno)
|
|||||||
{
|
{
|
||||||
if (live_pseudos_reg_renumber[r2->regno] >= 0
|
if (live_pseudos_reg_renumber[r2->regno] >= 0
|
||||||
&& ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
|
&& ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
|
||||||
&& rclass_intersect_p[regno_allocno_class_array[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))
|
|
||||||
sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
|
sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
gcc/testsuite/gcc.target/i386/pr116587.c
Normal file
27
gcc/testsuite/gcc.target/i386/pr116587.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user