This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
optimization/8328: powerpc64 ICE in reload
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-gnats at gcc dot gnu dot org
- Date: Thu, 24 Oct 2002 11:18:38 +0930
- Subject: 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 *) #
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: