Message ID | 20111027025956.GQ29439@bubble.grove.modra.org |
---|---|
State | New |
Headers | show |
From: Alan Modra <amodra@gmail.com> Date: Thu, 27 Oct 2011 13:29:56 +1030 > Some recent patch has exposed a reload bug. I'm seeing I think this might be a side effect or Eric's recent changes, CC:'d.
From: David Miller <davem@davemloft.net> Date: Wed, 26 Oct 2011 23:07:11 -0400 (EDT) > From: Alan Modra <amodra@gmail.com> > Date: Thu, 27 Oct 2011 13:29:56 +1030 > >> Some recent patch has exposed a reload bug. I'm seeing > > I think this might be a side effect or Eric's recent changes, > CC:'d. Eric, I'm seeing a similar segmentation fault in reload on sparc64. But it's in a slightly different place than Alan's crash. Simply compile gcc.target/ultrasp12.c with "-m64 -O2 -mcpu=ultrasparc -mvis" to see this. The crash is in find_valid_class() called from push_reload(), via this code block around line 1184 of reload.c: enum reg_class in_out_class = find_valid_class (outmode, GET_MODE (SUBREG_REG (out)), subreg_regno_offset (REGNO (SUBREG_REG (out)), GET_MODE (SUBREG_REG (out)), SUBREG_BYTE (out), GET_MODE (out)), REGNO (SUBREG_REG (out))); 'out' is: (subreg:DI (reg/v:V4QI 50 %f18 [orig:314 s2hi4_ ] [314]) 0) so subreg_regno_offset() returns -1, and find_valid_class() isn't too happy about getting "-1" for it's 'n' argument. I suspect the test that you removed in order to fix rtl-optimization/46603 would guard against this happening. And indeed, I confirmed that backing out the rtl-optimization/46603 fix makes the segmentation fault go away.
Ping http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02429.html Eric fixed the bootstrap breakage by another patch, but there is a fairly obvious bug in gen_reload fixed by my patch. I gave enough contect in the diff that you don't even need to look at the file. :)
> OK to apply, assuming no regressions? > > * reload1.c (gen_reload): Don't use REGNO on SUBREGs. > * print-rtl.c (print_rtx): Don't segfault on negative regno. OK, thanks.
Index: gcc/reload1.c =================================================================== --- gcc/reload1.c (revision 180542) +++ gcc/reload1.c (working copy) @@ -8588,28 +8588,28 @@ gen_reload (rtx out, rtx in, int opnum, && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER && (REG_P (out) || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out)))) && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)), REGNO_REG_CLASS (reg_or_subregno (out)), GET_MODE (out))) { /* Get the memory to use and rewrite both registers to its mode. */ rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type); if (GET_MODE (loc) != GET_MODE (out)) - out = gen_rtx_REG (GET_MODE (loc), REGNO (out)); + out = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (out)); if (GET_MODE (loc) != GET_MODE (in)) - in = gen_rtx_REG (GET_MODE (loc), REGNO (in)); + in = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (in)); gen_reload (loc, in, opnum, type); gen_reload (out, loc, opnum, type); } #endif else if (REG_P (out) && UNARY_P (in)) { rtx insn; rtx op1; rtx out_moded; rtx set; Index: gcc/print-rtl.c =================================================================== --- gcc/print-rtl.c (revision 180542) +++ gcc/print-rtl.c (working copy) @@ -465,13 +465,12 @@ print_rtx (const_rtx in_rtx) int value = XINT (in_rtx, i); const char *name; #ifndef GENERATOR_FILE - if (REG_P (in_rtx) && value < FIRST_PSEUDO_REGISTER) - fprintf (outfile, " %d %s", REGNO (in_rtx), - reg_names[REGNO (in_rtx)]); + if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER) + fprintf (outfile, " %d %s", value, reg_names[value]); else if (REG_P (in_rtx) - && value <= LAST_VIRTUAL_REGISTER) + && (unsigned) value <= LAST_VIRTUAL_REGISTER) { if (value == VIRTUAL_INCOMING_ARGS_REGNUM) fprintf (outfile, " %d virtual-incoming-args", value); else if (value == VIRTUAL_STACK_VARS_REGNUM)