Skip to content

Commit abea46e

Browse files
Make Float16 available for macOS on Apple Silicon (#34821)
Due to an unstable (and undesirable) calling convention in the LLVM layer for x86, I had previously marked Float16 unconditionally unavailable on macOS. My hope was that Intel would stabilize the calling convention and we could make it available on both macOS platforms at the same time. Unfortunately, that hasn't happened, and we want to make the type available for macOS/arm users. So, I am making the availability mirror Float80--the type will be unavailable for macOS on x86_64, and available on all other platforms (the other x86 platforms don't have a binary-stability guarantee to worry about). This isn't ideal. In particular, if/when the calling conventions for Float16 stabilize in LLVM, we would want to make the type available, but it would then have _different_ availability for different architectures of macOS, which the current availability system is not well-equipped to handle (it's possible, but not very ergonomic). Nonetheless, this seems like the best option. The good news is that because the full API is already built in Swift (and simply marked unavailable), we can simply add macOS 11.0 availability for these API and it will work.
1 parent 0360fe6 commit abea46e

File tree

9 files changed

+46
-47
lines changed

9 files changed

+46
-47
lines changed

stdlib/public/core/CTypes.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ public typealias CLong = Int
5656
/// The C 'long long' type.
5757
public typealias CLongLong = Int64
5858

59+
#if !(os(macOS) && arch(x86_64))
5960
/// The C '_Float16' type.
60-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
61-
@available(macOS, unavailable)
62-
@available(macCatalyst, unavailable)
61+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
6362
public typealias CFloat16 = Float16
63+
#endif
6464

6565
/// The C 'float' type.
6666
public typealias CFloat = Float

stdlib/public/core/Codable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4730,9 +4730,8 @@ extension RawRepresentable where RawValue == Float, Self: Decodable {
47304730
}
47314731
}
47324732

4733-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
4734-
@available(macOS, unavailable)
4735-
@available(macCatalyst, unavailable)
4733+
#if !(os(macOS) && arch(x86_64))
4734+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
47364735
extension Float16: Codable {
47374736
/// Creates a new instance by decoding from the given decoder.
47384737
///
@@ -4763,6 +4762,7 @@ extension Float16: Codable {
47634762
try Float(self).encode(to: encoder)
47644763
}
47654764
}
4765+
#endif
47664766

