Closed
Description
When using the preserve_none
calling convention attribute, we generate incorrect code for variadic arguments:
#include <stdarg.h>
__attribute__((preserve_none))
int F1(int P5, ...) {
va_list vl;
va_start(vl, P5);
int P6 = va_arg(vl, int);
va_end(vl);
return P6;
}
$ /work/llvm/install/bin/clang --target=aarch64--none-elf -c test.c -O1 -o - -S
.text
.file "test.c"
.globl F1 // -- Begin function F1
.p2align 2
.type F1,@function
F1: // @F1
// %bb.0: // %entry
sub sp, sp, #224
mov x8, #-64 // =0xffffffffffffffc0
mov x9, sp
add x10, sp, #128
movk x8, #65408, lsl #32
add x9, x9, #128
stp x0, x1, [sp, #128]
stp x9, x8, [sp, #208]
add x9, x10, #64
add x10, sp, #224
mov x8, #-64 // =0xffffffffffffffc0
stp x2, x3, [sp, #144]
stp x4, x5, [sp, #160]
stp x6, x7, [sp, #176]
stp q0, q1, [sp]
stp q2, q3, [sp, #32]
stp q4, q5, [sp, #64]
stp q6, q7, [sp, #96]
stp x10, x9, [sp, #192]
tbz w8, #31, .LBB0_3
// %bb.1: // %vaarg.maybe_reg
add w9, w8, #8
cmn w8, #8
str w9, [sp, #216]
b.gt .LBB0_3
// %bb.2: // %vaarg.in_reg
ldr x9, [sp, #200]
add x8, x9, x8
b .LBB0_4
.LBB0_3: // %vaarg.on_stack
ldr x8, [sp, #192]
add x9, x8, #8
str x9, [sp, #192]
.LBB0_4: // %vaarg.end
ldr w0, [x8]
add sp, sp, #224
ret
.Lfunc_end0:
.size F1, .Lfunc_end0-F1
// -- End function
.ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 79ce70b8033815b6abd3a9a5cc2335de70f1aaab)"
.section ".note.GNU-stack","",@progbits
.addrsig
The two constants of -64
in the assembly correspond to the gr_offs
field in the va_list
, so this ends up loading the argument from the saved copy of x0
, which the first (non-variadic) argument was passed in, instead of x1
.
Without the preserve_none
attribute, that constant is -56
, so the argument is correctly loaded from x1
:
$ /work/llvm/install/bin/clang --target=aarch64--none-elf -c test.c -O1 -o - -S
.text
.file "test.c"
.globl F1 // -- Begin function F1
.p2align 2
.type F1,@function
F1: // @F1
// %bb.0: // %entry
sub sp, sp, #224
mov x8, #-56 // =0xffffffffffffffc8
mov x9, sp
add x10, sp, #136
movk x8, #65408, lsl #32
add x9, x9, #128
stp x1, x2, [sp, #136]
stp x9, x8, [sp, #208]
add x9, x10, #56
add x10, sp, #224
mov x8, #-56 // =0xffffffffffffffc8
stp x3, x4, [sp, #152]
stp x5, x6, [sp, #168]
stp q0, q1, [sp]
stp q2, q3, [sp, #32]
stp q4, q5, [sp, #64]
stp q6, q7, [sp, #96]
str x9, [sp, #200]
stp x7, x10, [sp, #184]
tbz w8, #31, .LBB0_3
// %bb.1: // %vaarg.maybe_reg
add w9, w8, #8
cmn w8, #8
str w9, [sp, #216]
b.gt .LBB0_3
// %bb.2: // %vaarg.in_reg
ldr x9, [sp, #200]
add x8, x9, x8
b .LBB0_4
.LBB0_3: // %vaarg.on_stack
ldr x8, [sp, #192]
add x9, x8, #8
str x9, [sp, #192]
.LBB0_4: // %vaarg.end
ldr w0, [x8]
add sp, sp, #224
ret
.Lfunc_end0:
.size F1, .Lfunc_end0-F1
// -- End function
.ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git 79ce70b8033815b6abd3a9a5cc2335de70f1aaab)"
.section ".note.GNU-stack","",@progbits
.addrsig