Created attachment 19742
minimal testcase
When compiling for Arm architecture, which implements only the 16-bit Thumb
instruction set (like Armv4t or Armv6m) a variadic function, which has
increased stack alignment requirements (so it dynamically re-aligns the SP),
the Arm back end generates invalid code to store the incoming variadic
arguments, which are passed in registers.
When the attached test case is compiled via
clang -target thumbv6m-eabi -O2 -S variadic-stack-align.c
the generated assembly looks like:
test:
.fnstart
.pad #12
sub sp, #12 ; allocate space for variadic register args
.save {r4, r6, r7, lr}
push {r4, r6, r7, lr}
.setfp r7, sp, #8
add r7, sp, #8
.pad #36
sub sp, #36 ;
mov r4, sp ;
lsrs r4, r4, #5 ; Align stack pointer
lsls r4, r4, #5 ;
mov sp, r4 ;
str r3, [sp, #60] ;
str r2, [sp, #56] ; Store incoming arguments
str r1, [sp, #52] ;
...
The offsets, used to store the register varargs are not correct after the SP is
aligned. Instead, the function should store these arguments via the FP.
variadic-stack-align.c
(180 bytes, text/x-csrc)