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

    <tr>
        <th>Summary</th>
        <td>
            clang fastcall x86 abi does not match gcc on unix
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          m-lw
      </td>
    </tr>
</table>

<pre>
    Some uses of fastcall in the x86 abi no longer match what gcc has always generated on unix.  This changed in llvm 16 and is probably the result of the fix for #57737.  Possibly this fix should have only applied to MS Windows targets?

E.g. compiling this code with the -O option on FreeBSD 13.3 with clang version 19.0.0git (snapshot from 2024-05-10):
```
typedef union { long long l ; double d ; } res_val_union;
#define FASTCALL_ATTRIBUTE  __attribute__ ((fastcall))

static res_val_union fastcall_results_vector[100] ;

res_val_union* fastcall_type_results_5(void) { return fastcall_results_vector ;}

int FASTCALL_ATTRIBUTE  fastcall_ilc_5(long long arg_1, signed char arg_2)
{
  fastcall_results_vector[0].l = (long long)arg_1;
 fastcall_results_vector[1].l = (long long)arg_2;
  return 50;
}
```
gives this code:
```
fastcall_ilc_5: # @fastcall_ilc_5
        .cfi_startproc
# %bb.0: # %entry
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset %ebp, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register %ebp
        movl    8(%ebp), %eax
        movl    12(%ebp), %edx
        movl    %edx, fastcall_results_vector+4
        movl    %eax, fastcall_results_vector
        movsbl  %cl, %eax
        movl    %eax, fastcall_results_vector+8
        sarl    $31, %eax
        movl    %eax, fastcall_results_vector+12
        movl    $50, %eax
        popl    %ebp
        .cfi_def_cfa %esp, 4
        retl    $8
```
whereas in gcc version 15.0.0 20240630 (experimental) it gives:
```
fastcall_ilc_5:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        movl    12(%ebp), %edx
        movl    %eax, fastcall_results_vector
        movl    %edx, fastcall_results_vector+4
        movsbl  16(%ebp), %eax
        movl    %eax, fastcall_results_vector+8
        cltd
        movl    %edx, fastcall_results_vector+12
        movl    $50, %eax
        popl    %ebp
        ret     $12
```
Note that the second argument is in `%cl` in clang but is on the stack in gcc.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vt1u4zYTfRr6ZmCBov6sC13E8Rr4gP3aoknRS4GSRhJbWhRIykneviClWHE2P9tdFDBkUJw5M3N4hhpujOgGxIIke5IcNnyyvdLFaSsfNpVqnoo7dUKYDBpQLbTc2JpLCWIA2yM87lLglYBBgVRDhxpO3NY9PPTcQlfX0HMDXD7wJwMdDqi5xQbUANMgHgOA-14YqHs-dNg4TCnPJwhT4EMDwsCoVcUr-eRjaTSTtC4Lt2rFI7RKA2FRkmVRFgD8powRs7Uw3sD0apIN9PyMoAb5BHwcpcAGrIL_38GfYmjUgwHLdYfWkOhI6IHQm_n5JegCqNVpFFIM3QxaqwbhQdje57D9FdRohRpcRUeNuL87QBgF0WxSSz50cEZtnEmYBzSgnbBA2M4MfDS9stBqdQJGWbylyTakhOUkWuKTlC4_v7RPIzbYOubUACTbe8aXB5BoD42aKonQ-AXJDo6x8sxl6V1ItF9wWdRgKwaE483d_e3N16_lzf397__b_3H_BaAsubVaVJPFsnSpErZ7PnWXHctfcmQst6K-DnQRSTmfmCnPWFulSbIPKSXJAdZU_PM6TXazAriaLygJYbuzEg1huS9fo530u9F8kOzwMo4Y7JslXxCErH2UlViuuzIk7BZ8kzROqtq_ZCsR2VIMfFC4Kztwp3SAl_iE5XOEZ0I-4u5DCLZCPBOT0JXnCxHXmurEGc2q7Pek94qg6MZ1HZCYvtpYuM6DuhWlsVzbUav6ojogLKmqgF4AWIKD1U8Xv3EyvSQ0dxvVeA3XYFvWLS9V2xq0sLveXd4ujuwWtqvBSZ2fQY3f-wheYyeMRf3aaAHZ-YaYg-TPWPzxtVnI3rJrvrFb3rLbd8-d7eO3nPiHTi8cTLW41PL9dD9HZPuVT8P17BRH4c9hhuxbrzihb4COavxEGLCe78qYRrug7t4U9kOPGrlxXx73sbpc1Ym7qv21TNOIun7DxxG1OOFgubsGQVjwzfPdLfOZyD9T6X8nwO_W0g8pdhZgmH5f3v9OibW0zY8k-LO602hnnwvQ9eH_oiyCdSOQmxIM1mpo3Fdjcvpxc40YwBn7rkypW86zQjX5bTUPV8by-u9Fm8GMvGmKqMmjnG-wCDOWsSxidLfpi6ymuzyJ0jRmbRznaUzjNMwjTqucVQlNNqLwcs5ZEsY0jXdB06YsyqMawzjKMhqSmOKJCxm4GSxQutsIYyYsQprnu2wjeYXS-CmRMZ8tYcwNjLpwDttq6gyJqRTGmhXCCiuxmIu7zI7PQ2Oj0MCg7DIzug5cJsPNpGXRWzv6_mJHwo6dsP1UBbU6EXZ0-MvfdtTqL6wtYUefryHsuKR8Ltg_AQAA___LI0Ss">