ARM: Invalid Stack Alignment BUG
Craig Newell
CraigN@cheque.uq.edu.au
Sat Mar 11 21:05:00 GMT 2000
Hi All,
I have been trying the latest CVS version on the ARM processor and
the compiler now generates unaligned stack pointers which are invalid
on the ARM.
After much learning about the internals of GCC I have found the BUG but
as I am yet to get my "GNU paperwork" in order ... I will not give a patch
but rather attempt to describe the BUG in as much detail as possible so
that someone who has the "GNU paperwork" in order can commit a patch.
The symptoms of the BUG are that code is generated that does not keep
the stack pointer word aligned at all times. This happens alot in my code
with "-O[123]" but it also happens with "-O0" ... so here is a test case
that generates invalid code with "-O0":
A Simple Test Program:
--- t.c -------------------------
void *a;
int
f(void)
{
unsigned char b;
if(g(a, 0x002000, &b, 1) != 1)
return -1;
return b;
}
---------------------------------
Compiled with "arm-elf-gcc -S t.c" produces:
--- t.s -------------------------
@ Generated by gcc 2.96 20000309 (experimental) for ARM/elf
.file "t.c"
.gcc2_compiled.:
.text
.align 2
.global f
.type f,function
f:
@ args = 0, pretend = 0, frame = 1
@ frame_needed = 1, current_function_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #1 <<=== ** BUG ** (should be 4)
ldr r3, .L4
sub r2, fp, #13
ldr r0, [r3, #0]
mov r1, #8192
mov r3, #1
bl g
mov r3, r0
cmp r3, #1
beq .L3
mvn r0, #0
b .L2
.L3:
ldrb r3, [fp, #-13] @ zero_extendqisi2
mov r0, r3
.L2:
ldmea fp, {fp, sp, pc}
.L5:
.align 2
.L4:
.word a
.Lfe1:
.size f,.Lfe1-f
.comm a, 4 @ 4
----------------------------------------------
So what causes this is the following commit to reload1.c:
----------------------------------------------
revision 1.198
date: 2000/02/09 13:38:09; author: hubicka; state: Exp; lines: +3 -2
* reload1.c (reload) Align stack frame to
cfun->stack_alignment_needed,
not to BIGGEST_ALIGNMENT.
----------------------------
[craign@FreeSpirit gcc]$ cvs diff -D 2/9/2000 -D 2/10/2000 reload1.c
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.197
retrieving revision 1.198
diff -u -r1.197 -r1.198
--- reload1.c 2000/01/17 15:47:28 1.197
+++ reload1.c 2000/02/09 13:38:09 1.198
@@ -841,11 +841,12 @@
HOST_WIDE_INT starting_frame_size;
- /* Round size of stack frame to BIGGEST_ALIGNMENT. This must be done
+ /* Round size of stack frame to stack_alignment_needed. This must be done
here because the stack size may be a part of the offset
computation
for register elimination, and there might have been new stack
slots
created in the last iteration of this loop. */
- assign_stack_local (BLKmode, 0, 0);
+ if (cfun->stack_alignment_needed)
+ assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
starting_frame_size = get_frame_size ();
-----------------------------------
But this appears not to be in error as much as causing a false
assumption in gcc/config/arm.c to be broken. I say this as it appears
that exactly the same problem that I am seeing here on the ARM also
occured on the SH which was then fixed with the following commit (and
another one soon after to fix a problem in the first attempt).:
-----------------------------------
Thu Feb 24 22:06:52 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
Fix bug exposed by reload.c no longer rounding the frame
size to BIGGEST_ALIGNMENT:
* sh.c (rounded_frame_size): New function.
(sh_expand_prologue, sh_expand_epilogue): Use it.
(initial_elimination_offset): Likewise.
----------------------------------
So what this shows is that gcc/config/arm/arm.c in functions
arm_output_epilogue() [line 6041] and arm_expand_prologue() [line 6335]
forgets about the following limitation to get_frame_size():
---- function.c line 495 ----
/* Return size needed for stack frame based on slots so far allocated.
This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY;
the caller may have to do that. */
HOST_WIDE_INT
get_frame_size ()
{
return get_func_frame_size (cfun);
}
-----------------------------
So finally, would it be possible for someone to make a patch and commit
it to the CVS so that the ARM target will be operational again.
Thanks,
CraigN
PS. I am in the process of getting my "GNU paperwork" in order
... hopefully not much longer ...
--
Craig Newell email: CraigN@cheque.uq.edu.au
Free Spirit icbm: somewhere in NJ, USA
Thanks,
CraigN
--
Craig Newell email: CraigN@cheque.uq.edu.au
Free Spirit icbm: somewhere in NJ, USA
More information about the Gcc-patches
mailing list