Skip to content

Commit

Permalink
Adjust Float16 availability for Swift 5.4 toolchains.
Browse files Browse the repository at this point in the history
In older toolchains, Float16 is marked unavailable on all mac targets; starting with the 5.4 toolchain, it is available starting in macOS 11.0 when targeting Apple Silicon.
  • Loading branch information
stephentyrone committed Feb 19, 2021
1 parent 105b59b commit 97852af
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 19 deletions.
171 changes: 170 additions & 1 deletion Sources/RealModule/Float16+Real.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,177 @@
//
//===----------------------------------------------------------------------===//

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
import _NumericsShims

// When building with a Swift 5.4 or later toolchain, Float16 is available on
// non-x86 macOS from 11.0 onward.
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))

@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
extension Float16: Real {
@_transparent
public static func cos(_ x: Float16) -> Float16 {
Float16(.cos(Float(x)))
}

@_transparent
public static func sin(_ x: Float16) -> Float16 {
Float16(.sin(Float(x)))
}

@_transparent
public static func tan(_ x: Float16) -> Float16 {
Float16(.tan(Float(x)))
}

@_transparent
public static func acos(_ x: Float16) -> Float16 {
Float16(.acos(Float(x)))
}

@_transparent
public static func asin(_ x: Float16) -> Float16 {
Float16(.asin(Float(x)))
}

@_transparent
public static func atan(_ x: Float16) -> Float16 {
Float16(.atan(Float(x)))
}

@_transparent
public static func cosh(_ x: Float16) -> Float16 {
Float16(.cosh(Float(x)))
}

@_transparent
public static func sinh(_ x: Float16) -> Float16 {
Float16(.sinh(Float(x)))
}

@_transparent
public static func tanh(_ x: Float16) -> Float16 {
Float16(.tanh(Float(x)))
}

@_transparent
public static func acosh(_ x: Float16) -> Float16 {
Float16(.acosh(Float(x)))
}

@_transparent
public static func asinh(_ x: Float16) -> Float16 {
Float16(.asinh(Float(x)))
}

@_transparent
public static func atanh(_ x: Float16) -> Float16 {
Float16(.atanh(Float(x)))
}

@_transparent
public static func exp(_ x: Float16) -> Float16 {
Float16(.exp(Float(x)))
}

@_transparent
public static func expMinusOne(_ x: Float16) -> Float16 {
Float16(.expMinusOne(Float(x)))
}

@_transparent
public static func log(_ x: Float16) -> Float16 {
Float16(.log(Float(x)))
}

@_transparent
public static func log(onePlus x: Float16) -> Float16 {
Float16(.log(onePlus: Float(x)))
}

@_transparent
public static func erf(_ x: Float16) -> Float16 {
Float16(.erf(Float(x)))
}

@_transparent
public static func erfc(_ x: Float16) -> Float16 {
Float16(.erfc(Float(x)))
}

@_transparent
public static func exp2(_ x: Float16) -> Float16 {
Float16(.exp2(Float(x)))
}

@_transparent
public static func exp10(_ x: Float16) -> Float16 {
Float16(.exp10(Float(x)))
}

@_transparent
public static func hypot(_ x: Float16, _ y: Float16) -> Float16 {
if x.isInfinite || y.isInfinite { return .infinity }
let xf = Float(x)
let yf = Float(y)
return Float16(.sqrt(xf*xf + yf*yf))
}

@_transparent
public static func gamma(_ x: Float16) -> Float16 {
Float16(.gamma(Float(x)))
}

@_transparent
public static func log2(_ x: Float16) -> Float16 {
Float16(.log2(Float(x)))
}

@_transparent
public static func log10(_ x: Float16) -> Float16 {
Float16(.log10(Float(x)))
}

@_transparent
public static func pow(_ x: Float16, _ y: Float16) -> Float16 {
Float16(.pow(Float(x), Float(y)))
}

@_transparent
public static func pow(_ x: Float16, _ n: Int) -> Float16 {
// Float16 is simpler than Float or Double, because the range of
// "interesting" exponents is pretty small; anything outside of
// -22707 ... 34061 simply overflows or underflows for every
// x that isn't zero or one. This whole range is representable
// as Float, so we can just use powf as long as we're a little
// bit (get it?) careful to preserve parity.
let clamped = min(max(n, -0x10000), 0x10000) | (n & 1)
return Float16(libm_powf(Float(x), Float(clamped)))
}

@_transparent
public static func root(_ x: Float16, _ n: Int) -> Float16 {
Float16(.root(Float(x), n))
}

@_transparent
public static func atan2(y: Float16, x: Float16) -> Float16 {
Float16(.atan2(y: Float(y), x: Float(x)))
}

#if !os(Windows)
@_transparent
public static func logGamma(_ x: Float16) -> Float16 {
Float16(.logGamma(Float(x)))
}
#endif
}

