This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
optimization/10392: [3.3 regression] [SH] optimizer generates faulty array indexing
- From: marcus at mc dot pp dot se
- To: gcc-gnats at gcc dot gnu dot org
- Date: Sun, 13 Apr 2003 16:47:38 +0200 (MEST)
- Subject: optimization/10392: [3.3 regression] [SH] optimizer generates faulty array indexing
>Number: 10392
>Category: optimization
>Synopsis: [3.3 regression] [SH] optimizer generates faulty array indexing
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Sun Apr 13 14:56:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Marcus Comstedt
>Release: 3.3 20030407 (prerelease)
>Organization:
>Environment:
System: SunOS continuity 5.8 Generic_108528-19 sun4m sparc SUNW,SPARCstation-10
Architecture: sun4
host: sparc-sun-solaris2.8
build: sparc-sun-solaris2.8
target: sh-unknown-elf
configured with: /home/marcus/gcc-20030407/configure --target=sh-elf --with-newlib --enable-languages=c,c++
>Description:
This is a regression from previous 3.3 snapshots.
I'm not sure how to best describe this problem, since I can't figure
out what it is that the optimizer has done. But the code it outputs
is dead wrong. Basically, the address calculation of an index operation
on an array on the stack can _under some conditions_ get messed up
completely. Just look at the reproduction recipe in the next section.
It could be related to PR 8867, however the test program from that PR
_does_ generate correct code with the same snapshot, and the generated
code here is even more weird than what happened then.
>How-To-Repeat:
Example program:
---8<--- file.c ---8<---
extern char *use(char *);
void func(char *a, char *b)
{
char buf[128];
unsigned char i;
char *item[] = {
"one",
"two",
};
for(i=0; i<2; i++) {
char *x;
use(item[i]);
x = use(buf);
use(a);
use(b);
use(x);
}
}
---8<---
Compile with
sh-elf-gcc -O2 -m4 -S file.c
(note that the -m4 is needed to trig the bug), and what you get is
---8<--- file.s ---8<---
.file "file.c"
.text
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
.LC0:
.string "one"
.align 2
.LC1:
.string "two"
.text
.align 1
.align 5
.global _func
.type _func, @function
_func:
mov.l r8,@-r15
mov.l r9,@-r15
mov.l r10,@-r15
mov #0,r10
mov.l r11,@-r15
mov r5,r11
mov.l r12,@-r15
mov r4,r12
mov.l r13,@-r15
mov #1,r13
mov.l r14,@-r15
sts.l pr,@-r15
add #-68,r15
mov.l .L9,r2
add #-68,r15
mov.w .L10,r0
mov r15,r14
mov.l .L11,r9
mov r14,r1
add #124,r1
mov.l r2,@(4,r1)
mov.l .L12,r1
mov.l r1,@(r0,r14)
.L6:
mov.w .L13,r1
mov r14,r0
add r1,r1
jsr @r9
mov.l @(r0,r1),r4
jsr @r9
mov r14,r4
mov r12,r4
jsr @r9
mov r0,r8
jsr @r9
mov r11,r4
jsr @r9
mov r8,r4
mov r10,r1
add #1,r1
extu.b r1,r10
cmp/hi r13,r10
bf .L6
add #68,r14
add #68,r14
mov r14,r15
lds.l @r15+,pr
mov.l @r15+,r14
mov.l @r15+,r13
mov.l @r15+,r12
mov.l @r15+,r11
mov.l @r15+,r10
mov.l @r15+,r9
rts
mov.l @r15+,r8
.align 1
.L10:
.short 132
.L13:
.short 128
.L14:
.align 2
.L9:
.long .LC0
.L11:
.long _use
.L12:
.long .LC1
.size _func, .-_func
.ident "GCC: (GNU) 3.3 20030407 (prerelease)"
---8<---
The faulty code is the code generated for
use(item[i]);
which corresponds to the 5 lines immediately following .L6.
r1 is loaded with 128, which is the offset of the "item" array from the
frame pointer, and r0 is loaded with the frame pointer. So far so
good. But then, rather than adding i*4 (the loop variable i is in r10)
to either r0 or r1, r1 is added to itself. As a result the mov.l will
fetch some arbitrary value from the callers stack frame (since 2*128 =
256 > 136). Note that r10 is not used at all!
>Fix:
Workaround: Compile with less optimization.
>Release-Note:
>Audit-Trail:
>Unformatted: