This is an archive of the discontinued LLVM Phabricator instance.

[Builtins] Fix calling long double math functions on x86_64 mingw
AbandonedPublic

Authored by mstorsjo on Mar 16 2018, 1:49 PM.

Details

Reviewers
rnk
compnerd
Summary

On x86_64 mingw, long doubles are passed as arguments and returned as if they were a struct. For normal functions, this calling convention detail is handled within clang when generating the IR. When a math function is handled as a builtin, it gets emitted as an LLVM intrinsic call, which for x86_64 mingw in most (all?) cases gets emitted as a libcall. When the libcall is lowered in llvm, the long double specifics of the calling convention aren't taken into account (since they're normally taken care of in clang).

Skip emitting intrinsics for the functions that handle long doubles for this target.

While use of long double might be quite rare in general, it's used internally in the implementation of some mingw math functions for other precisions than long double.

Diff Detail

Event Timeline

mstorsjo created this revision.Mar 16 2018, 1:49 PM

Can we just fix the bug in the backend, rather than trying to hack around it in clang?

rnk accepted this revision.Mar 16 2018, 2:01 PM

lgtm

This revision is now accepted and ready to land.Mar 16 2018, 2:01 PM

Can we just fix the bug in the backend, rather than trying to hack around it in clang?

That'd obviously be ideal - but I don't know how easy that'd be (not familiar enough with that aspect of LLVM); if it's easily doable there, why is the handling of this detail of the calling convention done in clang for normal functions to begin with? (The calling convention requires allocating stack space in the caller for the argument and return value, which isn't done in the IR emitted by clang originally when using intrinsics.)

The backend has code to generate SRet returns, which is used when TargetLowering::CanLowerReturn returns false. Probably a tiny change to X86CallingConv.td to use that codepath on Windows.

The backend has code to generate SRet returns, which is used when TargetLowering::CanLowerReturn returns false. Probably a tiny change to X86CallingConv.td to use that codepath on Windows.

Thanks, I managed to make something that seems to work by tweaking that file, see D44592.

mstorsjo abandoned this revision.Mar 19 2018, 11:24 PM

Fixed the issue via D44592 instead, thanks @efriedma for the pointers!