This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

optimization/8328: powerpc64 ICE in reload


>Number:         8328
>Category:       optimization
>Synopsis:       get_secondary_mem called during reload_as_needed
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          ice-on-legal-code
>Submitter-Id:   net
>Arrival-Date:   Wed Oct 23 18:56:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Alan Modra
>Release:        3.2.1 20021023 (prerelease)
>Organization:
IBM
>Environment:
configured with: /src/gcc-3.2/configure --prefix=/usr/local --build=i686-linux --host=i686-linux --target=powerpc64-linux --disable-nls --with-headers=/usr/local/powerpc64-linux/include --enable-languages=c
>Description:
The testcase triggers at least two bugs in handling of a register
holding a common subexpression, "(void *) &loc".  The first one being
that gcse incorrectly inserts code around a label.  We replace

=========
(note 308 131 310 NOTE_INSN_LOOP_END)

(code_label 310 308 363 3 ("exit") "" [4 uses])

(note 363 310 311 [bb 10] NOTE_INSN_BASIC_BLOCK)

(note 311 363 316 0x401e3dc0 NOTE_INSN_BLOCK_BEG)

(insn 316 311 318 (set (reg/f:DI 177)
        (plus:DI (reg/f:DI 31 r31)
            (const_int 116 [0x74]))) 220 {*adddi3_internal1} (nil)
    (nil))

(insn 318 316 321 (set (mem/s:DI (plus:DI (reg/f:DI 31 r31)
                (const_int 384 [0x180])) [9 <variable>.data+0 S8 A64])
        (reg/f:DI 177)) 316 {*movdi_internal64} (nil)
    (nil))
=========

with

=========
(note 308 404 406 NOTE_INSN_LOOP_END)

(code_label 406 308 405 12 "" "" [1 uses])

(note 405 406 383 [bb 12] NOTE_INSN_BASIC_BLOCK)

(insn 383 405 310 (set (reg/f:DI 186)
        (plus:DI (reg/f:DI 31 r31)
            (const_int 116 [0x74]))) 220 {*adddi3_internal1} (nil)
    (nil))

(code_label 310 383 363 3 ("exit") "" [4 uses])

(note 363 310 311 [bb 13] NOTE_INSN_BASIC_BLOCK)

(note 311 363 318 0x401e3dc0 NOTE_INSN_BLOCK_BEG)

(insn 318 311 321 (set (mem/s:DI (plus:DI (reg/f:DI 31 r31)
                (const_int 384 [0x180])) [9 <variable>.data+0 S8 A64])
        (reg/f:DI 186)) 316 {*movdi_internal64} (nil)
    (nil))
=========

Note how insn 383 has moved before "exit".  Also, I believe that gcse
should be using register DI 131 here as that is the one used in a
previous replacement of "(void *) &loc".

The second problem is that reg DI 186 is allocated a fp reg, and thus
needs secondary mem to transfer the result of r31+116.

#0  assign_stack_local_1 (mode=DImode, size=8, align=1075958620, 
    function=0x4001c400) at /src/gcc-ppc64-32/gcc/function.c:621
#1  0x080f08fc in assign_stack_local (mode=1075958620, size=48320598876, 
    align=1075958620) at /src/gcc-ppc64-32/gcc/function.c:641
#2  0x0818cf46 in get_secondary_mem (x=0x40017000, mode=DImode, opnum=1, 
    type=RELOAD_FOR_INPUT) at /src/gcc-ppc64-32/gcc/reload.c:620
#3  0x081a750c in gen_reload (out=0x401ead34, in=0x40017000, opnum=1, 
    type=RELOAD_FOR_INPUT) at /src/gcc-ppc64-32/gcc/reload1.c:7535
#4  0x081a7346 in gen_reload (out=0x401ead34, in=0x4021d26c, opnum=1, 
    type=RELOAD_FOR_INPUT) at /src/gcc-ppc64-32/gcc/reload1.c:7519
