[PATCH] df: Fix up handling of paradoxical subregs in debug insns [PR101170]
Richard Biener
rguenther@suse.de
Thu Jun 24 10:13:18 GMT 2021
On Thu, 24 Jun 2021, Jakub Jelinek wrote:
> Hi!
>
> The recent addition of gcc_assert (regno < endregno); triggers during
> glibc build on m68k.
> The problem is that RA decisions shouldn't depend on expressions in
> DEBUG_INSNs and those expressions can contain paradoxical subregs of certain
> pseudos. If RA then decides to allocate the pseudo to a register
> with very small hard register REGNO, we can trigger the new assert,
> as (int) subreg_regno_offset may be negative on big endian and the small
> REGNO + the negative offset can wrap around.
Hm, I wonder if we should reset the debug_insn if the RA made a decision
that produces such non-sensical result for a debug_insn use?
> The following patch in that case records the range from the REGNO 0 to
> endregno, before the addition of the assert as both regno and endregno are
> unsigned it wouldn't record anything at all silently.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux and tested with a
> cross compiler to m68k-liux on the testcase, ok for trunk?
OK.
Thanks,
Richard.
> 2021-06-24 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/101170
> * df-scan.c (df_ref_record): For paradoxical big-endian SUBREGs
> where regno + subreg_regno_offset wraps around use 0 as starting
> regno.
>
> * gcc.dg/pr101170.c: New test.
>
> --- gcc/df-scan.c.jj 2021-06-22 10:04:46.371208994 +0200
> +++ gcc/df-scan.c 2021-06-23 12:46:51.654678805 +0200
> @@ -2576,9 +2576,21 @@ df_ref_record (enum df_ref_class cl,
>
> if (GET_CODE (reg) == SUBREG)
> {
> - regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
> - SUBREG_BYTE (reg), GET_MODE (reg));
> - endregno = regno + subreg_nregs (reg);
> + int off = subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
> + SUBREG_BYTE (reg), GET_MODE (reg));
> + unsigned int nregno = regno + off;
> + endregno = nregno + subreg_nregs (reg);
> + if (off < 0 && regno < (unsigned) -off)
> + /* Deal with paradoxical SUBREGs on big endian where
> + in debug insns the hard reg number might be smaller
> + than -off, such as (subreg:DI (reg:SI 0 [+4 ]) 0));
> + RA decisions shouldn't be affected by debug insns
> + and so RA can decide to put pseudo into a hard reg
> + with small REGNO, even when it is referenced in
> + a paradoxical SUBREG in a debug insn. */
> + regno = 0;
> + else
> + regno = nregno;
> }
> else
> endregno = END_REGNO (reg);
> --- gcc/testsuite/gcc.dg/pr101170.c.jj 2021-06-23 12:27:08.866593960 +0200
> +++ gcc/testsuite/gcc.dg/pr101170.c 2021-06-23 12:26:55.823769555 +0200
> @@ -0,0 +1,37 @@
> +/* PR middle-end/101170 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -g" } */
> +
> +#include <stdarg.h>
> +
> +struct S { int a; int b[4]; } s;
> +va_list ap;
> +int i;
> +long long l;
> +
> +struct S
> +foo (int x)
> +{
> + struct S a = {};
> + do
> + if (x)
> + return a;
> + while (1);
> +}
> +
> +__attribute__((noipa)) void
> +bar (void)
> +{
> + for (; i; i++)
> + l |= va_arg (ap, long long) << s.b[i];
> + if (l)
> + foo (l);
> +}
> +
> +void
> +baz (int v, ...)
> +{
> + va_start (ap, v);
> + bar ();
> + va_end (ap);
> +}
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
More information about the Gcc-patches
mailing list