lra: Fix up debug_p handling in lra_substitute_pseudo [PR104778]

The following testcase ICEs on powerpc-linux, because lra_substitute_pseudo
substitutes (const_int 1) into a subreg operand.  First a subreg of subreg
of a reg appears in a debug insn (which surely is invalid outside of
debug insns, but in debug insns we allow even what is normally invalid in
RTL like subregs which the target doesn't like, because either dwarf2out
is able to handle it, or we just throw away the location expression,
making some var <optimized out>.

lra_substitute_pseudo already has some code to deal with specifically
SUBREG of REG with the REG being substituted for VOIDmode constant,
but that doesn't cover this case, so the following patch extends
lra_substitute_pseudo for debug_p mode to treat stuff like e.g.
combiner's subst function to ensure we don't lose mode which is essential
for the IL.

2022-03-14  Jakub Jelinek  <jakub@redhat.com>

	PR debug/104778
	* lra.cc (lra_substitute_pseudo): For debug_p mode, simplify
	SUBREG, ZERO_EXTEND, SIGN_EXTEND, FLOAT or UNSIGNED_FLOAT if recursive
	call simplified the first operand into VOIDmode constant.

	* gcc.target/powerpc/pr104778.c: New test.
This commit is contained in:
Jakub Jelinek 2022-03-14 14:49:09 +01:00
parent 8f7b7c1495
commit 77eb0461ab
2 changed files with 84 additions and 2 deletions

View File

@ -2015,8 +2015,39 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
{
if (fmt[i] == 'e')
{
if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
new_reg, subreg_p, debug_p))
if (debug_p
&& i == 0
&& (code == SUBREG
|| code == ZERO_EXTEND
|| code == SIGN_EXTEND
|| code == FLOAT
|| code == UNSIGNED_FLOAT))
{
rtx y = XEXP (x, 0);
if (lra_substitute_pseudo (&y, old_regno,
new_reg, subreg_p, debug_p))
{
result = true;
if (CONST_SCALAR_INT_P (y))
{
if (code == SUBREG)
y = simplify_subreg (GET_MODE (x), y,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
else
y = simplify_unary_operation (code, GET_MODE (x), y,
GET_MODE (XEXP (x, 0)));
if (y)
*loc = y;
else
*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
}
else
XEXP (x, 0) = y;
}
}
else if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
new_reg, subreg_p, debug_p))
result = true;
}
else if (fmt[i] == 'E')

View File

@ -0,0 +1,51 @@
/* PR debug/104778 */
/* { dg-do compile } */
/* { dg-options "-mcmpb -Og -g" } */
/* { dg-additional-options "-fpie" { target pie } } */
unsigned long long int p;
short int m, n;
void
foo (double u, int v, int x, int y, int z)
{
long long int a = v;
short int b = v;
int c = 0, d = m, e = u;
if (n)
{
int q = b;
while (p / 1.0)
c = 0;
if (n * n == (d + 1) / (1LL << x))
a = 1;
b = u;
while (d)
{
u = m + 1ULL;
b = a - (unsigned long long int) u + a + (char) (u + 1.0);
d = (v - 1LL) * n / d + q + x;
q = m;
}
}
while (c < 1)
{
int r;
if (m == y)
m = e * z;
e = !a;
while (!r)
;
if (b)
m = d;
}
}