<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">