[(possibly) Bug report] clang-cl fastcall (32bits) abi does not match msvc

Hello everyone,

I hit an abi incompatibility between msvc and clang regarding fastcall x86-32bits architecture, possibly a clang bug unless something was missed

Assume two functions implemented in two different source files:

void caller()
unsigned long long a = 0x3333333344444444;
int b = 0x11111111, c = 0x22222222;

  fastercall(a, b, c);


__fascall void fastercall(unsigned long long a, int b, int c)
unsigned long long v = a;
v += b;
v += c;
std::cout << v << std::endl;

Calling method caller() above should result in printing: 0x3333333377777777

And this is the case if both files are compiled with msvc compiler or clang-cl compiler.
But if y.cpp is compiled with clang-cl and x.cpp with msvc then the result is 0x33333333aaaaaaaa

fastcall definition is here: __fastcall | Microsoft Docs

it says the two first DWORDs or smaller size arguments should be passed with ecx edx, the others by stack.
i.e. b and c should go with ecx edx while a go to stack and this is not what clang-cl does:
with msvc edx and ecx have the proper values 0x1…1 and 0x2…2 while it is not the case with clang-cl.

Any comments?

This should be an ABI compatibility issue. A simple test: Compiler Explorer
It seems we failed to assign reg to the following arguments once current one failed.

Hi Phoebe and
thanks for your fast answer and issue identification.
What is the right way to address it? Do I need to file a bug and if yes, how is it done?


File a bug on github, Issues · llvm/llvm-project · GitHub

Thanks just done.

For reference: [Bug report] clang-cl fastcall (32bits) abi does not match msvc · Issue #57737 · llvm/llvm-project · GitHub