This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Incorrect ARM code generation ...
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Incorrect ARM code generation ...
- From: Craig Newell <craign at ieee dot org>
- Date: Thu, 9 Nov 2000 10:43:40 -0500 (EST)
Hi All,
I have been attempting to get the latest GCC CVS tree to work again on
my ARM based project and have been finding that incorrect code is being
generated. A simple "rebuild gcc a million and one times" extensive
search has revealed that the following CVS checkin broke things:
-----------------------------------------------------------------------
CVSROOT: /cvs/gcc
Module name: egcs
Changes by: kenner@sourceware.cygnus.com 2000-10-20 13:57:21
Modified files:
gcc : ChangeLog expr.c tree.c
Log message:
* expr.c (expand_expr, case SAVE_EXPR): Set RTX_UNCHANGING_P on
returned MEM.
(expand_expr_unaligned, case ARRAY_REF): Check that index is
a constant before comparing it; use tree_low_cst.
* tree.c (save_expr): Set TREE_READONLY.
(substitute_expr): Return inside of NON_LVALUE_EXPR.
(build, build1): Set TREE_READONLY if all operands are.
(build_index_type): If upper bound is a negative number, lower
bound is zero and sizetype is unsigned, use upper bound of one and
lower of zero.
-----------------------------------------------------------------------
It is quite hard to find a suitable test case that is not 2000+ lines
long but here is one that I hope is small enough:
---- bug.i ------------------------------------------------------------
typedef struct {
void *o;
void *m;
} hjlo;
typedef struct {
hjlo *(b[0]);
} aoo;
void
f(hjlo *p)
{
aoo *a = (aoo *)(p->o);
void *c = (void *)(a->b[(((unsigned long int)p->m) >> 5)]);
}
-----------------------------------------------------------------------
When compiled with "arm-elf-gcc -O0 -S bug.i" from the head of the CVS
including the Oct. 20 checkin:
--- bad.s -------------------------------------------------------------
@ Generated by gcc 2.97 20001108 (experimental) for ARM/elf
.file "bug.i"
.gcc2_compiled.:
.text
.align 2
.global f
.type f,function
f:
@ args = 0, pretend = 0, frame = 12
@ frame_needed = 1, current_function_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #12
str r0, [fp, #-16]
ldr r3, [fp, #-16]
ldr r3, [r3, #0]
str r3, [fp, #-20]
ldr r3, [fp, #-16]
ldr r3, [r3, #4]
mov r3, r3, lsr #5
sub r3, r3, #1
mov r2, r3, asl #2
ldr r3, [fp, #-20]
ldr r3, [r3, r2]
str r3, [fp, #-24]
ldmea fp, {fp, sp, pc}
.Lfe1:
.size f,.Lfe1-f
-----------------------------------------------------------------------
The incorrect code generated is the 'extra' "sub r3, r3,
#1" instruction. As far as I can see, there is no single unit offsets
anywhere in the test case to generate this "-1".
When compiled with "arm-elf-gcc -O0 -S bug.i" from the head of the CVS
*excluding* the Oct. 20 checkin the 'extra' subs instruction is not
generated:
--- good.s -------------------------------------------------------------
@ Generated by gcc 2.97 20001108 (experimental) for ARM/elf
.file "bug.i"
.gcc2_compiled.:
.text
.align 2
.global f
.type f,function
f:
@ args = 0, pretend = 0, frame = 12
@ frame_needed = 1, current_function_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #12
str r0, [fp, #-16]
ldr r3, [fp, #-16]
ldr r3, [r3, #0]
str r3, [fp, #-20]
ldr r3, [fp, #-16]
ldr r3, [r3, #4]
mov r3, r3, lsr #5
mov r2, r3, asl #2
ldr r3, [fp, #-20]
ldr r3, [r3, r2]
str r3, [fp, #-24]
ldmea fp, {fp, sp, pc}
.Lfe1:
.size f,.Lfe1-f
-----------------------------------------------------------------------
Thanks,
CraigN
PS. I hope this gets to the list ... third time lucky ...
--
Craig Newell email: CraigN@ieee.org
Free Spirit icbm: N 42°38'47" W 71°18'19"