Bug 29558 - [4.2/4.3 Regression] ICE in set_variable_part, at var-tracking.c:2140
Summary: [4.2/4.3 Regression] ICE in set_variable_part, at var-tracking.c:2140
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.2.0
: P3 blocker
Target Milestone: 4.2.0
Assignee: Richard Henderson
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2006-10-23 09:06 UTC by Richard Biener
Modified: 2007-02-19 23:45 UTC (History)
6 users (show)

See Also:
Host:
Target: powerpc64-linux-gnu
Build:
Known to work: 4.0.4 3.4.6 4.1.2
Known to fail: 4.2.0
Last reconfirmed: 2007-02-15 17:50:41


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2006-10-23 09:06:46 UTC
We ICE there with the following testcase compiled with -g -O:

void stpi_unpack_16_1(int length,    const unsigned char *in,    unsigned char *out0,    unsigned char *out1,    unsigned char *out2,    unsigned char *out3,    unsigned char *out4,    unsigned char *out5,    unsigned char *out6,    unsigned char *out7,    unsigned char *out8,    unsigned char *out9,    unsigned char *out10,    unsigned char *out11,    unsigned char *out12,    unsigned char *out13,    unsigned char *out14,    unsigned char *out15)
{
  unsigned char tempin, bit;
  unsigned char temp[16];
  for (bit = 128; length > 0; length--) {
    if (tempin & 128)
      temp[0] |= bit;
    else  
      {
        *out1++ = temp[1];
        *out2++ = temp[2];
        *out3++ = temp[3];
        *out4++ = temp[4];
        *out5++ = temp[5];
        *out6++ = temp[6];
        *out7++ = temp[7];
        *out9++ = temp[9];
        *out10++ = temp[10];
        *out11++ = temp[11];
        *out12++ = temp[12];
        *out13++ = temp[13];
        *out14++ = temp[14];
        *out15++ = temp[15];
        __builtin_memset (temp, 0, 16);
     }
  }
}
Comment 1 Richard Biener 2006-10-23 10:14:39 UTC
Slightly more reduced:

void stpi_unpack_16_1(int length, unsigned char *out, unsigned char bit)
{
  unsigned char tempin;
  unsigned char temp[16];
  for (bit = 128; length > 0; length--) {
    if (tempin & 128)
      temp[0] |= bit;
    else
      {
        *out++ = temp[1];
        *out++ = temp[2];
        *out++ = temp[3];
        *out++ = temp[4];
        *out++ = temp[5];
        *out++ = temp[6];
        *out++ = temp[7];
        *out++ = temp[9];
        *out++ = temp[10];
        *out++ = temp[11];
        *out++ = temp[12];
        *out++ = temp[13];
        *out++ = temp[14];
        *out++ = temp[15];
        __builtin_memset (temp, 0, 16);
     }
  }
}

it ICEs on

          /* We track only variables whose size is <= MAX_VAR_PARTS bytes
             thus there are at most MAX_VAR_PARTS different offsets.  */
          gcc_assert (var->n_var_parts < MAX_VAR_PARTS);

because var->n_var_parts is == MAX_VAR_PARTS.  It looks like the analysis
part is wrong in trying to track temp[].
Comment 2 Richard Biener 2006-10-23 11:29:19 UTC
Fails on the 4.2.0 branch.  On the 4.1 branch it might be due to packports of

2006-05-23  Alexandre Oliva  <aoliva@redhat.com>

        * simplify-rtx.c (simplify_subreg): Adjust REG_OFFSET for
        big-endian paradoxical subregs.
        * var-tracking.c (struct micro_operation_def): Document that,
        for modify micro operations, insn is the subsequent instruction.
        (var_reg_delete_and_set, var_mem_delete_and_set): Split into...
        (var_reg_set, var_mem_set): ... new functions.
        (add_stores): Record subsequent insn.
        (compute_bb_dataflow): Use new functions for MO_USE.
        (emit_notes_in_bb): Use new functions for MO_USE.  Emit use
        notes after the insn, and modify notes before the insn known
        to be the subsequent one.
        (vt_initialize): Invert sorting of MO_CLOBBERs and MO_SETs.

from  Alexandre Oliva  <aoliva@redhat.com>

        * var-tracking.c (enum micro_operation_type): Add MO_COPY.
        (var_debug_decl): New function.
        (var_reg_set): Follow debug decl link.  Add location even if
        reg is already known to hold some other variable.
        (var_mem_set): Follow debug decl link.
        (var_reg_delete_and_set, var_mem_delete_and_set): Follow debug
        decl link.  Delete other known locations of the variable part
        if requested.
        (var_reg_delete, var_mem_delete): Delete other known locations
        of the variable part if requested.
        (same_variable_part_p): New function.
        (add_stores): Select MO_COPY when appropriate.
        (vt_initialize): Handle it.
        (compute_bb_dataflow, emit_notes_in_bb): Likewise.  Delete
        known locations for MO_SET and MO_CLOBBER.
        (find_variable_location_part): New function.
        (set_variable_part, delete_variable_part): Use it.
        (clobber_variable_part): New function.
        * dwarf2out.c (dwarf2out_var_location): Do not follow debug
        decl link.