// When building with older Swift toolchains for macOS, Float16 is not
// available. We will drop support for these older toolchains at some
// future point and remove this duplication.
#elseif swift(>=5.3) && !(os(macOS) || targetEnvironment(macCatalyst))

@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
extension Float16: Real {
@_transparent
Expand Down Expand Up @@ -171,4 +339,5 @@ extension Float16: Real {
}
#endif
}

#endif
4 changes: 2 additions & 2 deletions Sources/_TestSupport/RealTestSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public protocol FixedWidthFloatingPoint: BinaryFloatingPoint
where Exponent: FixedWidthInteger,
RawSignificand: FixedWidthInteger { }

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
@available(iOS 14.0, watchOS 14.0, tvOS 7.0, *)
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
@available(macOS 11.0, iOS 14.0, watchOS 14.0, tvOS 7.0, *)
extension Float16: FixedWidthFloatingPoint { }
#endif

Expand Down
4 changes: 2 additions & 2 deletions Tests/RealTests/ElementaryFunctionChecks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ internal extension Real where Self: BinaryFloatingPoint {

final class ElementaryFunctionChecks: XCTestCase {

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
func testFloat16() {
if #available(iOS 14.0, watchOS 14.0, tvOS 7.0, *) {
if #available(macOS 11.0, iOS 14.0, watchOS 14.0, tvOS 7.0, *) {
Float16.elementaryFunctionChecks()
Float16.realFunctionChecks()
}
Expand Down
10 changes: 6 additions & 4 deletions Tests/RealTests/IntegerExponentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ internal extension Real where Self: FixedWidthFloatingPoint {
}
}

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
@available(iOS 14.0, watchOS 14.0, tvOS 7.0, *)
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
@available(macOS 11.0, iOS 14.0, watchOS 14.0, tvOS 7.0, *)
extension Float16 {
static func testIntegerExponent() {
testIntegerExponentCommon()
Expand Down Expand Up @@ -174,9 +174,11 @@ extension Double {

final class IntegerExponentTests: XCTestCase {

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
func testFloat16() {
Float16.testIntegerExponent()
if #available(macOS 11.0, iOS 14.0, watchOS 14.0, tvOS 7.0, *) {
Float16.testIntegerExponent()
}
}
#endif

Expand Down
18 changes: 8 additions & 10 deletions Tests/WindowsMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,15 @@ extension RealTests.ApproximateEqualityTests {
])
}

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
extension ElementaryFunctionChecks {
static var all = testCase([
("testFloat16", ElementaryFunctionChecks.testFloat16),
("testFloat", ElementaryFunctionChecks.testFloat),
("testDouble", ElementaryFunctionChecks.testDouble),
])
}
#else
extension ElementaryFunctionChecks {
static var all = testCase([
("testFloat", ElementaryFunctionChecks.testFloat),
("testDouble", ElementaryFunctionChecks.testDouble),
])
}
#endif

#if swift(>=5.3) && !(os(macOS) || os(iOS) && targetEnvironment(macCatalyst))
extension IntegerExponentTests {
static var all = testCase([
("testFloat16", IntegerExponentTests.testFloat16),
Expand All @@ -58,6 +49,13 @@ extension IntegerExponentTests {
])
}
#else
extension ElementaryFunctionChecks {
static var all = testCase([
("testFloat", ElementaryFunctionChecks.testFloat),
("testDouble", ElementaryFunctionChecks.testDouble),
])
}

extension IntegerExponentTests {
static var all = testCase([
("testFloat", IntegerExponentTests.testFloat),
Expand Down

0 comments on commit 97852af

Please sign in to comment.