47674767
extension Int: Codable {
47684768
/// Creates a new instance by decoding from the given decoder.

stdlib/public/core/FloatingPointParsing.swift.gyb

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,12 @@ internal func _isspace_clocale(_ u: UTF16.CodeUnit) -> Bool {
4242

4343
% if bits == 80:
4444
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
45+
% elif bits == 16:
46+
#if !(os(macOS) && arch(x86_64))
4547
% end
4648

47-
//===--- Parsing ----------------------------------------------------------===//
4849
%if bits == 16:
49-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
50-
@available(macOS, unavailable)
51-
@available(macCatalyst, unavailable)
50+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
5251
%end
5352
extension ${Self}: LosslessStringConvertible {
5453
/// Creates a new instance from the given string.
@@ -136,7 +135,7 @@ extension ${Self}: LosslessStringConvertible {
136135
%if bits == 16:
137136
self.init(Substring(text))
138137
%else:
139-
if #available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
138+
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
140139
self.init(Substring(text))
141140
} else {
142141
self = 0.0
@@ -166,13 +165,7 @@ extension ${Self}: LosslessStringConvertible {
166165
// In particular, we still have to export
167166
// _swift_stdlib_strtoXYZ_clocale()
168167
// as ABI to support old compiled code that still requires it.
169-
%if bits == 16:
170-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
171-
@available(macOS, unavailable)
172-
@available(macCatalyst, unavailable)
173-
%else:
174-
@available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
175-
%end
168+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
176169
public init?(_ text: Substring) {
177170
self = 0.0
178171
let success = withUnsafeMutablePointer(to: &self) { p -> Bool in
@@ -196,7 +189,7 @@ extension ${Self}: LosslessStringConvertible {
196189
}
197190
}
198191

199-
% if bits == 80:
192+
% if bits in [16,80]:
200193
#endif
201194
% end
202195

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ RawSignificand = 'UInt' + str(SignificandSize)
4040

4141
def Availability(bits):
4242
if bits == 16:
43-
return '@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)\n@available(macOS, unavailable)\n@available(macCatalyst, unavailable)'
43+
return '@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)'
4444
return ''
4545

4646
if Self == 'Float16':
@@ -65,6 +65,8 @@ else:
6565

6666
% if bits == 80:
6767
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
68+
% elif bits == 16:
69+
#if !(os(macOS) && arch(x86_64))
6870
% end
6971

7072
${SelfDocComment}
@@ -1106,8 +1108,10 @@ extension ${Self} {
11061108
% srcBits = src_type.bits
11071109
% That = src_type.stdlib_name
11081110

1109-
% if (srcBits == 80) and (bits != 80):
1111+
% if srcBits == 80:
11101112
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
1113+
% elif srcBits == 16:
1114+
#if !(os(macOS) && arch(x86_64))
11111115
% end
11121116

11131117
% if srcBits == bits:
@@ -1192,7 +1196,7 @@ extension ${Self} {
11921196
}
11931197
}
11941198

1195-
% if (srcBits == 80) and (bits != 80):
1199+
% if srcBits in [16,80]:
11961200
#endif
11971201
% end
11981202
% end
@@ -1343,12 +1347,12 @@ internal struct _${Self}AnyHashableBox: _AnyHashableBox {
13431347
// Deprecated operators
13441348
//===----------------------------------------------------------------------===//
13451349

1346-
% if bits == 80:
1350+
% if bits in [16,80]:
13471351
#else
13481352

13491353
${SelfDocComment}
13501354
@frozen
1351-
@available(*, unavailable, message: "Float80 is not available on target platform.")
1355+
@available(*, unavailable, message: "${Self} is not available on target platform.")
13521356
public struct ${Self} {
13531357
/// Creates a value initialized to zero.
13541358
@_transparent

stdlib/public/core/IntegerTypes.swift.gyb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,8 @@ public struct ${Self}
11291129

11301130
% if FloatType == 'Float80':
11311131
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
1132+
% elif FloatType == 'Float16':
1133+
#if !(os(macOS) && arch(x86_64))
11321134
% end
11331135

11341136
/// Creates an integer from the given floating-point value, rounding toward
@@ -1152,9 +1154,7 @@ public struct ${Self}
11521154
/// `source` must be representable in this type after rounding toward
11531155
/// zero.
11541156
% if FloatType == 'Float16':
1155-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
1156-
@available(macOS, unavailable)
1157-
@available(macCatalyst, unavailable)
1157+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
11581158
% end
11591159
@_transparent
11601160
public init(_ source: ${FloatType}) {
@@ -1184,9 +1184,7 @@ public struct ${Self}
11841184
///
11851185
/// - Parameter source: A floating-point value to convert to an integer.
11861186
% if FloatType == 'Float16':
1187-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
1188-
@available(macOS, unavailable)
1189-
@available(macCatalyst, unavailable)
1187+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
11901188
% end
11911189
@_transparent
11921190
public init?(exactly source: ${FloatType}) {
@@ -1206,7 +1204,7 @@ public struct ${Self}
12061204
self._value = Builtin.fpto${u}i_FPIEEE${FloatBits}_${BuiltinName}(source._value)
12071205
}
12081206

1209-
% if FloatType == 'Float80':
1207+
% if FloatType in ['Float16', 'Float80']:
12101208
#endif
12111209
% end
12121210

stdlib/public/core/Runtime.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ internal struct _Buffer72 {
293293
}
294294
}
295295

296+
#if !(os(macOS) && arch(x86_64))
296297
// Note that this takes a Float32 argument instead of Float16, because clang
297298
// doesn't have _Float16 on all platforms yet.
298299
@_silgen_name("swift_float16ToString")
@@ -303,9 +304,7 @@ internal func _float16ToStringImpl(
303304
_ debug: Bool
304305
) -> Int
305306

306-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
307-
@available(macOS, unavailable)
308-
@available(macCatalyst, unavailable)
307+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
309308
internal func _float16ToString(
310309
_ value: Float16,
311310
debug: Bool
@@ -317,6 +316,7 @@ internal func _float16ToString(
317316
}
318317
return (buffer, length)
319318
}
319+
#endif
320320

321321
// Returns a UInt64, but that value is the length of the string, so it's
322322
// guaranteed to fit into an Int. This is part of the ABI, so we can't

stdlib/public/core/SIMDVectorTypes.swift.gyb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,10 @@ extension ${Self}: SIMDScalar {
253253
%end
254254

255255
%for (Self, bits) in [('Float16',16), ('Float',32), ('Double',64)]:
256-
%if bits == 16:
257-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
258-
@available(macOS, unavailable)
259-
@available(macCatalyst, unavailable)
260-
%end
256+
% if bits == 16:
257+
#if !(os(macOS) && arch(x86_64))
258+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
259+
% end
261260
extension ${Self} : SIMDScalar {
262261

263262
public typealias SIMDMaskScalar = Int${bits}
@@ -299,5 +298,8 @@ extension ${Self} : SIMDScalar {
299298

300299
% end
301300
}
301+
% if bits == 16:
302+
#endif
303+
% end
302304

303305
%end

test/ClangImporter/simd.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ let ll3_value: ll3 = makes_ll3()
2222
let ll8_value: ll8 = makes_ll8()
2323
let ull4_value: ull4 = makes_ull4()
2424
let ull16_value: ull16 = makes_ull16()
25+
#if !(os(macOS) && arch(x86_64))
2526
let half2_value: half2 = makes_half2()
2627
let half3_value: half3 = makes_half3()
2728
let half4_value: half4 = makes_half4()
2829
let half8_value: half8 = makes_half8()
2930
let half16_value: half16 = makes_half16()
3031
let half32_value: half32 = makes_half32()
32+
#endif
3133
let float2_value: float2 = makes_float2()
3234
let float3_value: float3 = makes_float3()
3335
let float4_value: float4 = makes_float4()
@@ -58,12 +60,14 @@ takes_ll3(ll3_value)
5860
takes_ll8(ll8_value)
5961
takes_ull4(ull4_value)
6062
takes_ull16(ull16_value)
63+
#if !(os(macOS) && arch(x86_64))
6164
takes_half2(half2_value)
6265
takes_half3(half3_value)
6366
takes_half4(half4_value)
6467
takes_half8(half8_value)
6568
takes_half16(half16_value)
6669
takes_half32(half32_value)
70+
#endif
6771
takes_float2(float2_value)
6872
takes_float3(float3_value)
6973
takes_float4(float4_value)

test/stdlib/PrintFloat.swift.gyb

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -345,11 +345,9 @@ let PrintTests = TestSuite("FloatingPointPrinting")
345345

346346
% for FloatType in ['Float16', 'Float', 'Double', 'Float80']:
347347
% if FloatType == 'Float16':
348-
@available(iOS 14.0, watchOS 7.0, tvOS 14.0, *)
349-
@available(macOS, unavailable)
350-
@available(macCatalyst, unavailable)
351-
% end
352-
% if FloatType == 'Float80':
348+
#if !(os(macOS) && arch(x86_64))
349+
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
350+
% elif FloatType == 'Float80':
353351
#if !os(Windows) && (arch(i386) || arch(x86_64))
354352
% end
355353

@@ -425,7 +423,7 @@ fileprivate func expectAccurateDescription(_ object: ${FloatType},
425423
// that the result is not closer. Note this requires higher-precision
426424
// arithmetic.
427425
}
428-
% if FloatType == 'Float80':
426+
% if FloatType in ['Float16','Float80']:
429427
#endif
430428
% end
431429
% end
@@ -587,8 +585,8 @@ PrintTests.test("Printable_CDouble") {
587585
expectDescription("-1.0", CDouble(-1.0))
588586
}
589587

590-
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
591-
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
588+
#if !(os(macOS) && arch(x86_64))
589+
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
592590
PrintTests.test("Printable_Float16") {
593591
func asFloat16(_ f: Float16) -> Float16 { return f }
594592

0 commit comments

Comments
 (0)