ira: Fix unnecessary register spill

The variables first_moveable_pseudo and last_moveable_pseudo aren't
reset after compiling a function, which means they leak into the first
scheduler pass of the following function. In some cases, this can cause
an extra spill during register allocation of the second function.

gcc/ChangeLog:

	* ira.c (move_unallocated_pseudos): Zero first_moveable_pseudo and
	last_moveable_pseudo before returning.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/nospill.c: New test.
This commit is contained in:
Omar Tahir 2020-07-09 10:14:19 +01:00 committed by Richard Sandiford
parent 319078dad6
commit edf95e51e5
2 changed files with 37 additions and 0 deletions

View File

@ -5126,6 +5126,8 @@ move_unallocated_pseudos (void)
INSN_UID (newinsn), i);
SET_REG_N_REFS (i, 0);
}
first_moveable_pseudo = last_moveable_pseudo = 0;
}
/* If the backend knows where to allocate pseudos for hard

View File

@ -0,0 +1,35 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
/* The pseudo for P is marked as moveable in the IRA pass. */
float
func_0 (float a, float b, float c)
{
float p = c / a;
if (b > 1)
{
b /= p;
if (c > 2)
a /= 3;
}
return b / c * a;
}
/* If first_moveable_pseudo and last_moveable_pseudo are not reset correctly,
they will carry over and spill the pseudo for Q. */
float
func_1 (float a, float b, float c)
{
float q = a + b;
c *= a / (b + b);
if (a > 0)
c *= q;
return a * b * c;
}
/* We have plenty of spare registers, so check nothing has been spilled. */
/* { dg-final { scan-assembler-not "\tstr\t" } } */