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

    <tr>
        <th>Summary</th>
        <td>
            Miscompilation of _BitInt passed as variadic argument
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation
      </td>
    </tr>

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

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

<pre>
    This code is miscompiled at all optimisation levels except for -O0, and for all (or many) targets (I've tried Arm v7M, AArch64 and x86_64):

```c
#include <stdarg.h>
#include <assert.h>

void F8 (int P0, ...) {
  va_list vl;
  va_start(vl, P0);
  signed _BitInt(13) P1;
  P1 = va_arg(vl, signed _BitInt(13));
  assert((int)P1 == -42);
}

int main (void) {
 F8(0, -42);
  return 0;
}
```

Generated code for v7M:
```
$ /work/llvm/build/bin/clang --target=arm-none-eabi -march=armv7-m -c test.c -o - -S -O1
...
F8:
        .fnstart
 .pad    #12
        sub     sp, #12
        .save   {r7, lr}
 push    {r7, lr}
        .setfp  r7, sp
        mov     r7, sp
 .pad    #4
        sub     sp, #4
        add.w   r0, r7, #8
 stm     r0!, {r1, r2, r3}
        add.w   r0, r7, #8
        adds r0, #4
        str     r0, [sp]
        ldrh    r0, [r7, #8]
 movw    r1, #8150
        cmp     r0, r1
        beq     .LBB0_2
 movw    r0, :lower16:.L.str
        movw    r1, :lower16:.L.str.1
        movt    r0, :upper16:.L.str
        movt r1, :upper16:.L.str.1
        movs    r2, #10
        bl __aeabi_assert
.LBB0_2:
        add     sp, #4
        pop.w   {r7, lr}
        add     sp, #12
        bx      lr
...
main:
 .fnstart
        .save   {r7, lr}
        push    {r7, lr}
 .setfp  r7, sp
        mov     r7, sp
        mvn     r1, #41
 bl      F8
        movs    r0, #0
        pop     {r7, pc}
...
```

The draft ABI spec for _BitInt (https://github.com/ARM-software/abi-aa/pull/191/files) says that the non-significant bits are unspecified, but the generated code for F8 compares the 16-bit chunk (loaded with the LDRH instruction) containing the argument and 3 unspecified bits to a constant which has those bits set to zero, which fails because main sign-extended the value into those bits, setting them to 1.

For a non-variadic version of the function, we emit a `BFC` instruction to clear the unspecified bits before comparing them, which is correct:

```c
#include <stdarg.h>
#include <assert.h>

__attribute((noinline))
void F8 (int P0, signed _BitInt(13) P1) {
  assert((int)P1 == -42);
}

int main (void) {
  F8(0, -42);
  return 0;
}
```

```
$ /work/llvm/build/bin/clang --target=arm-none-eabi -march=armv7-m -c test.c -o - -S -O1
...
F8:
        .fnstart
        bfc     r1, #13, #19
        movw    r0, #8150
        cmp     r1, r0
        it eq
        bxeq    lr
.LBB0_1:
        movw    r0, :lower16:.L.str
        movw    r1, :lower16:.L.str.1
        movt r0, :upper16:.L.str
        movt    r1, :upper16:.L.str.1
        movs r2, #7
        b       __aeabi_assert
...
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV12Tm7gS_TXySxcUCI8_Hvxgz1zuTVVSSeXm3SVEY7QREpEEnuyv35KwPRh7Jtmt3VTt1BRgdHR0ulvqbpi14qAQN-RhRx6eZqxztTYbbR1TiplyVujy--ZLLSxwXSIIC42wXDetkFgCc8CkBN060QjLnNAKJPYoLeAzx9ZBpQ1EHxNCH4GpMvz0MwhdaQMNU98JXYNj5oDO-rfvCF32CM4ILGFrGuiXH_zk7dbwejEPJM-rxX4xJ3RNsi1Jnkhyvi6S4Z-fftNMKC67EoFkj9aVzBzimmT_uTfMrEXjxsPh2mtRQr7y0oRy8ClYEsexl02WuwEE0LO9FNZBL0k2fmkdM47QVS_9PD97PQIE35ew3wn3TnlYmnneT-kI8ykFkj15LmYOF6b7M6_ZB4sIXQ3aCV0PXJ4umtMxmCyfxkZ7SxsmlLfaO-Da2NwTBj9MWAAMus4oSO4Qn2MzXue_qNAwh-Wwufzm8OHOpvE8x2sOhOZHbb4SmkvZN4TmRSdk6e9CEZpzydQBomjYUCR7YqaJlFYYISsERA0zvB5e98uogYiDQ-tiDpGGCKL_Q_QxHVbzMQ4P-eoiCE5_caWGwA5v45aV_jWhWUqvkbYrhnvr_XUHEFvWo5-73Jmlx0hz8Rm0na3htcELAbqqBRgAtr0ebXQf7pPRkeL5DwRPxllZxkdPGDbAQEtotjqhrGuG9RJC0zC23JnwYGi4ZjcG_IDxBWVPkDuinbms-gjkYWdb8jBZRpamvsKMVrpgG90fAyg9j6UPyTUPb9rRWia9Hi3w2xCV97tdsqdT2mHtbCv1EU26INk2fh9bZ26CNlZxC4_Tmwnuir9r27f53Qv5FHuH3AZyet7CE48UEvZ75g_Y_pRyhgN0csH08LCyfHOHtboN--GtTX_DMT1WxfMp6mZymn1ae5E0Ocg_cybPKt86mn_pTJ5HewVXW3B-jkchB0S-eiVA59OR3DgUrqS2_CL14pe7-flLjVAaVjnY7t6BbZGHHH2qOr461M611vuT5oTmB-Hqroi59pl5-_lDZHXljswgoTkrRMQYoXnbSUlonq5TQvNKSLS-vFj23YKrmQNXIyitIl_iRCU4Uw4K4Swwg9Apr0JUAktvSdEN-MNtIclX4NsUZtAGSLqICuGA15366pVLzUos4ShcHcbfP33-Hwhlnem472O8KK6VY0IJdQgQZg5dg8qFJiQbaxkEOg3Mz_HNk4NjLXgNNfPLa4sDxKLzsN_RaK9_wFRMSAsFctZZHAqvNz7CZ4fKi_SL90x2CEI5PeILGwidOylsPHcaj0OY-4Yr-LNnRrBScOjRWN-o6SoQV506GfwIRwRshAMGZJHs8keySMY-8fRcIjNh4o39BVba4MntZ0kvZoYe0hjk7hf0bfs9c86IonM4dEBKCyWFwlOb9Hpz93pTdt3y_VPt1d_YX_1bGqhz0q74derznh8e1q9UyOTHdXroPiajwgF-m5aMoXZfSkaoX-mN9l9SzP9MJR-T_1Qxv1Ty5cQDp_vdan5TKGblJivX2ZrNcJMuVul6tVisF7N6k_ISM7qkc75eccbW62XJlpSvCz5HXCGbiQ1NaJbMaZImWZot4uUDZvNVwbLioUoq5GSeYMOEjP0ejbU5zIS1HW4WlC7SmWQFShu-WCm9fI2yIYdR_xVrNn5iVHQHS-aJ_zCzL1ROOImbD1fzfC48V7XWm10Cs3DJmOfEP-uM3LxR8k5HKizeGv2bT3U0D9otoXmQ_0cAAAD__4nHM-A">