Open ZacWalk opened 5 months ago
The _Complex double
type itself seems to work OK accross the DLL boundary, the problem is with msvcrt.dll
bulitin functions like cexp
having different signature than GCC expects, as https://github.com/Windows-on-ARM-Experiments/mingw-woarm64-build/issues/102 tests demonstrates.
I looked into the ABI and _Complex double
should be treated the same as composite types which passed via d0/d1 and returned in d0/d1.
That is passing _Complex double
should have the same ABI as passing struct { double real; double imag;}
. I tested clang to see that is what is implemented there even. So this would mean there is some ABI mistake with respect of _Complex double
not being treated the same as the struct.
So I looked into using arm64 MSVC and the definition of the struct is basically:
struct dc { double val[2]; };
Someone to check the implementation of the ABI in the GCC for arm64 windows but I can say the standard elf ABI that GCC implements both _Complex double
and the above structs are passed exactly the same. So there is some ABI issues and I suspect there might be others.
Both should be considered HFAs in terms of the both ABIs.
In MSVC complex numbers are represented in a non-standard way using a struct. In MSVC cexp is defined:
_Dcomplex cexp( _Dcomplex z );
Gcc uses the standard approach with a complex type builtin. In GCC cexp is defined as:
double complex cexp( double complex z );
These two approaches are incompatible but normally only a problem when you call a complex method. However lately we noticed some optimisations might replace cos/sin with cexp causing a crash.
My recommendation would be to disable optimisations that add cexp like this.