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

    <tr>
        <th>Summary</th>
        <td>
            [ARM] __fp16 return values can get lost by hard float ABI
        </td>
    </tr>

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

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

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

<pre>
    Here is a simple C program:

```c
__fp16 inner(void);
float other(float);

__fp16 out_call_test(float arg) {
    __fp16 res = inner();
    other(arg);
    return res;
}
```

When compiled with `clang --target=arm-arm-none-eabi -mfpu=fp-armv8 -march=armv8.2-a+fp16 -mfloat-abi=hard -O1 -g0 -S test.c -o -`, it produces the following assembly:

```asm
out_call_test:
 .fnstart
        .save   {r11, lr}
        push    {r11, lr}
 .setfp  r11, sp
        mov     r11, sp
        .vsave  {d8}
 vpush   {d8}
        vmov.f32        s16, s0
        bl      inner
 vmov.f32        s0, s16
        bl      other
        vpop {d8}
        pop     {r11, pc}
```

My understanding is that all the functions in this example return their values in `s0` according to the hard float ABI. So, we want this function to finish with `s0` containing whatever was in `s0` after the `bl inner` instruction.

But, the `vmov.f32 s0, s16` immediately clobbers that value, and so would the `bl other` return value.

---

We don't get the same issue with `-mfloat-abi=softfp`, where I think the return values all have to be in `r0` instead of `s0`, and they are not clobbered, so something weird is going on:

```asm
out_call_test:
        .fnstart
        .save   {r4, r5, r11, lr}
        push    {r4, r5, r11, lr}
        .setfp  r11, sp, #8
        add     r11, sp, #8
        mov     r4, r0
        bl      inner
        mov     r5, r0
        mov     r0, r4
        bl      other
        vmov.f16        s0, r5
        vmov    r0, s0
        pop     {r4, r5, r11, pc}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVk2Po7gW_TXO5gpkTCBhkUVVRaXXi9aTXi_esmTwBTxtbGQbMvn3IxvyQU1XazRRVZB97z3HPvcjcOdkpxFPpHglxXnHJ98be1Koub3uaiOup_-gRZAOODg5jArhDUZrOssHkr8Qeib09l3S5a9Z1h8f7ZiVILVGS9hxNlIQVpH8dTG3ynAPxvfRGlfP5g2GmfxHw5X68Oj8zRu47QirgBzWEACANcCiA5Kf7-TPyMHtRrtAbEwW_WR1QHic5XD-dMXnM_6_Rw2NGUapUMBF-h6CCIrrDpLEc9uhJ_mZ2yEJ_9poTJDXEpKhHSeSn9sxGOYjJAO3Tb_4zseUJZyw13ifZIhXTngtSX7uuRWQ_DeDpKOQ_ICgStpAYiAJZ2NvIH1IkpgadOB7hNYoZS5Sd8Cdw6FW16-Sx92w7Gw1v3lD2mrnufUPwcIndXxGgJALm2XhBMreVbs5jZPr4Uun1KFvR4DV5MZt8GDm-PzCnM7LCcjhVRwfoPPK-Wl7_cyDmdM2Z7e1y8qITbdutVqeSzGtwJ9Do-wB4JehS71tyUczfnGuYNkKNTa_r8HvV5i0QOs81yKkWYa8hx5RaimASTdeGu1AavC9dIB_8tjOa737HqWFmasJow8pqQsswJvG2IjpTYSK1bd04MvrtxR-mHDCC8KFa79g39hCSCu1dP29LxbQxmjPpQ6ol557nNHChX8ibj3ayEhKWqtV_pKC1M7bKRKkzyK8Tj6cZI24Z-iRmhA7DCgk96iu0ChT12hXpeLVgyfXApyBi5mUeKJfUljSm2DRf8OfJMlmLiAIowk7eOjQRyTHhzBL3YR3Pbad7Uzr23Ft4ksfRu-3IKn-GeOfqV3MbR-q3huocdXO0ptEyAWY9q7n7Wq-xytwi6CNv0mAIkpkwJkBA10HF5RWhDLqTFga_S8HBqHVdmSEjdCrhFahvveB2Rbx-29DgdAqNPA_dF0mCKHVY0awNyAsP95duBC_tQ9mDvaF6d5hVa0IrZ7a_-FZfPJct6Padr8FeBoChFZLfYaBUS0VaouN7Q7jHuijGb_U4lcjYidOuajyiu_wlJWHYs-Koix2_UkUgmaHHAXlHMXx2LDy0BRMsH2NOc0PO3lilOWU0TzLiooVaVVWnGX5PmsFFlVVkj3FgUuVKjUPqbHdLtb1qaRFRneK16hcfKtgrObNT9SC5C8v__tOGCPsjTA2SLf8aPLQyGG7OO_sKcAl9dQ5sqdKOu8eBF56Fd9UAkxxfvzWPzdFw3VsN2Wch_r6aVrtJqtOvfejCwXK3gl776TvpzptzEDYe-BaH8lozR_YeMLe480cYe_xcn8FAAD__y4jpsY">