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/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:


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