<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/95093>95093</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [AArch64] Wrong code for variadic argument with preserve_none calling convention
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:AArch64,
            miscompilation
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ostannard
      </td>
    </tr>
</table>

<pre>
    When using the `preserve_none` calling convention attribute, we generate incorrect code for variadic arguments:
```c
#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
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsmFuP4ygWxz8NeUG2ML4_5KGq09mX1W5Lu6t-jLDBDlsOpIAkVf3pR-BL-ZJUdal6enpGY0V2gg-H_zkHwy8mWvNaMLYG8T2INytyMnup1lIbIgRRdFVI-rz-umcCnjQXNTR7BkGCjoppps5sJ6RgIEGwJE1j75dSnJkwXApIjFG8OBkG8Cd4YbBmgiliGOSilEqx0sBSUgYrqeCZKE4oLyFR9enAhNEgvANoA9AdSFD7KbvfOOSibE6UQRB-0oYSVft7EH7ubrvzbjeMvtsBnAGcTSXj3H6cLRcGbgOAM_vlS2zV-r4PcA5Bet-awDPZNVwbeG5A2LfZRm2IMgBn58Z2s53zkYFzmEAQbqwtUfVgyYWZmJ7Jjgna3R67UMyclIBfkqENpJtZYsaBzxtxBAHeXqR6AHjbNOcDwFsutCFNA_C24ALgbdkQUUPPM0TVzIBwQ4gq90nkeTZVHmsq6JXQMG38Enr_DqAnoQe9__Qa28M37MnMmireMAghwLjtDTCeWdSNLBoIt4GVCfAWeh68ZzUXsDqJ0s2jbTDrc8Sk4bWAc1_m-WhHs7X8BCLUO2ittgEI7_pBQIR6r30LjovCR9bm9ePFngmjnqcS9KmA-mgL3J4BDjGOpjYHeXbXp6yz8JLorcHCDXqqJkeJbnjNu9Endwml7d0ATcQFOFu4eZiIS-IIue-NbuzvEN_w7MZtz9cca3Ns7ZyAp8DZxfcTJfHmRp_Wdzbvg9Gyz0xPG6-NI_q-jLyU6wfXaQgGO2HhIgFRdDsBkesTL_ok6KXPYJw443RhnCY3B3h0SXgcVeWa5aOT_riQHuLbjp3yx4Xy5Hawj07_40J_flt-V8Ru9o1jzpfSTPHNXS99XUMXtv_P-3u0C68sCsF7FoUzsdvRgTwXbKdYfX3SXZzQQcDsUSkPYiowGyqsRt0nT0KwTE7h18ZebweGxytiL52Lpe6GtgMvE4zRaAYOz1T2Uo2nWXBFd21Vdc9aL_GKHCnsHls-3BC0WBMmFZ8tBjfy3af19enTC76i0e7cV-VdUOfx6fpC9dZWoZjpB7ebmUUENHBRb-Rr_m3Y9uDI0ptvnG8dLzvwZ0HhdPscRuOUCeO29BYbzkxpu0sHuY98VHMDAc5qbkBkf-xPhV_KAwjvOvawF--o5P9ZaXxrneYlS1GRoTDMgrhISEFDkpO4LHEYxpSlqAoIIYUjtvmOr1mLCABjX0jD_H_8639eO1-wXazcGbc4cFSyLrjRMxeEUqV5_QpS_XfPoLlIi7YWi42GsrIM7CWRJV8uHBQTrdmhaJ6hY1t9lIJCI3tertVOVpW29hVnDe17gQR1aGkHtZPBduEaMkE1PB1hIwntubtnY1gpeXAtmpwZhaU8PneanlDn57Ln5d7ZVFxpVxQhhddztqXbwd2FaHi0-q2slk61YYT2PgOQIH-cka_c7OXJ3PwzMCF_sydmyB3k2qUuTsbxjkLjGnZ_DppnFzyjbbi9kOX_gr9J909DunHy1mBXCGqJqK3X95FumPxs0nXrcYt7k00lfAVkfgDpxsnHSfdDdRqCcaDYsuskAfFtXmwZt0XYKelmS9L9Pmp1lu8j19-bWr-LpuaZScdlHqcmW6r6Ixj3g3A7S86vyrjd8SNQ9535_hAJz2X_okDsRv9JUPwO2v2Lw-6KrkOahzlZsXWQBhnK8zBIV_t1nBakihBmRVlFRVkFSRiXaYEpLVFJ0mjF1xjhCCVBgPIoC1M_zQKWVVFKE0YTGmMQIXYgvPFtKnyp6hXX-sTWeYzycNWQgjXavXvGuCDlg5044d3dnYOyIaoD16U8HHlDXIWwnYMrtXbZLU61BhGyBK1fBjHcNO6ddu8q3sCvSrr307feOMMLN3s4Ydkrb7VXJ9Ws98Yc3QtqN4VGlR_Ac1x5y6E2aA3wto37vMa_BQAA___nuPJR">