2006-09-11  Alexandre Oliva  <aoliva@redhat.com>

        PR target/28672
        * var-tracking.c (dump_dataflow_set): Start dumping at
        register zero.
        (clobber_variable_part): Kill only the variable part in
        registers holding it, leaving other variables alone.
Comment 3 Andrew Pinski 2006-10-23 16:06:32 UTC
It works for me with 4.1.2 20061017 but fails with 4.2.0 20061015 so this only fails on the 4.2 branch.
Comment 4 Janis Johnson 2006-11-07 19:18:25 UTC
A regression hunt on powerpc64-linux using the testcase in comment #1 with "-O -g -m64" identified the following patch:

    http://gcc.gnu.org/viewcvs?view=rev&rev=114013

    r114013 | aoliva | 2006-05-23 05:35:21 +0000 (Tue, 23 May 2006)
Comment 5 Peter Bergner 2007-01-19 22:30:38 UTC
The src we seem to be having problems with is:

    temp[0] |= bit;

After local-alloc, we have the following RTL:

(insn 143 28 29 6 pr29558.c:7 (set (reg:QI 142)
        (const_int -128 [0xffffffffffffff80])) 327 {*movqi_internal} (nil)
    (expr_list:REG_EQUIV (const_int -128 [0xffffffffffffff80])
        (nil)))

(insn 29 143 30 6 pr29558.c:7 (set (reg:SI 144)
        (ior:SI (subreg:SI (reg:QI 143 [ temp ]) 0)
            (subreg:SI (reg:QI 142) 0))) 137 {*boolsi3_internal1} (insn_list:REG_DEP_TRUE 27 (insn_list:REG_DEP_TRUE 28 (nil)))
    (expr_list:REG_DEAD (reg:QI 143 [ temp ])
        (expr_list:REG_DEAD (reg:QI 142)
            (nil))))

(insn 30 29 138 6 pr29558.c:7 (set (mem/s/j:QI (plus:DI (reg/f:DI 113 sfp)
                (const_int 48 [0x30])) [0 temp+0 S1 A128])
        (subreg:QI (reg:SI 144) 3)) 327 {*movqi_internal} (insn_list:REG_DEP_TRUE 29 (nil))
    (expr_list:REG_DEAD (reg:SI 144)
        (nil)))

Which looks ok, but then after global-alloc/reload, we end up with:

(insn 143 28 29 6 pr29558.c:7 (set (reg:QI 9 9 [142])
        (const_int -128 [0xffffffffffffff80])) 327 {*movqi_internal} (nil)
    (expr_list:REG_EQUIV (const_int -128 [0xffffffffffffff80])
        (nil)))

(insn 29 143 30 6 pr29558.c:7 (set (reg:SI 0 0 [144])
        (ior:SI (reg:SI 0 0 [orig:143 temp+-3 ] [143])
            (reg:SI 9 9 [orig:142+-3 ] [142]))) 137 {*boolsi3_internal1} (insn_list:REG_DEP_TRUE 27 (insn_list:REG_DEP_TRUE 28 
(nil)))
    (nil))

(insn 30 29 138 6 pr29558.c:7 (set (mem/s/j:QI (plus:DI (reg/f:DI 1 1)
                (const_int -16 [0xfffffffffffffff0])) [0 temp+0 S1 A128])
        (reg:QI 0 0 [orig:144+3 ] [144])) 327 {*movqi_internal} (insn_list:REG_DEP_TRUE 29 (nil))
    (nil))

I'm not sure why yet, but it seems the -3 offset in reg:SI 0 0 [orig:143 temp+-3 ] [143]) is causing problems in the var tracking code, such that find_variable_location_part() always returns -1 (ie, failure) which puts us into the code we ICE in.
Comment 6 Peter Bergner 2007-01-19 22:32:24 UTC
I should mention, I'm using current mainline on powerpc64-linux using -g -O -m64.
Comment 7 Richard Henderson 2007-02-19 16:11:01 UTC
Subject: Bug 29558

Author: rth
Date: Mon Feb 19 16:10:49 2007
New Revision: 122130

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=122130
Log:
        PR debug/29558
        * var-tracking.c (track_expr_p): Disallow AGGREGATE_TYPE_P
        in memory.

Added:
    branches/gcc-4_2-branch/gcc/testsuite/gcc.dg/debug/pr29558.c
Modified:
    branches/gcc-4_2-branch/gcc/ChangeLog
    branches/gcc-4_2-branch/gcc/var-tracking.c

Comment 8 Richard Henderson 2007-02-19 16:22:14 UTC
Subject: Bug 29558

Author: rth
Date: Mon Feb 19 16:21:59 2007
New Revision: 122131

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=122131
Log:
        PR debug/29558
        * var-tracking.c (track_expr_p): Disallow AGGREGATE_TYPE_P
        in memory.

Added:
    trunk/gcc/testsuite/gcc.dg/debug/pr29558.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/var-tracking.c

Comment 9 Mark Mitchell 2007-02-19 20:34:42 UTC
RTH --

You checked in a patch for this on the 4.2 branch; should this issue be closed now?

Thanks,

-- Mark
Comment 10 Richard Henderson 2007-02-19 23:45:01 UTC
Fixed.