#5  0x081a55c1 in emit_input_reload_insns (chain=0x4021d35c, rl=0x83512a0, 
    old=0x4021d26c, j=0) at /src/gcc-ppc64-32/gcc/reload1.c:6608
#6  0x081a5cab in do_input_reload (chain=0x83953a0, rl=0x83512a0, j=0)
    at /src/gcc-ppc64-32/gcc/reload1.c:6858
#7  0x081a612f in emit_reload_insns (chain=0x0)
    at /src/gcc-ppc64-32/gcc/reload1.c:7015
#8  0x0819f992 in reload_as_needed (live_known=1)
    at /src/gcc-ppc64-32/gcc/reload1.c:3914
#9  0x0819abb9 in reload (first=0x401e3e80, global=1)
    at /src/gcc-ppc64-32/gcc/reload1.c:1109
#10 0x0822a626 in global_alloc (file=0x0) at /src/gcc-ppc64-32/gcc/global.c:590

>How-To-Repeat:
gcc64-3.2/gcc/xgcc -Bgcc64-3.2/gcc/ -O2 wjybug.i -c    
/src/tmp/wjybug.c: In function `myfunc':
/src/tmp/wjybug.c:113: Internal compiler error in reload, at reload1.c:1112

# 1 "/src/tmp/wjybug.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "/src/tmp/wjybug.c"

struct list
{
  unsigned short type;
  unsigned int len;
  void *data;
  short *ind;
};

extern int foo (int *);
extern int bar (void);
extern int qwe (struct list *);
extern long check (int *);
extern void display (int *);
extern void trace (int *);

int
myfunc (int *opts, char *str)
{
  short num;
  int loc;
  int start;
  int len;
  int code;
  int rc = 0;

  if (code && (rc = check (opts)))
    goto exit;

  foo (&code);
  {
    struct list mylist[1];
    mylist[0].type = 960;
    mylist[0].len = 4;
    mylist[0].data = (void *) &loc;
    mylist[0].ind = 0L;
    qwe (mylist);
  }
  bar ();

  if (code && (rc = check (opts)))
    goto exit;

  foo (&code);
  bar ();

  if (code && (rc = check (opts)))
    goto exit;

  if (opts)
    trace (opts);

  display (opts);

  while (code >= 0)
    {
      foo (&code);
      {
        struct list mylist[1];
        mylist[0].type = 500;
        mylist[0].len = 2;
        mylist[0].data = (void *) &num;
        mylist[0].ind = 0L;
        qwe (mylist);
      }
      bar ();
      {
        struct list mylist[3];
        mylist[0].type = 960;
        mylist[0].len = 4;
        mylist[0].data = (void *) &loc;
        mylist[0].ind = 0L;
        mylist[1].type = 496;
        mylist[1].len = 4;
        mylist[1].data = (void *) &start;
        mylist[1].ind = 0L;
        mylist[2].type = 496;
        mylist[2].len = 4;
        mylist[2].data = (void *) &len;
        mylist[2].ind = 0L;
        qwe (mylist);
      }
      {
        struct list mylist[4];
        mylist[0].type = 460;
        mylist[0].len = 129;
        mylist[0].data = (void *) str;
        mylist[0].ind = 0L;
        mylist[1].type = 460;
        mylist[1].len = 129;
        mylist[1].data = (void *) str;
        mylist[1].ind = 0L;
        mylist[2].type = 460;
        mylist[2].len = 9;
        mylist[2].data = (void *) str;
        mylist[2].ind = 0L;
        mylist[3].type = 500;
        mylist[3].len = 2;
        mylist[3].data = (void *) str;
        mylist[3].ind = 0L;
        qwe (mylist);
      }
    }

exit:
  {
    struct list mylist[1];
    mylist[0].data = (void *) &loc;
    mylist[0].ind = 0L;
    qwe (mylist);
  }
  return (rc);
}

>Fix:
I'm going to poke at the gcse problem, but would appreciate pointers.
mainline gcc doesn't exhibit this ICE.
>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]