Skip to content

Commit 125e54f

Browse files
committed
[Runtime] Adjust argument types to match the LLVM15 ABI.
It appears that LLVM 15 changed the ABI for _Float16 on x86-64 such that values are now passed in `xmm0` instead of using integer registers. Also enable this code for Linux. rdar://104134160
1 parent df1891e commit 125e54f

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

stdlib/public/runtime/Float16Support.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
// Android NDK <r21 do not provide `__aeabi_d2h` in the compiler runtime,
3232
// provide shims in that case.
3333
#if (defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_EABI__)) || \
34-
((defined(__i386__) || defined(__i686__) || defined(__x86_64__)) && !defined(__APPLE__) && !defined(__linux__))
34+
((defined(__i386__) || defined(__i686__) || defined(__x86_64__)) && !defined(__APPLE__))
3535

3636
#include "swift/shims/Visibility.h"
3737

@@ -49,6 +49,20 @@ static float fromEncoding(unsigned int e) {
4949
return f;
5050
}
5151

52+
static unsigned short toEncoding(_Float16 f) {
53+
unsigned short s;
54+
static_assert(sizeof s == sizeof f, "_Float16 and short must have the same size");
55+
__builtin_memcpy(&s, &f, sizeof f);
56+
return s;
57+
}
58+
59+
static _Float16 fromEncoding(unsigned short s) {
60+
_Float16 f;
61+
static_assert(sizeof s == sizeof f, "_Float16 and short must have the same size");
62+
__builtin_memcpy(&f, &s, sizeof f);
63+
return f;
64+
}
65+
5266
#if defined(__x86_64__) && defined(__F16C__)
5367

5468
// If we're compiling the runtime for a target that has the conversion
@@ -126,7 +140,7 @@ SWIFT_RUNTIME_EXPORT unsigned short __gnu_f2h_ieee(float f) {
126140
//
127141
// Note that F16C doesn't provide this operation, so we still need a software
128142
// implementation on those cores.
129-
SWIFT_RUNTIME_EXPORT unsigned short __truncdfhf2(double d) {
143+
SWIFT_RUNTIME_EXPORT _Float16 __truncdfhf2(double d) {
130144
// You can't just do (half)(float)x, because that makes the result
131145
// susceptible to double-rounding. Instead we need to make the first
132146
// rounding use round-to-odd, but that doesn't exist on x86, so we have
@@ -148,7 +162,7 @@ SWIFT_RUNTIME_EXPORT unsigned short __truncdfhf2(double d) {
148162
if (fabs < dabs) e |= 1;
149163
f = fromEncoding(e);
150164
}
151-
return __gnu_f2h_ieee(f);
165+
return fromEncoding(__gnu_f2h_ieee(f));
152166
}
153167

154168
// Convert from Float16 to long double.
@@ -160,18 +174,18 @@ SWIFT_RUNTIME_EXPORT unsigned short __truncdfhf2(double d) {
160174
//
161175
// There's no risk of rounding problems from the double conversion, because
162176
// we're extending.
163-
SWIFT_RUNTIME_EXPORT long double __extendhfxf2(short h) {
164-
return __gnu_h2f_ieee(h);
177+
SWIFT_RUNTIME_EXPORT long double __extendhfxf2(_Float16 h) {
178+
return __gnu_h2f_ieee(toEncoding(h));
165179
}
166180

167181
// This is just an alternative name for __gnu_h2f_ieee
168-
SWIFT_RUNTIME_EXPORT float __extendhfsf2(unsigned short h) {
169-
return __gnu_h2f_ieee(h);
182+
SWIFT_RUNTIME_EXPORT float __extendhfsf2(_Float16 h) {
183+
return __gnu_h2f_ieee(toEncoding(h));
170184
}
171185

172186
// Same again but for __gnu_f2h_ieee
173-
SWIFT_RUNTIME_EXPORT unsigned short __truncsfhf2(float f) {
174-
return __gnu_f2h_ieee(f);
187+
SWIFT_RUNTIME_EXPORT _Float16 __truncsfhf2(float f) {
188+
return fromEncoding(__gnu_f2h_ieee(f));
175189
}
176190

177191
#if defined(__ARM_EABI__)

0 commit comments

Comments
 (0)