From 5e5cd76e8d8d379e580c30cb25eac668c754d482 Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Mon, 11 Feb 2019 22:09:44 -0800 Subject: [PATCH 01/11] Work in progress towards "Mathsable" Fundamental decision to be made; should implementation hooks present like `Float.exp(_ x: Float) -> Float` or like `Float.Maths.exp(_ x: Float) -> Float`? Having the intermediate namespace to group them as in the second is definitely nicer, but it requires a little bit of extra machinery, and much more importantly, there doesn't seem to be any way to make access to the static `Maths` associatedtype transparent. --- stdlib/public/CMakeLists.txt | 2 + stdlib/public/Maths/CMakeLists.txt | 8 ++ stdlib/public/Maths/Maths.swift.gyb | 64 +++++++++++++ stdlib/public/Platform/tgmath.swift.gyb | 4 +- stdlib/public/core/CMakeLists.txt | 1 + stdlib/public/core/GroupInfo.json | 3 +- stdlib/public/core/Mathsable.swift.gyb | 117 ++++++++++++++++++++++++ utils/SwiftMathsFunctions.py | 37 ++++++++ 8 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 stdlib/public/Maths/CMakeLists.txt create mode 100644 stdlib/public/Maths/Maths.swift.gyb create mode 100644 stdlib/public/core/Mathsable.swift.gyb create mode 100644 utils/SwiftMathsFunctions.py diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt index 8b661b508cfc7..4acb934fd47c9 100644 --- a/stdlib/public/CMakeLists.txt +++ b/stdlib/public/CMakeLists.txt @@ -61,6 +61,8 @@ if(SWIFT_BUILD_STDLIB) add_subdirectory(stubs) add_subdirectory(core) add_subdirectory(SwiftOnoneSupport) + + add_subdirectory(Maths) endif() if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR) diff --git a/stdlib/public/Maths/CMakeLists.txt b/stdlib/public/Maths/CMakeLists.txt new file mode 100644 index 0000000000000..10d901b8f2177 --- /dev/null +++ b/stdlib/public/Maths/CMakeLists.txt @@ -0,0 +1,8 @@ +add_swift_target_library(swiftMaths ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY + Maths.swift.gyb + + SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" + SWIFT_COMPILE_FLAGS + LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" +) + diff --git a/stdlib/public/Maths/Maths.swift.gyb b/stdlib/public/Maths/Maths.swift.gyb new file mode 100644 index 0000000000000..aca4c0ace6336 --- /dev/null +++ b/stdlib/public/Maths/Maths.swift.gyb @@ -0,0 +1,64 @@ +//===--- Maths.swift ------------------------------------------*- swift -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2019 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// MARK: - Free functions defined on FloatingPoint +@_transparent +public func ceil(_ x: T) -> T where T: FloatingPoint { + return x.rounded(.up) +} + +@_transparent +public func floor(_ x: T) -> T where T: FloatingPoint { + return x.rounded(.down) +} + +@_transparent +public func round(_ x: T) -> T { + return x.rounded() +} + +@_transparent +public func trunc(_ x: T) -> T where T: FloatingPoint { + return x.rounded(.towardZero) +} + +@_transparent +public func sqrt(_ x: T) -> T where T: FloatingPoint { + return x.squareRoot() +} + +@_transparent +public func fma(_ x: T, _ y: T, _ z: T) -> T where T: FloatingPoint { + return z.addingProduct(x, y) +} + +@_transparent +public func remainder(_ x: T, _ y: T) -> T where T: FloatingPoint { + return x.remainder(dividingBy: y) +} + +@_transparent +public func fmod(_ x: T, _ y: T) -> T where T: FloatingPoint { + return x.truncatingRemainder(dividingBy: y) +} + +// MARK: - Free functions defined on Mathsable + +%from SwiftMathsFunctions import * +%for func in MathFunctions: + +@_transparent +public func ${func.free_decl()} { +// return T.Maths.${func.name}(${func.params()}) + return T.${func.name}(${func.params()}) +} +%end diff --git a/stdlib/public/Platform/tgmath.swift.gyb b/stdlib/public/Platform/tgmath.swift.gyb index 4f3f279de4f13..44efd60a9c957 100644 --- a/stdlib/public/Platform/tgmath.swift.gyb +++ b/stdlib/public/Platform/tgmath.swift.gyb @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import SwiftShims +@_exported import Maths // Generic functions implementable directly on FloatingPoint. @_transparent @@ -163,9 +164,6 @@ UnaryFunctions = [ # We call this intrinsic via the Builtin method so keep this list in # sync with core/BuiltinMath.swift.gyb UnaryIntrinsicFunctions = [ - 'cos', 'sin', - 'exp', 'exp2', - 'log', 'log10', 'log2', 'nearbyint', 'rint', ] diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index f7874df471288..6b06ea7842834 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -87,6 +87,7 @@ set(SWIFTLIB_ESSENTIAL LifetimeManager.swift ManagedBuffer.swift Map.swift + Mathsable.swift.gyb MemoryLayout.swift UnicodeScalar.swift # ORDER DEPENDENCY: Must precede Mirrors.swift Misc.swift diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index 06ba858a9f666..07d406c18160d 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -167,7 +167,8 @@ "Floating": [ "FloatingPoint.swift", "FloatingPointParsing.swift", - "FloatingPointTypes.swift"], + "FloatingPointTypes.swift", + "Mathsable.swift"], "Vector": [ "SIMDVector.swift", "SIMDVectorTypes.swift"]} diff --git a/stdlib/public/core/Mathsable.swift.gyb b/stdlib/public/core/Mathsable.swift.gyb new file mode 100644 index 0000000000000..5132a98bd1e0d --- /dev/null +++ b/stdlib/public/core/Mathsable.swift.gyb @@ -0,0 +1,117 @@ +//===--- Mathsable.swift --------------------------------------*- swift -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2019 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// We are omitting the following for now, which could also be defined on +// FloatingPoint, as it's not obvious that we want free function +// implementations: +// +// fabs - use Swift.abs instead. +// +// scalbn, frexp, ldexp, ilogb - we should provide a better technique +// for safely rescaling floating-point computations instead of these +// poorly named and easy to misuse functions. + +%{ +from SwiftMathsFunctions import * +}% + +/* NAMESPACED +public protocol Mathsable { + associatedtype Maths: MathsImplementations where Maths.Value == Self +} + +public protocol MathsImplementations { + associatedtype Value +%for func in MathFunctions: + static func ${func.decl("Value")} +%end +} + +%for type in all_floating_point_types(): +extension ${type.stdlib_name}: Mathsable { + public enum Maths: MathsImplementations { + public typealias Value = ${type.stdlib_name} +% for func in MathFunctions: + + @_transparent + public static func ${func.decl("Value")} { + return ${func.impl(type)} + } +%end + } +} + +%end + +public struct _SIMDMaths: MathsImplementations +where V: SIMD, V.Scalar: Mathsable { + + public typealias Value = V +%for func in MathFunctions: + + @_transparent + public static func ${func.decl("V")} { + var r = V() + for i in x.indices { + r[i] = V.Scalar.Maths.${func.name}(${func.params("", "[i]")}) + } + return r + } +%end +} + +extension SIMD where Scalar: Mathsable { + public typealias Maths = _SIMDMaths +} + +%for n in [2,3,4,8,16,32,64]: +extension SIMD${n}: Mathsable where Scalar: Mathsable { } +%end +*/ + +/* NO NAMESPACE */ +public protocol Mathsable { +%for func in MathFunctions: + static func ${func.decl("Self")} +%end +} + +%for type in all_floating_point_types(): +extension ${type.stdlib_name}: Mathsable { +% for func in MathFunctions: + + @_transparent + public static func ${func.decl(type.stdlib_name)} { + return ${func.impl(type)} + } +%end +} + +%end + +extension SIMD where Scalar: Mathsable { +%for func in MathFunctions: + + @_transparent + public static func ${func.decl("Self")} { + var r = Self() + for i in x.indices { + r[i] = Scalar.${func.name}(${func.params("", "[i]")}) + } + return r + } +%end +} + +%for n in [2,3,4,8,16,32,64]: +extension SIMD${n}: Mathsable where Scalar: Mathsable { } +%end diff --git a/utils/SwiftMathsFunctions.py b/utils/SwiftMathsFunctions.py new file mode 100644 index 0000000000000..8fe129b7fdcee --- /dev/null +++ b/utils/SwiftMathsFunctions.py @@ -0,0 +1,37 @@ +from SwiftFloatingPointTypes import all_floating_point_types + +class SwiftMathsFunction(object): + def __init__(self, name, cName=None, intrinsic=False, args="x"): + self.name = name + self.cName = cName if cName is not None else name + self.intrinsic = intrinsic + self.args = args + + def params(self, prefix="", suffix=""): + return ", ".join( + map(lambda a: prefix + a + suffix, self.args) + ) + + def decl(self, type): + return self.name + "(" + self.params("_ ", ": " + type) + ") -> " + type + + def free_decl(self): + return self.name + "(" + self.params("_ ", ": T") + ") -> T where T: Mathsable" + + def impl(self, type): + if self.intrinsic: + builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) + return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" + return self.cName + type.cFuncSuffix + "(" + self.params() + ")" + +MathFunctions = [ + SwiftMathsFunction(name="cos", intrinsic=True), + SwiftMathsFunction(name="sin", intrinsic=True), + SwiftMathsFunction(name="exp", intrinsic=True), + SwiftMathsFunction(name="exp2", intrinsic=True), + SwiftMathsFunction(name="log", intrinsic=True), + SwiftMathsFunction(name="log10", intrinsic=True), + SwiftMathsFunction(name="log2", intrinsic=True), +] + + From b8d1481fc667854ca361d7012d1c4c145a67d37d Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Fri, 22 Feb 2019 12:30:22 -0500 Subject: [PATCH 02/11] WOW\! 100% less gratuitous type machinery at runtime\! --- stdlib/public/CMakeLists.txt | 1 - stdlib/public/Maths/Maths.swift.gyb | 43 ++++++++------------- stdlib/public/Platform/CMakeLists.txt | 5 ++- stdlib/public/Platform/tgmath.swift.gyb | 40 ------------------- stdlib/public/core/Mathsable.swift.gyb | 51 +++---------------------- stdlib/public/core/SIMDVector.swift | 2 +- utils/SwiftMathsFunctions.py | 4 +- 7 files changed, 28 insertions(+), 118 deletions(-) diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt index 4acb934fd47c9..f45ae05185627 100644 --- a/stdlib/public/CMakeLists.txt +++ b/stdlib/public/CMakeLists.txt @@ -61,7 +61,6 @@ if(SWIFT_BUILD_STDLIB) add_subdirectory(stubs) add_subdirectory(core) add_subdirectory(SwiftOnoneSupport) - add_subdirectory(Maths) endif() diff --git a/stdlib/public/Maths/Maths.swift.gyb b/stdlib/public/Maths/Maths.swift.gyb index aca4c0ace6336..b20c895faee58 100644 --- a/stdlib/public/Maths/Maths.swift.gyb +++ b/stdlib/public/Maths/Maths.swift.gyb @@ -11,54 +11,41 @@ //===----------------------------------------------------------------------===// // MARK: - Free functions defined on FloatingPoint -@_transparent -public func ceil(_ x: T) -> T where T: FloatingPoint { - return x.rounded(.up) +%for constraint in ["T: FloatingPoint", "T: SIMD, T.Scalar: FloatingPoint"]: +% for (func,dir) in [("ceil", ".up"), ("floor", ".down"), ("round", ""), ("trunc", ".towardZero")]: +@_alwaysEmitIntoClient +public func ${func}(_ x: T) -> T where ${constraint} { + return x.rounded(${dir}) } -@_transparent -public func floor(_ x: T) -> T where T: FloatingPoint { - return x.rounded(.down) -} - -@_transparent -public func round(_ x: T) -> T { - return x.rounded() -} - -@_transparent -public func trunc(_ x: T) -> T where T: FloatingPoint { - return x.rounded(.towardZero) -} - -@_transparent -public func sqrt(_ x: T) -> T where T: FloatingPoint { +%end +@_alwaysEmitIntoClient +public func sqrt(_ x: T) -> T where ${constraint} { return x.squareRoot() } -@_transparent -public func fma(_ x: T, _ y: T, _ z: T) -> T where T: FloatingPoint { +@_alwaysEmitIntoClient +public func fma(_ x: T, _ y: T, _ z: T) -> T where ${constraint} { return z.addingProduct(x, y) } -@_transparent +%end +@_alwaysEmitIntoClient public func remainder(_ x: T, _ y: T) -> T where T: FloatingPoint { return x.remainder(dividingBy: y) } -@_transparent +@_alwaysEmitIntoClient public func fmod(_ x: T, _ y: T) -> T where T: FloatingPoint { return x.truncatingRemainder(dividingBy: y) } // MARK: - Free functions defined on Mathsable - %from SwiftMathsFunctions import * %for func in MathFunctions: -@_transparent +@_alwaysEmitIntoClient public func ${func.free_decl()} { -// return T.Maths.${func.name}(${func.params()}) - return T.${func.name}(${func.params()}) + return T.Maths.${func.name}(${func.params()}) } %end diff --git a/stdlib/public/Platform/CMakeLists.txt b/stdlib/public/Platform/CMakeLists.txt index 305ae6e181da9..aa72adc77750c 100644 --- a/stdlib/public/Platform/CMakeLists.txt +++ b/stdlib/public/Platform/CMakeLists.txt @@ -18,6 +18,7 @@ add_swift_target_library(swiftDarwin ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_ SWIFT_COMPILE_FLAGS -Xfrontend -disable-objc-attr-requires-foundation-module "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" TARGET_SDKS ALL_APPLE_PLATFORMS + SWIFT_MODULE_DEPENDS Maths # This is overly conservative, but we have so few API notes files that # haven't migrated to the Swift repo that it's probably fine in practice. @@ -33,6 +34,7 @@ add_swift_target_library(swiftGlibc ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_O SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" TARGET_SDKS ANDROID CYGWIN FREEBSD LINUX HAIKU + SWIFT_MODULE_DEPENDS Maths DEPENDS glibc_modulemap) add_swift_target_library(swiftMSVCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY @@ -44,7 +46,8 @@ add_swift_target_library(swiftMSVCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_ SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" - TARGET_SDKS WINDOWS) + TARGET_SDKS WINDOWS + SWIFT_MODULE_DEPENDS Maths) set(glibc_modulemap_target_list) foreach(sdk ${SWIFT_SDKS}) diff --git a/stdlib/public/Platform/tgmath.swift.gyb b/stdlib/public/Platform/tgmath.swift.gyb index 44efd60a9c957..563c335cc95fc 100644 --- a/stdlib/public/Platform/tgmath.swift.gyb +++ b/stdlib/public/Platform/tgmath.swift.gyb @@ -20,46 +20,6 @@ public func fabs(_ x: T) -> T { return x.magnitude } -@_transparent -public func sqrt(_ x: T) -> T { - return x.squareRoot() -} - -@_transparent -public func fma(_ x: T, _ y: T, _ z: T) -> T { - return z.addingProduct(x, y) -} - -@_transparent -public func remainder(_ x: T, _ y: T) -> T { - return x.remainder(dividingBy: y) -} - -@_transparent -public func fmod(_ x: T, _ y: T) -> T { - return x.truncatingRemainder(dividingBy: y) -} - -@_transparent -public func ceil(_ x: T) -> T { - return x.rounded(.up) -} - -@_transparent -public func floor(_ x: T) -> T { - return x.rounded(.down) -} - -@_transparent -public func round(_ x: T) -> T { - return x.rounded() -} - -@_transparent -public func trunc(_ x: T) -> T { - return x.rounded(.towardZero) -} - @_transparent public func scalbn(_ x: T, _ n : Int) -> T { return T(sign: .plus, exponent: T.Exponent(n), significand: x) diff --git a/stdlib/public/core/Mathsable.swift.gyb b/stdlib/public/core/Mathsable.swift.gyb index 5132a98bd1e0d..7eb365c1bfdd8 100644 --- a/stdlib/public/core/Mathsable.swift.gyb +++ b/stdlib/public/core/Mathsable.swift.gyb @@ -24,7 +24,6 @@ from SwiftMathsFunctions import * }% -/* NAMESPACED public protocol Mathsable { associatedtype Maths: MathsImplementations where Maths.Value == Self } @@ -38,27 +37,28 @@ public protocol MathsImplementations { %for type in all_floating_point_types(): extension ${type.stdlib_name}: Mathsable { + @_frozen public enum Maths: MathsImplementations { public typealias Value = ${type.stdlib_name} % for func in MathFunctions: - - @_transparent + @_alwaysEmitIntoClient public static func ${func.decl("Value")} { return ${func.impl(type)} } -%end +% end } } - + %end +@_fixed_layout public struct _SIMDMaths: MathsImplementations where V: SIMD, V.Scalar: Mathsable { public typealias Value = V %for func in MathFunctions: - @_transparent + @inlinable public static func ${func.decl("V")} { var r = V() for i in x.indices { @@ -76,42 +76,3 @@ extension SIMD where Scalar: Mathsable { %for n in [2,3,4,8,16,32,64]: extension SIMD${n}: Mathsable where Scalar: Mathsable { } %end -*/ - -/* NO NAMESPACE */ -public protocol Mathsable { -%for func in MathFunctions: - static func ${func.decl("Self")} -%end -} - -%for type in all_floating_point_types(): -extension ${type.stdlib_name}: Mathsable { -% for func in MathFunctions: - - @_transparent - public static func ${func.decl(type.stdlib_name)} { - return ${func.impl(type)} - } -%end -} - -%end - -extension SIMD where Scalar: Mathsable { -%for func in MathFunctions: - - @_transparent - public static func ${func.decl("Self")} { - var r = Self() - for i in x.indices { - r[i] = Scalar.${func.name}(${func.params("", "[i]")}) - } - return r - } -%end -} - -%for n in [2,3,4,8,16,32,64]: -extension SIMD${n}: Mathsable where Scalar: Mathsable { } -%end diff --git a/stdlib/public/core/SIMDVector.swift b/stdlib/public/core/SIMDVector.swift index dce9b3355b674..5bb63081c06bb 100644 --- a/stdlib/public/core/SIMDVector.swift +++ b/stdlib/public/core/SIMDVector.swift @@ -652,7 +652,7 @@ extension SIMD where Scalar : FloatingPoint { } @_transparent - public func rounded(_ rule: FloatingPointRoundingRule) -> Self { + public func rounded(_ rule: FloatingPointRoundingRule = .toNearestOrEven) -> Self { var result = Self() for i in result.indices { result[i] = self[i].rounded(rule) } return result diff --git a/utils/SwiftMathsFunctions.py b/utils/SwiftMathsFunctions.py index 8fe129b7fdcee..5a2de70f977a6 100644 --- a/utils/SwiftMathsFunctions.py +++ b/utils/SwiftMathsFunctions.py @@ -15,8 +15,8 @@ def params(self, prefix="", suffix=""): def decl(self, type): return self.name + "(" + self.params("_ ", ": " + type) + ") -> " + type - def free_decl(self): - return self.name + "(" + self.params("_ ", ": T") + ") -> T where T: Mathsable" + def free_decl(self, protocol="Mathsable"): + return self.name + "(" + self.params("_ ", ": T") + ") -> T where T: " + protocol def impl(self, type): if self.intrinsic: From 2f7435da7dce1af1418c77d69a9d70f719cba98f Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Fri, 22 Feb 2019 16:55:45 -0500 Subject: [PATCH 03/11] First non-intrinsic functions. --- stdlib/public/Maths/Maths.swift.gyb | 2 +- stdlib/public/SwiftShims/LibcShims.h | 87 +++++++++++++++++-- stdlib/public/core/BuiltinMath.swift.gyb | 5 +- .../public/core/FloatingPointTypes.swift.gyb | 4 +- stdlib/public/core/Mathsable.swift.gyb | 34 +++++--- utils/SwiftMathsFunctions.py | 39 +++++---- 6 files changed, 129 insertions(+), 42 deletions(-) diff --git a/stdlib/public/Maths/Maths.swift.gyb b/stdlib/public/Maths/Maths.swift.gyb index b20c895faee58..669c449054e3c 100644 --- a/stdlib/public/Maths/Maths.swift.gyb +++ b/stdlib/public/Maths/Maths.swift.gyb @@ -42,7 +42,7 @@ public func fmod(_ x: T, _ y: T) -> T where T: FloatingPoint { // MARK: - Free functions defined on Mathsable %from SwiftMathsFunctions import * -%for func in MathFunctions: +%for func in MathsFunctions: @_alwaysEmitIntoClient public func ${func.free_decl()} { diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h index ff99bc796ccd6..3353d84aacfdb 100644 --- a/stdlib/public/SwiftShims/LibcShims.h +++ b/stdlib/public/SwiftShims/LibcShims.h @@ -127,33 +127,108 @@ static inline __swift_size_t _swift_stdlib_malloc_size(const void *ptr) { // Math library functions static inline SWIFT_ALWAYS_INLINE -float _stdlib_remainderf(float _self, float _other) { +float _swift_stdlib_tanf(float x) { + return __builtin_tanf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_acosf(float x) { + return __builtin_acosf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_asinf(float x) { + return __builtin_asinf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_atanf(float x) { + return __builtin_atanf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_atan2f(float y, float x) { + return __builtin_atan2f(y, x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_remainderf(float _self, float _other) { return __builtin_remainderf(_self, _other); } static inline SWIFT_ALWAYS_INLINE -float _stdlib_squareRootf(float _self) { +float _swift_stdlib_squareRootf(float _self) { return __builtin_sqrtf(_self); } + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_tan(double x) { + return __builtin_tan(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_acos(double x) { + return __builtin_acos(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_asin(double x) { + return __builtin_asin(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_atan(double x) { + return __builtin_atan(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_atan2(double y, double x) { + return __builtin_atan2(y, x); +} static inline SWIFT_ALWAYS_INLINE -double _stdlib_remainder(double _self, double _other) { +double _swift_stdlib_remainder(double _self, double _other) { return __builtin_remainder(_self, _other); } static inline SWIFT_ALWAYS_INLINE -double _stdlib_squareRoot(double _self) { +double _swift_stdlib_squareRoot(double _self) { return __builtin_sqrt(_self); } #if !defined _WIN32 && (defined __i386__ || defined __x86_64__) static inline SWIFT_ALWAYS_INLINE -long double _stdlib_remainderl(long double _self, long double _other) { +long double _swift_stdlib_tanl(long double x) { + return __builtin_tanl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_acosl(long double x) { + return __builtin_acosl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_asinl(long double x) { + return __builtin_asinl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_atanl(long double x) { + return __builtin_atanl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_atan2l(long double y, long double x) { + return __builtin_atan2l(y, x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_remainderl(long double _self, long double _other) { return __builtin_remainderl(_self, _other); } static inline SWIFT_ALWAYS_INLINE -long double _stdlib_squareRootl(long double _self) { +long double _swift_stdlib_squareRootl(long double _self) { return __builtin_sqrtl(_self); } #endif diff --git a/stdlib/public/core/BuiltinMath.swift.gyb b/stdlib/public/core/BuiltinMath.swift.gyb index 69db331f4cb53..9f7108f2a10ae 100644 --- a/stdlib/public/core/BuiltinMath.swift.gyb +++ b/stdlib/public/core/BuiltinMath.swift.gyb @@ -45,10 +45,7 @@ def cFuncSuffix(bits): # These functions have a corresponding LLVM intrinsic # Note, keep this up to date with Darwin/tgmath.swift.gyb UnaryIntrinsicFunctions = [ - 'cos', 'sin', - 'exp', 'exp2', - 'log', 'log10', 'log2', - 'nearbyint', 'rint', + 'nearbyint', 'rint', ] def TypedUnaryIntrinsicFunctions(): diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb index 6c7c9b4f6919a..074d88c5798e0 100644 --- a/stdlib/public/core/FloatingPointTypes.swift.gyb +++ b/stdlib/public/core/FloatingPointTypes.swift.gyb @@ -1115,7 +1115,7 @@ extension ${Self}: BinaryFloatingPoint { @inlinable // FIXME(inline-always) @inline(__always) public mutating func formRemainder(dividingBy other: ${Self}) { - self = _stdlib_remainder${cFuncSuffix}(self, other) + self = _swift_stdlib_remainder${cFuncSuffix}(self, other) } /// Replaces this value with the remainder of itself divided by the given @@ -1157,7 +1157,7 @@ extension ${Self}: BinaryFloatingPoint { /// value. @_transparent public mutating func formSquareRoot( ) { - self = _stdlib_squareRoot${cFuncSuffix}(self) + self = _swift_stdlib_squareRoot${cFuncSuffix}(self) } /// Adds the product of the two given values to this value in place, computed diff --git a/stdlib/public/core/Mathsable.swift.gyb b/stdlib/public/core/Mathsable.swift.gyb index 7eb365c1bfdd8..62b0b6bb5b76b 100644 --- a/stdlib/public/core/Mathsable.swift.gyb +++ b/stdlib/public/core/Mathsable.swift.gyb @@ -10,37 +10,39 @@ // //===----------------------------------------------------------------------===// -// We are omitting the following for now, which could also be defined on -// FloatingPoint, as it's not obvious that we want free function -// implementations: -// -// fabs - use Swift.abs instead. -// -// scalbn, frexp, ldexp, ilogb - we should provide a better technique -// for safely rescaling floating-point computations instead of these -// poorly named and easy to misuse functions. +import SwiftShims %{ from SwiftMathsFunctions import * }% +/// A type that has basic maths functions available. +/// +/// "Basic maths functions" means roughly "the usual transcendental +/// functions provided by `` in C-family langauges." public protocol Mathsable { associatedtype Maths: MathsImplementations where Maths.Value == Self } +/// A type that provides the implementation trampolines for maths functions +/// on the related `Value` type. public protocol MathsImplementations { associatedtype Value -%for func in MathFunctions: +%for func in MathsFunctions: static func ${func.decl("Value")} %end } %for type in all_floating_point_types(): +% if type.bits == 80: +#if (arch(i386) || arch(x86_64)) && !os(Windows) +% end extension ${type.stdlib_name}: Mathsable { + /// Defines basic maths functions for ${type.stdlib_name} @_frozen public enum Maths: MathsImplementations { public typealias Value = ${type.stdlib_name} -% for func in MathFunctions: +% for func in MathsFunctions: @_alwaysEmitIntoClient public static func ${func.decl("Value")} { return ${func.impl(type)} @@ -48,17 +50,21 @@ extension ${type.stdlib_name}: Mathsable { % end } } - + +% if type.bits == 80: +#endif +% end %end +/// Defines basic maths functions operating elementwise on SIMD vector types. @_fixed_layout public struct _SIMDMaths: MathsImplementations where V: SIMD, V.Scalar: Mathsable { public typealias Value = V -%for func in MathFunctions: +%for func in MathsFunctions: - @inlinable + @_alwaysEmitIntoClient public static func ${func.decl("V")} { var r = V() for i in x.indices { diff --git a/utils/SwiftMathsFunctions.py b/utils/SwiftMathsFunctions.py index 5a2de70f977a6..9aa6c42550384 100644 --- a/utils/SwiftMathsFunctions.py +++ b/utils/SwiftMathsFunctions.py @@ -1,10 +1,10 @@ from SwiftFloatingPointTypes import all_floating_point_types class SwiftMathsFunction(object): - def __init__(self, name, cName=None, intrinsic=False, args="x"): + def __init__(self, name, kind=None, swiftName=None, args="x"): self.name = name - self.cName = cName if cName is not None else name - self.intrinsic = intrinsic + self.swiftName = swiftName if swiftName is not None else name + self.kind = kind if kind is not None else "library" self.args = args def params(self, prefix="", suffix=""): @@ -13,25 +13,34 @@ def params(self, prefix="", suffix=""): ) def decl(self, type): - return self.name + "(" + self.params("_ ", ": " + type) + ") -> " + type + return self.swiftName + "(" + self.params("_ ", ": " + type) + ") -> " + type def free_decl(self, protocol="Mathsable"): - return self.name + "(" + self.params("_ ", ": T") + ") -> T where T: " + protocol + return self.swiftName + "(" + self.params("_ ", ": T") + ") -> T where T: " + protocol def impl(self, type): - if self.intrinsic: + if self.kind == "intrinsic": builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" - return self.cName + type.cFuncSuffix + "(" + self.params() + ")" + if self.kind == "builtin": + builtin = "Builtin." + self.name + "_FPIEEE" + str(type.bits) + return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" + return "_swift_stdlib_" + self.name + type.cFuncSuffix + "(" + self.params() + ")" -MathFunctions = [ - SwiftMathsFunction(name="cos", intrinsic=True), - SwiftMathsFunction(name="sin", intrinsic=True), - SwiftMathsFunction(name="exp", intrinsic=True), - SwiftMathsFunction(name="exp2", intrinsic=True), - SwiftMathsFunction(name="log", intrinsic=True), - SwiftMathsFunction(name="log10", intrinsic=True), - SwiftMathsFunction(name="log2", intrinsic=True), +MathsFunctions = [ + SwiftMathsFunction(name="cos", kind="intrinsic"), + SwiftMathsFunction(name="sin", kind="intrinsic"), + SwiftMathsFunction(name="tan"), + SwiftMathsFunction(name="acos"), + SwiftMathsFunction(name="asin"), + SwiftMathsFunction(name="atan"), + SwiftMathsFunction(name="atan2", args="yx"), + SwiftMathsFunction(name="exp", kind="intrinsic"), + SwiftMathsFunction(name="exp2", kind="intrinsic"), + SwiftMathsFunction(name="log", kind="intrinsic"), + SwiftMathsFunction(name="log10", kind="intrinsic"), + SwiftMathsFunction(name="log2", kind="intrinsic"), + SwiftMathsFunction(name="pow", kind="intrinsic", args="xy"), ] From cad116a12b94fe98bce5d768043fa800fe14aa1b Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Sat, 2 Mar 2019 20:13:00 -0500 Subject: [PATCH 04/11] Revert "build: improve the builds with Visual Studio" This reverts commit d9dde28bf183535f03813bc3a5852d8354c918fa. --- cmake/modules/ClangClCompileRules.cmake | 6 ++---- cmake/modules/SwiftSharedCMakeConfig.cmake | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/cmake/modules/ClangClCompileRules.cmake b/cmake/modules/ClangClCompileRules.cmake index 1012478926f6c..593ba684fa18d 100644 --- a/cmake/modules/ClangClCompileRules.cmake +++ b/cmake/modules/ClangClCompileRules.cmake @@ -1,10 +1,8 @@ # clang-cl interprets paths starting with /U as macro undefines, so we need to # put a -- before the input file path to force it to be treated as a path. -if(NOT MSVC AND "${CMAKE_SIMULATE_ID}" STREQUAL "MSVC") - string(REPLACE "-c " "-c -- " CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") - string(REPLACE "-c " "-c -- " CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") -endif() +string(REPLACE "-c " "-c -- " CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") +string(REPLACE "-c " "-c -- " CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") # NOTE(compnerd) incremental linking is known to cause corruption in the # protocol conformance tables. Avoid using incremental links with Visual diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake index 76a731becc937..9240596a5b533 100644 --- a/cmake/modules/SwiftSharedCMakeConfig.cmake +++ b/cmake/modules/SwiftSharedCMakeConfig.cmake @@ -258,11 +258,7 @@ endmacro() macro(swift_common_cxx_warnings) # Make unhandled switch cases be an error in assert builds if(DEFINED LLVM_ENABLE_ASSERTIONS) - check_cxx_compiler_flag("-Werror=switch" CXX_SUPPORTS_WERROR_SWITCH_FLAG) - append_if(CXX_SUPPORTS_WERROR_SWITCH_FLAG "-Werror=switch" CMAKE_CXX_FLAGS) - - check_cxx_compiler_flag("/we4062" CXX_SUPPORTS_WE4062) - append_if(CXX_SUPPORTS_WE4062 "/we4062" CMAKE_CXX_FLAGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=switch") endif() check_cxx_compiler_flag("-Werror -Wdocumentation" CXX_SUPPORTS_DOCUMENTATION_FLAG) From 3fda509805acc50ae8876efa163d1a07de2a38cd Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 6 Mar 2019 17:12:44 -0500 Subject: [PATCH 05/11] Implementation of ElementaryFunctions / Real protocols. This commit implements SE-0246, by adding conformance to Real to the Float, CGFloat, Double, and Float80 types, implemented either in terms of the system's C math library, existing standard library functionality, or LLVM intrinsics. It includes basic test coverage for these new functions, and deprecates and obsoletes *some* existing functionality in the Platform overlay. We still need to make a decision about how to handle the remaining "tgmath" functions, because obsoleting them is technically a source-breaking change (if users have unqualified names like "exp(1)", it's fine, but it would break users who have used qualified names like "Darwin.exp(1)".) --- cmake/modules/ClangClCompileRules.cmake | 6 +- cmake/modules/SwiftSharedCMakeConfig.cmake | 6 +- stdlib/public/CMakeLists.txt | 1 - .../Darwin/CoreGraphics/CGFloat.swift.gyb | 109 +++++- stdlib/public/Maths/CMakeLists.txt | 8 - stdlib/public/Maths/Maths.swift.gyb | 51 --- stdlib/public/Platform/CMakeLists.txt | 5 +- stdlib/public/Platform/tgmath.swift.gyb | 202 ++++++++--- stdlib/public/SwiftShims/LibcShims.h | 263 ++++++++++++-- stdlib/public/core/BuiltinMath.swift.gyb | 75 ---- stdlib/public/core/CMakeLists.txt | 11 +- stdlib/public/core/FloatingPoint.swift | 16 - stdlib/public/core/GroupInfo.json | 5 +- stdlib/public/core/MathFunctions.swift.gyb | 328 ++++++++++++++++++ stdlib/public/core/Mathsable.swift.gyb | 84 ----- .../complete_repl_identifier_prefix_1.swift | 2 + test/IRGen/builtin_math.swift | 2 +- test/Parse/recovery.swift | 5 +- .../Sema/sema_symlink.swift.response | 25 +- .../stability-stdlib-abi.swift.expected | 221 ++++++++++++ test/stdlib/tgmath.swift.gyb | 35 +- utils/SwiftMathFunctions.py | 62 ++++ utils/SwiftMathsFunctions.py | 46 --- 23 files changed, 1151 insertions(+), 417 deletions(-) delete mode 100644 stdlib/public/Maths/CMakeLists.txt delete mode 100644 stdlib/public/Maths/Maths.swift.gyb delete mode 100644 stdlib/public/core/BuiltinMath.swift.gyb create mode 100644 stdlib/public/core/MathFunctions.swift.gyb delete mode 100644 stdlib/public/core/Mathsable.swift.gyb create mode 100644 utils/SwiftMathFunctions.py delete mode 100644 utils/SwiftMathsFunctions.py diff --git a/cmake/modules/ClangClCompileRules.cmake b/cmake/modules/ClangClCompileRules.cmake index 593ba684fa18d..1012478926f6c 100644 --- a/cmake/modules/ClangClCompileRules.cmake +++ b/cmake/modules/ClangClCompileRules.cmake @@ -1,8 +1,10 @@ # clang-cl interprets paths starting with /U as macro undefines, so we need to # put a -- before the input file path to force it to be treated as a path. -string(REPLACE "-c " "-c -- " CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") -string(REPLACE "-c " "-c -- " CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") +if(NOT MSVC AND "${CMAKE_SIMULATE_ID}" STREQUAL "MSVC") + string(REPLACE "-c " "-c -- " CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") + string(REPLACE "-c " "-c -- " CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") +endif() # NOTE(compnerd) incremental linking is known to cause corruption in the # protocol conformance tables. Avoid using incremental links with Visual diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake index 9240596a5b533..76a731becc937 100644 --- a/cmake/modules/SwiftSharedCMakeConfig.cmake +++ b/cmake/modules/SwiftSharedCMakeConfig.cmake @@ -258,7 +258,11 @@ endmacro() macro(swift_common_cxx_warnings) # Make unhandled switch cases be an error in assert builds if(DEFINED LLVM_ENABLE_ASSERTIONS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=switch") + check_cxx_compiler_flag("-Werror=switch" CXX_SUPPORTS_WERROR_SWITCH_FLAG) + append_if(CXX_SUPPORTS_WERROR_SWITCH_FLAG "-Werror=switch" CMAKE_CXX_FLAGS) + + check_cxx_compiler_flag("/we4062" CXX_SUPPORTS_WE4062) + append_if(CXX_SUPPORTS_WE4062 "/we4062" CMAKE_CXX_FLAGS) endif() check_cxx_compiler_flag("-Werror -Wdocumentation" CXX_SUPPORTS_DOCUMENTATION_FLAG) diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt index f45ae05185627..8b661b508cfc7 100644 --- a/stdlib/public/CMakeLists.txt +++ b/stdlib/public/CMakeLists.txt @@ -61,7 +61,6 @@ if(SWIFT_BUILD_STDLIB) add_subdirectory(stubs) add_subdirectory(core) add_subdirectory(SwiftOnoneSupport) - add_subdirectory(Maths) endif() if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR) diff --git a/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb b/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb index 0ad49ea7b11e0..73685e224cde6 100644 --- a/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb +++ b/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb @@ -513,18 +513,111 @@ public func %=(lhs: inout CGFloat, rhs: CGFloat) { // tgmath //===----------------------------------------------------------------------===// +%from SwiftMathFunctions import * +extension CGFloat: Real { +% for func in ElementaryFunctions + RealFunctions: + + @_alwaysEmitIntoClient + public static func ${func.decl("CGFloat")} { + return CGFloat(NativeType.${func.swiftName}(${func.params("", ".native")})) + } +% end + + @_alwaysEmitIntoClient + public static func pow(_ x: CGFloat, _ y: CGFloat) -> CGFloat { + return CGFloat(NativeType.pow(x.native, y.native)) + } + + @_alwaysEmitIntoClient + public static func pow(_ x: CGFloat, _ n: Int) -> CGFloat { + return CGFloat(NativeType.pow(x.native, n)) + } + + @_alwaysEmitIntoClient + public static func root(_ x: CGFloat, _ n: Int) -> CGFloat { + return CGFloat(NativeType.root(x.native, n)) + } + + @_alwaysEmitIntoClient + public static func atan2(y: CGFloat, x: CGFloat) -> CGFloat { + return CGFloat(NativeType.atan2(y: y.native, x: x.native)) + } + +#if !os(Windows) + @_alwaysEmitIntoClient + public static func logGamma(_ x: CGFloat) -> CGFloat { + return CGFloat(NativeType.logGamma(x.native)) + } +#endif +} + +@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.") +@_transparent +public func cbrt(_ x: CGFloat) -> CGFloat { + return CGFloat.root(x, 3) +} + +@available(swift, deprecated: 5.1, message: "Use CGFloat.minimum( ) or Swift.min( )") +@_transparent +public func fmin(_ x: CGFloat, _ y: CGFloat) -> CGFloat { + return .minimum(x, y) +} + +@available(swift, deprecated: 5.1, message: "Use CGFloat.maximum( ) or Swift.max( )") +@_transparent +public func fmax(_ x: CGFloat, _ y: CGFloat) -> CGFloat { + return .maximum(x, y) +} + +#if !os(Windows) +@available(swift, deprecated: 5.1, message: "Use (logGamma(x), signGamma(x)).") +@_transparent +public func lgamma(_ x: CGFloat) -> (CGFloat, Int) { + return (CGFloat.logGamma(x), CGFloat.signGamma(x) == .plus ? 1 : -1) +} +#endif + +@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.") +@_transparent +public func logb(_ x: CGFloat) -> CGFloat { + return CGFloat.log2(x).rounded(.down) +} + +@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven).") +@_transparent +public func nearbyint(_ x: CGFloat) -> CGFloat { + return x.rounded(.toNearestOrEven) +} + +@available(swift, deprecated: 5.1, message: "Use the .nextUp or .nextDown property.") +@_transparent +public func nextafter(_ x: CGFloat, _ y: CGFloat) -> CGFloat { + return y > x ? x.nextUp : (y < x ? x.nextDown : y) +} + +@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven).") +@_transparent +public func rint(_ x: CGFloat) -> CGFloat { + return x.rounded(.toNearestOrEven) +} + +@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.") +@_transparent +public func tgamma(_ x: CGFloat) -> CGFloat { + return CGFloat.gamma(x) +} + %{ UnaryFunctions = [ 'acos', 'asin', 'atan', 'cos', 'sin', 'tan', 'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh', 'exp', 'exp2', 'expm1', - 'log', 'log10', 'log1p', 'log2', 'logb', - 'cbrt', 'erf', 'erfc', 'tgamma', - 'nearbyint', 'rint' + 'log', 'log10', 'log1p', 'log2', + 'erf', 'erfc', ] BinaryFunctions = [ - 'atan2', 'hypot', 'pow', 'copysign', 'nextafter', 'fdim', 'fmax', 'fmin' + 'atan2', 'hypot', 'pow', 'copysign', 'fdim' ] }% @@ -571,18 +664,12 @@ public func ldexp(_ x: CGFloat, _ n: Int) -> CGFloat { return CGFloat(ldexp(x.native, n)) } -@available(swift, deprecated: 4.2, message: "use the exponent property.") +@available(swift, deprecated: 4.2, obsoleted: 5.1, message: "use the exponent property.") @_transparent public func ilogb(_ x: CGFloat) -> Int { return Int(x.exponent) } -@_transparent -public func lgamma(_ x: CGFloat) -> (CGFloat, Int) { - let (value, sign) = lgamma(x.native) - return (CGFloat(value), sign) -} - @_transparent public func remquo(_ x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) { let (rem, quo) = remquo(x.native, y.native) diff --git a/stdlib/public/Maths/CMakeLists.txt b/stdlib/public/Maths/CMakeLists.txt deleted file mode 100644 index 10d901b8f2177..0000000000000 --- a/stdlib/public/Maths/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_swift_target_library(swiftMaths ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY - Maths.swift.gyb - - SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" - SWIFT_COMPILE_FLAGS - LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" -) - diff --git a/stdlib/public/Maths/Maths.swift.gyb b/stdlib/public/Maths/Maths.swift.gyb deleted file mode 100644 index 669c449054e3c..0000000000000 --- a/stdlib/public/Maths/Maths.swift.gyb +++ /dev/null @@ -1,51 +0,0 @@ -//===--- Maths.swift ------------------------------------------*- swift -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -// MARK: - Free functions defined on FloatingPoint -%for constraint in ["T: FloatingPoint", "T: SIMD, T.Scalar: FloatingPoint"]: -% for (func,dir) in [("ceil", ".up"), ("floor", ".down"), ("round", ""), ("trunc", ".towardZero")]: -@_alwaysEmitIntoClient -public func ${func}(_ x: T) -> T where ${constraint} { - return x.rounded(${dir}) -} - -%end -@_alwaysEmitIntoClient -public func sqrt(_ x: T) -> T where ${constraint} { - return x.squareRoot() -} - -@_alwaysEmitIntoClient -public func fma(_ x: T, _ y: T, _ z: T) -> T where ${constraint} { - return z.addingProduct(x, y) -} - -%end -@_alwaysEmitIntoClient -public func remainder(_ x: T, _ y: T) -> T where T: FloatingPoint { - return x.remainder(dividingBy: y) -} - -@_alwaysEmitIntoClient -public func fmod(_ x: T, _ y: T) -> T where T: FloatingPoint { - return x.truncatingRemainder(dividingBy: y) -} - -// MARK: - Free functions defined on Mathsable -%from SwiftMathsFunctions import * -%for func in MathsFunctions: - -@_alwaysEmitIntoClient -public func ${func.free_decl()} { - return T.Maths.${func.name}(${func.params()}) -} -%end diff --git a/stdlib/public/Platform/CMakeLists.txt b/stdlib/public/Platform/CMakeLists.txt index aa72adc77750c..305ae6e181da9 100644 --- a/stdlib/public/Platform/CMakeLists.txt +++ b/stdlib/public/Platform/CMakeLists.txt @@ -18,7 +18,6 @@ add_swift_target_library(swiftDarwin ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_ SWIFT_COMPILE_FLAGS -Xfrontend -disable-objc-attr-requires-foundation-module "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" TARGET_SDKS ALL_APPLE_PLATFORMS - SWIFT_MODULE_DEPENDS Maths # This is overly conservative, but we have so few API notes files that # haven't migrated to the Swift repo that it's probably fine in practice. @@ -34,7 +33,6 @@ add_swift_target_library(swiftGlibc ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_O SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" TARGET_SDKS ANDROID CYGWIN FREEBSD LINUX HAIKU - SWIFT_MODULE_DEPENDS Maths DEPENDS glibc_modulemap) add_swift_target_library(swiftMSVCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY @@ -46,8 +44,7 @@ add_swift_target_library(swiftMSVCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_ SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" - TARGET_SDKS WINDOWS - SWIFT_MODULE_DEPENDS Maths) + TARGET_SDKS WINDOWS) set(glibc_modulemap_target_list) foreach(sdk ${SWIFT_SDKS}) diff --git a/stdlib/public/Platform/tgmath.swift.gyb b/stdlib/public/Platform/tgmath.swift.gyb index 563c335cc95fc..dc22df68f1ac6 100644 --- a/stdlib/public/Platform/tgmath.swift.gyb +++ b/stdlib/public/Platform/tgmath.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information @@ -11,15 +11,55 @@ //===----------------------------------------------------------------------===// import SwiftShims -@_exported import Maths // Generic functions implementable directly on FloatingPoint. @_transparent -@available(swift, deprecated: 4.2, renamed: "abs") +@available(swift, deprecated: 4.2, obsoleted: 5.1, renamed: "Swift.abs") public func fabs(_ x: T) -> T { return x.magnitude } +@available(swift, obsoleted: 5.1, message: "Use Swift.sqrt(x) or x.squareRoot().") +@_transparent +public func sqrt(_ x: T) -> T { + return x.squareRoot() +} + +@_transparent +public func fma(_ x: T, _ y: T, _ z: T) -> T { + return z.addingProduct(x, y) +} + +@_transparent +public func remainder(_ x: T, _ y: T) -> T { + return x.remainder(dividingBy: y) +} + +@_transparent +public func fmod(_ x: T, _ y: T) -> T { + return x.truncatingRemainder(dividingBy: y) +} + +@_transparent +public func ceil(_ x: T) -> T { + return x.rounded(.up) +} + +@_transparent +public func floor(_ x: T) -> T { + return x.rounded(.down) +} + +@_transparent +public func round(_ x: T) -> T { + return x.rounded() +} + +@_transparent +public func trunc(_ x: T) -> T { + return x.rounded(.towardZero) +} + @_transparent public func scalbn(_ x: T, _ n : Int) -> T { return T(sign: .plus, exponent: T.Exponent(n), significand: x) @@ -73,7 +113,7 @@ public func isnan(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the sign property.") public func signbit(_ value: T) -> Int { fatalError() } -@available(swift, deprecated: 4.2, message: "use the exponent property.") +@available(swift, deprecated: 4.2, obsoleted: 5.1, message: "use the exponent property.") public func ilogb(_ x: T) -> Int { return Int(x.exponent) } @@ -116,41 +156,20 @@ UnaryFunctions = [ 'acos', 'asin', 'atan', 'tan', 'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh', 'expm1', - 'log1p', 'logb', - 'cbrt', 'erf', 'erfc', 'tgamma', + 'log1p', + 'erf', 'erfc', ] # These functions have a corresponding LLVM intrinsic -# We call this intrinsic via the Builtin method so keep this list in -# sync with core/BuiltinMath.swift.gyb UnaryIntrinsicFunctions = [ - 'nearbyint', 'rint', + 'cos', 'sin', 'exp', 'exp2', 'log', 'log10', 'log2', 'nearbyint', 'rint' ] # (T, T) -> T BinaryFunctions = [ - 'atan2', 'hypot', 'pow', - 'copysign', 'nextafter', 'fdim', 'fmax', 'fmin' -] - -# These functions have special implementations. -OtherFunctions = [ - 'scalbn', 'lgamma', 'remquo', 'nan', 'jn', 'yn' + 'atan2', 'hypot', 'fdim', 'copysign' ] -# These functions are imported correctly as-is. -OkayFunctions = ['j0', 'j1', 'y0', 'y1'] - -# These functions are not supported for various reasons. -UnhandledFunctions = [ - 'math_errhandling', 'scalbln', - 'lrint', 'lround', 'llrint', 'llround', 'nexttoward', - 'isgreater', 'isgreaterequal', 'isless', 'islessequal', - 'islessgreater', 'isunordered', '__exp10', - '__sincos', '__cospi', '__sinpi', '__tanpi', '__sincospi' -] - - def AllFloatTypes(): for bits in allFloatBits: yield floatName(bits), cFloatName(bits), cFuncSuffix(bits) @@ -184,50 +203,74 @@ def TypedBinaryFunctions(): % end @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { - return ${T}(${ufunc}${f}(${CT}(x))) + return ${T}.${ufunc}(x) } % if T == 'Float80': #endif % end % end +@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.") +@_transparent +public func cbrt(_ x: Float) -> Float { + return Float.root(x, 3) +} + +@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.") +@_transparent +public func logb(_ x: Float) -> Float { + return Float.log2(x).rounded(.down) +} + +@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.") +@_transparent +public func tgamma(_ x: Float) -> Float { + return Float.gamma(x) +} + +#if (arch(i386) || arch(x86_64)) && !os(Windows) +@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.") +@_transparent +public func cbrt(_ x: Float80) -> Float80 { + return Float80.root(x, 3) +} + +@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.") +@_transparent +public func logb(_ x: Float80) -> Float80 { + return Float80.log2(x).rounded(.down) +} + +@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.") +@_transparent +public func tgamma(_ x: Float80) -> Float80 { + return Float80.gamma(x) +} +#endif -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) // Unary intrinsic functions // Note these have a corresponding LLVM intrinsic % for T, ufunc in TypedUnaryIntrinsicFunctions(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end +% if ufunc[-3:] != 'int': @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { - return _${ufunc}(x) + return ${T}.${ufunc}(x) } -% if T == 'Float80': -#endif -% end - -% end -#else -// FIXME: As of now, we cannot declare 64-bit (Double/CDouble) overlays here. -// Since CoreFoundation also exports libc functions, they will conflict with -// Swift overlays when building Foundation. For now, just like normal -// UnaryFunctions, we define overlays only for OverlayFloatTypes. -% for ufunc in UnaryIntrinsicFunctions: -% for T, CT, f in OverlayFloatTypes(): -% if T == 'Float80': -#if (arch(i386) || arch(x86_64)) && !os(Windows) -% end +% else: +@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven) instead.") @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { - return ${T}(${ufunc}${f}(${CT}(x))) + return x.rounded(.toNearestOrEven) } -% if T == 'Float80': +% end +% if T == 'Float80': #endif -% end % end + % end -#endif // Binary functions @@ -245,6 +288,54 @@ public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} { % end +@_transparent +public func pow(_ x: Float, _ y: Float) -> Float { + return Float.pow(x, y) +} + +@available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.") +@_transparent +public func nextafter(_ x: Float, _ y: Float) -> Float { + return y > x ? x.nextUp : (y < x ? x.nextDown : y) +} + +@available(swift, deprecated: 5.1, message: "Use Float.minimum( ) or Swift.min( )") +@_transparent +public func fmin(_ x: Float, _ y: Float) -> Float { + return .minimum(x, y) +} + +@available(swift, deprecated: 5.1, message: "Use Float.maximum( ) or Swift.max( )") +@_transparent +public func fmax(_ x: Float, _ y: Float) -> Float { + return .maximum(x, y) +} + +#if (arch(i386) || arch(x86_64)) && !os(Windows) +@_transparent +public func pow(_ x: Float80, _ y: Float80) -> Float80 { + return Float80.pow(x, y) +} + +@available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.") +@_transparent +public func nextafter(_ x: Float80, _ y: Float80) -> Float80 { + return y > x ? x.nextUp : (y < x ? x.nextDown : y) +} + +@available(swift, deprecated: 5.1, message: "Use Float80.minimum( ) or Swift.min( )") +@_transparent +public func fmin(_ x: Float80, _ y: Float80) -> Float80 { + return Float80.minimum(x, y) +} + +@available(swift, deprecated: 5.1, message: "Use Float80.maximum( ) or Swift.max( )") +@_transparent +public func fmax(_ x: Float80, _ y: Float80) -> Float80 { + return Float80.maximum(x, y) +} +#endif + % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. % for T, CT, f in AllFloatTypes(): % if T == 'Float80': @@ -253,11 +344,10 @@ public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} { // lgamma not available on Windows, apparently? #if !os(Windows) % end +@available(swift, deprecated: 5.1, message: "Use (logGamma(x), signGamma(x)).") @_transparent public func lgamma(_ x: ${T}) -> (${T}, Int) { - var sign = Int32(0) - let value = lgamma${f}_r(${CT}(x), &sign) - return (${T}(value), Int(sign)) + return (${T}.logGamma(x), ${T}.signGamma(x) == .plus ? 1 : -1) } #endif @@ -284,8 +374,8 @@ public func remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end -@available(swift, deprecated: 4.2, message: - "use ${T}(nan: ${T}.RawSignificand) instead.") +@available(swift, deprecated: 4.2, obsoleted: 5.1, message: + "use ${T}(nan: ${T}.RawSignificand).") @_transparent public func nan(_ tag: String) -> ${T} { return ${T}(nan${f}(tag)) diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h index 3353d84aacfdb..e495d56501c91 100644 --- a/stdlib/public/SwiftShims/LibcShims.h +++ b/stdlib/public/SwiftShims/LibcShims.h @@ -126,6 +126,16 @@ static inline __swift_size_t _swift_stdlib_malloc_size(const void *ptr) { #endif // Math library functions +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_remainderf(float _self, float other) { + return __builtin_remainderf(_self, other); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_squareRootf(float _self) { + return __builtin_sqrtf(_self); +} + static inline SWIFT_ALWAYS_INLINE float _swift_stdlib_tanf(float x) { return __builtin_tanf(x); @@ -150,17 +160,94 @@ static inline SWIFT_ALWAYS_INLINE float _swift_stdlib_atan2f(float y, float x) { return __builtin_atan2f(y, x); } - + static inline SWIFT_ALWAYS_INLINE -float _swift_stdlib_remainderf(float _self, float _other) { - return __builtin_remainderf(_self, _other); +float _swift_stdlib_coshf(float x) { + return __builtin_coshf(x); } static inline SWIFT_ALWAYS_INLINE -float _swift_stdlib_squareRootf(float _self) { - return __builtin_sqrtf(_self); +float _swift_stdlib_sinhf(float x) { + return __builtin_sinhf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_tanhf(float x) { + return __builtin_tanhf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_acoshf(float x) { + return __builtin_acoshf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_asinhf(float x) { + return __builtin_asinhf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_atanhf(float x) { + return __builtin_atanhf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_exp10f(float x) { +#if defined __APPLE__ + extern float __exp10f(float); + return __exp10f(x); +#else + return __builtin_powf(10, x); +#endif +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_expm1f(float x) { + return __builtin_expm1f(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_log1pf(float x) { + return __builtin_log1pf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_hypotf(float x, float y) { + return __builtin_hypotf(x, y); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_erff(float x) { + return __builtin_erff(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_erfcf(float x) { + return __builtin_erfcf(x); +} + +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_tgammaf(float x) { + return __builtin_tgammaf(x); } +static inline SWIFT_ALWAYS_INLINE +float _swift_stdlib_lgammaf(float x) { + extern float lgammaf_r(float x, int *psigngam); + int dontCare; + return lgammaf_r(x, &dontCare); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_remainder(double _self, double other) { + return __builtin_remainder(_self, other); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_squareRoot(double _self) { + return __builtin_sqrt(_self); +} + static inline SWIFT_ALWAYS_INLINE double _swift_stdlib_tan(double x) { return __builtin_tan(x); @@ -185,18 +272,95 @@ static inline SWIFT_ALWAYS_INLINE double _swift_stdlib_atan2(double y, double x) { return __builtin_atan2(y, x); } + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_cosh(double x) { + return __builtin_cosh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_sinh(double x) { + return __builtin_sinh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_tanh(double x) { + return __builtin_tanh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_acosh(double x) { + return __builtin_acosh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_asinh(double x) { + return __builtin_asinh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_atanh(double x) { + return __builtin_atanh(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_exp10(double x) { +#if defined __APPLE__ + extern double __exp10(double); + return __exp10(x); +#else + return __builtin_pow(10, x); +#endif +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_expm1(double x) { + return __builtin_expm1(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_log1p(double x) { + return __builtin_log1p(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_hypot(double x, double y) { + return __builtin_hypot(x, y); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_erf(double x) { + return __builtin_erf(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_erfc(double x) { + return __builtin_erfc(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_tgamma(double x) { + return __builtin_tgamma(x); +} + +static inline SWIFT_ALWAYS_INLINE +double _swift_stdlib_lgamma(double x) { + extern double lgamma_r(double x, int *psigngam); + int dontCare; + return lgamma_r(x, &dontCare); +} +#if !defined _WIN32 && (defined __i386__ || defined __x86_64__) static inline SWIFT_ALWAYS_INLINE -double _swift_stdlib_remainder(double _self, double _other) { - return __builtin_remainder(_self, _other); +long double _swift_stdlib_remainderl(long double _self, long double other) { + return __builtin_remainderl(_self, other); } static inline SWIFT_ALWAYS_INLINE -double _swift_stdlib_squareRoot(double _self) { - return __builtin_sqrt(_self); +long double _swift_stdlib_squareRootl(long double _self) { + return __builtin_sqrtl(_self); } -#if !defined _WIN32 && (defined __i386__ || defined __x86_64__) static inline SWIFT_ALWAYS_INLINE long double _swift_stdlib_tanl(long double x) { return __builtin_tanl(x); @@ -223,25 +387,78 @@ long double _swift_stdlib_atan2l(long double y, long double x) { } static inline SWIFT_ALWAYS_INLINE -long double _swift_stdlib_remainderl(long double _self, long double _other) { - return __builtin_remainderl(_self, _other); +long double _swift_stdlib_coshl(long double x) { + return __builtin_coshl(x); } static inline SWIFT_ALWAYS_INLINE -long double _swift_stdlib_squareRootl(long double _self) { - return __builtin_sqrtl(_self); +long double _swift_stdlib_sinhl(long double x) { + return __builtin_sinhl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_tanhl(long double x) { + return __builtin_tanhl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_acoshl(long double x) { + return __builtin_acoshl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_asinhl(long double x) { + return __builtin_asinhl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_atanhl(long double x) { + return __builtin_atanhl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_exp10l(long double x) { + return __builtin_powl(10, x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_expm1l(long double x) { + return __builtin_expm1l(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_log1pl(long double x) { + return __builtin_log1pl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_hypotl(long double x, long double y) { + return __builtin_hypotl(x, y); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_erfl(long double x) { + return __builtin_erfl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_erfcl(long double x) { + return __builtin_erfcl(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_tgammal(long double x) { + return __builtin_tgammal(x); +} + +static inline SWIFT_ALWAYS_INLINE +long double _swift_stdlib_lgammal(long double x) { + extern long double lgammal_r(long double x, int *psigngam); + int dontCare; + return lgammal_r(x, &dontCare); } #endif -// Apple's math.h does not declare lgamma_r() etc by default, but they're -// unconditionally exported by libsystem_m.dylib in all OS versions that -// support Swift development; we simply need to provide declarations here. -#if defined(__APPLE__) -float lgammaf_r(float x, int *psigngam); -double lgamma_r(double x, int *psigngam); -long double lgammal_r(long double x, int *psigngam); -#endif // defined(__APPLE__) - #ifdef __cplusplus }} // extern "C", namespace swift #endif diff --git a/stdlib/public/core/BuiltinMath.swift.gyb b/stdlib/public/core/BuiltinMath.swift.gyb deleted file mode 100644 index 9f7108f2a10ae..0000000000000 --- a/stdlib/public/core/BuiltinMath.swift.gyb +++ /dev/null @@ -1,75 +0,0 @@ -//===--- BuiltinMath.swift.gyb --------------------------------*- swift -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -%{ - -# Don't need 64-bit (Double/CDouble) overlays. The ordinary C imports work fine. -overlayFloatBits = [32, 80] -allFloatBits = [32, 64, 80] - -def floatName(bits): - if bits == 32: - return 'Float' - if bits == 64: - return 'Double' - if bits == 80: - return 'Float80' - -def cFloatName(bits): - if bits == 32: - return 'CFloat' - if bits == 64: - return 'CDouble' - if bits == 80: - return 'CLongDouble' - -def cFuncSuffix(bits): - if bits == 32: - return 'f' - if bits == 64: - return '' - if bits == 80: - return 'l' - -# Each of the following lists is ordered to match math.h - -# These functions have a corresponding LLVM intrinsic -# Note, keep this up to date with Darwin/tgmath.swift.gyb -UnaryIntrinsicFunctions = [ - 'nearbyint', 'rint', -] - -def TypedUnaryIntrinsicFunctions(): - for ufunc in UnaryIntrinsicFunctions: - for bits in allFloatBits: - yield floatName(bits), cFloatName(bits), bits, ufunc - -}% - -// Unary intrinsic functions -// Note these have a corresponding LLVM intrinsic -% for T, CT, bits, ufunc in TypedUnaryIntrinsicFunctions(): -% if bits == 80: -#if !os(Windows) && (arch(i386) || arch(x86_64)) -% end -@_transparent -public func _${ufunc}(_ x: ${T}) -> ${T} { - return ${T}(Builtin.int_${ufunc}_FPIEEE${bits}(x._value)) -} -% if bits == 80: -#endif -% end -% end - -// ${'Local Variables'}: -// eval: (read-only-mode 1) -// End: diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 6b06ea7842834..849a883920f0d 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -87,7 +87,6 @@ set(SWIFTLIB_ESSENTIAL LifetimeManager.swift ManagedBuffer.swift Map.swift - Mathsable.swift.gyb MemoryLayout.swift UnicodeScalar.swift # ORDER DEPENDENCY: Must precede Mirrors.swift Misc.swift @@ -185,7 +184,6 @@ set(SWIFTLIB_ESSENTIAL set(SWIFTLIB_ESSENTIAL_GYB_SOURCES AtomicInt.swift.gyb - BuiltinMath.swift.gyb Codable.swift.gyb FixedArray.swift.gyb FloatingPointParsing.swift.gyb @@ -219,10 +217,11 @@ set(SWIFTLIB_SOURCES ) set(SWIFTLIB_GYB_SOURCES - ${SWIFTLIB_ESSENTIAL_GYB_SOURCES} - ExistentialCollection.swift.gyb - SIMDVectorTypes.swift.gyb - Tuple.swift.gyb + ${SWIFTLIB_ESSENTIAL_GYB_SOURCES} + ExistentialCollection.swift.gyb + MathFunctions.swift.gyb + SIMDVectorTypes.swift.gyb + Tuple.swift.gyb ) set(GROUP_INFO_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/GroupInfo.json) set(swift_core_link_flags "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}") diff --git a/stdlib/public/core/FloatingPoint.swift b/stdlib/public/core/FloatingPoint.swift index 6933ca3ce82f4..ccb4fdd788c52 100644 --- a/stdlib/public/core/FloatingPoint.swift +++ b/stdlib/public/core/FloatingPoint.swift @@ -1898,10 +1898,6 @@ extension FloatingPoint { /// other is NaN. @inlinable public static func minimum(_ x: Self, _ y: Self) -> Self { - if x.isSignalingNaN || y.isSignalingNaN { - // Produce a quiet NaN matching platform arithmetic behavior. - return x + y - } if x <= y || y.isNaN { return x } return y } @@ -1935,10 +1931,6 @@ extension FloatingPoint { /// other is NaN. @inlinable public static func maximum(_ x: Self, _ y: Self) -> Self { - if x.isSignalingNaN || y.isSignalingNaN { - // Produce a quiet NaN matching platform arithmetic behavior. - return x + y - } if x > y || y.isNaN { return x } return y } @@ -1974,10 +1966,6 @@ extension FloatingPoint { /// a number if the other is NaN. @inlinable public static func minimumMagnitude(_ x: Self, _ y: Self) -> Self { - if x.isSignalingNaN || y.isSignalingNaN { - // Produce a quiet NaN matching platform arithmetic behavior. - return x + y - } if x.magnitude <= y.magnitude || y.isNaN { return x } return y } @@ -2013,10 +2001,6 @@ extension FloatingPoint { /// a number if the other is NaN. @inlinable public static func maximumMagnitude(_ x: Self, _ y: Self) -> Self { - if x.isSignalingNaN || y.isSignalingNaN { - // Produce a quiet NaN matching platform arithmetic behavior. - return x + y - } if x.magnitude > y.magnitude || y.isNaN { return x } return y } diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index 07d406c18160d..aa250689af7ad 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -158,7 +158,7 @@ ], "Math": [ "SetAlgebra.swift", - "BuiltinMath.swift", + "MathFunctions.swift", { "Integers": [ "Integers.swift", @@ -167,8 +167,7 @@ "Floating": [ "FloatingPoint.swift", "FloatingPointParsing.swift", - "FloatingPointTypes.swift", - "Mathsable.swift"], + "FloatingPointTypes.swift"], "Vector": [ "SIMDVector.swift", "SIMDVectorTypes.swift"]} diff --git a/stdlib/public/core/MathFunctions.swift.gyb b/stdlib/public/core/MathFunctions.swift.gyb new file mode 100644 index 0000000000000..c4a9ccdb9834e --- /dev/null +++ b/stdlib/public/core/MathFunctions.swift.gyb @@ -0,0 +1,328 @@ +//===--- MathFunctions.swift ----------------------------------*- swift -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2019 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import SwiftShims +%from SwiftMathFunctions import * + +/// A type that has elementary functions available. +/// +/// An ["elementary function"][elfn] is a function built up from powers, roots, +/// exponentials, logarithms, trigonometric functions (sin, cos, tan) and +/// their inverses, and the hyperbolic functions (sinh, cosh, tanh) and their +/// inverses. +/// +/// Conformance to this protocol means that all of these building blocks are +/// available as static functions on the type. +/// +/// ```swift +/// let x: Float = 1 +/// let y = Float.sin(x) // 0.84147096 +/// ``` +/// +/// All of these are made available as free functions by importing the Math +/// module: +/// +/// ```swift +/// import Math +/// let y = sin(x) // 0.84147096 +/// ``` +/// +/// Additional operations, such as `atan2(y:x:)`, `hypot(_:_:)` and some +/// special functions, are provided on the Real protocol, which refines both +/// ElementaryFunctions and FloatingPoint. +/// +/// [elfn]: http://en.wikipedia.org/wiki/Elementary_function +public protocol ElementaryFunctions { + +%for func in ElementaryFunctions: + + ${func.comment} + static func ${func.decl("Self")} +%end + + /// `exp(y log(x))` computed without loss of intermediate precision. + /// + /// For real types, if `x` is negative the result is NaN, even if `y` has + /// an integral value. For complex types, there is a branch cut on the + /// negative real axis. + static func pow(_ x: Self, _ y: Self) -> Self + + /// `x` raised to the `n`th power. + static func pow(_ x: Self, _ n: Int) -> Self + + /// The `n`th root of `x`. + /// + /// For real types, if `x` is negative and `n` is even, the result is NaN. + /// For complex types, there is a branch cut along the negative real axis. + static func root(_ x: Self, _ n: Int) -> Self +} + +/// A type that models the real numbers. +public protocol Real: ElementaryFunctions, FloatingPoint { +%for func in RealFunctions: + + ${func.comment} + static func ${func.decl("Self")} +%end + + /// `atan(y/x)` with quadrant fixup. + /// + /// There is an infinite family of angles whose tangent is `y/x`. `atan2` + /// selects the representative that is the angle between the vector `(x, y)` + /// and the real axis in the range [-π, π]. + static func atan2(y: Self, x: Self) -> Self + +#if !os(Windows) + // lgamma is not available on Windows. + // TODO: provide an implementation of lgamma with the stdlib to support + // Windows so we can vend a uniform interface. + + /// `log(gamma(x))` computed without undue overflow. + /// + /// `log(abs(gamma(x)))` is returned. To get the sign of `gamma(x)` cheaply, + /// use `signGamma(x)`. + static func logGamma(_ x: Self) -> Self +#endif +} + +extension Real { +#if !os(Windows) + // lgamma is not available on Windows; no lgamma means signGamma + // is basically useless, so don't bother exposing it. + + /// The sign of `gamma(x)`. + /// + /// This function is typically used in conjunction with `logGamma(x)`, which + /// computes `log(abs(gamma(x)))`, to recover the sign information that is + /// lost to the absolute value. + /// + /// `gamma(x)` has a simple pole at each non-positive integer and an + /// essential singularity at infinity; we arbitrarily choose to return + /// `.plus` for the sign in those cases. For all other values, `signGamma(x)` + /// is `.plus` if `x >= 0` or `trunc(x)` is odd, and `.minus` otherwise. + @_alwaysEmitIntoClient + public static func signGamma(_ x: Self) -> FloatingPointSign { + if x >= 0 { return .plus } + let trunc = x.rounded(.towardZero) + // Treat poles as gamma(x) == +inf. This is arbitrary, but we need to + // pick one sign or the other. + if x == trunc { return .plus } + // Result is .minus if trunc is even, .plus otherwise. To figure out if + // trunc is even or odd, check if trunc/2 is an integer. + let halfTrunc = trunc/2 + if halfTrunc == halfTrunc.rounded(.towardZero) { return .minus } + return .plus + } +#endif +} + +%for type in all_floating_point_types(): +% if type.bits == 80: +#if (arch(i386) || arch(x86_64)) && !os(Windows) +% end +% Self = type.stdlib_name +extension ${Self}: Real { +% for func in ElementaryFunctions + RealFunctions: + + @_alwaysEmitIntoClient + public static func ${func.decl(Self)} { + return ${func.impl(type)} + } +% end + + @_alwaysEmitIntoClient + public static func pow(_ x: ${Self}, _ y: ${Self}) -> ${Self} { + guard x >= 0 else { return .nan } + return ${Self}(Builtin.int_pow_FPIEEE${type.bits}(x._value, y._value)) + } + + @_alwaysEmitIntoClient + public static func pow(_ x: ${Self}, _ n: Int) -> ${Self} { + // TODO: this implementation isn't quite right for n so large that + // the conversion to `${Self}` rounds. We could also consider using + // a multiply-chain implementation for small `n`; this would be faster + // for static `n`, but less accurate on platforms with a good `pow` + // implementation. + return ${Self}(Builtin.int_pow_FPIEEE${type.bits}(x._value, ${Self}(n)._value)) + } + + @_alwaysEmitIntoClient + public static func root(_ x: ${Self}, _ n: Int) -> ${Self} { + guard x >= 0 || n % 2 != 0 else { return .nan } + // TODO: this implementation isn't quite right for n so large that + // the conversion to `${Self}` rounds. + return ${Self}(signOf: x, magnitudeOf: pow(x, 1/${Self}(n))) + } + + @_alwaysEmitIntoClient + public static func atan2(y: ${Self}, x: ${Self}) -> ${Self} { + return _swift_stdlib_atan2${type.cFuncSuffix}(y, x) + } + +#if !os(Windows) + @_alwaysEmitIntoClient + public static func logGamma(_ x: ${Self}) -> ${Self} { + return _swift_stdlib_lgamma${type.cFuncSuffix}(x) + } +#endif +} +% if type.bits == 80: +#endif +% end +%end + +// MARK: - Free functions defined on ElementaryFunctions: +%from SwiftMathFunctions import * +%for func in ElementaryFunctions: + +% if func.name == 'sqrt': +// sqrt requires availability because it was previous generic on FloatingPoint. +@available(swift, introduced: 5.1) +% end +@_alwaysEmitIntoClient +public func ${func.free_decl()} { + return T.${func.swiftName}(${func.params()}) +} + +@_alwaysEmitIntoClient +public func ${func.free_decl("T: SIMD, T.Scalar: ElementaryFunctions")} { + var r = T() + for i in r.indices { r[i] = T.Scalar.${func.swiftName}(${func.params("","[i]")}) } + return r +} +%end + +@_alwaysEmitIntoClient +public func pow(_ x: T, _ y: T) -> T where T: ElementaryFunctions { + return T.pow(x, y) +} + +@_alwaysEmitIntoClient +public func pow(_ x: T, _ y: T) -> T where T: SIMD, T.Scalar: ElementaryFunctions { + var r = T() + for i in r.indices { r[i] = T.Scalar.pow(x[i], y[i]) } + return r +} + +@_alwaysEmitIntoClient +public func pow(_ x: T, _ n: Int) -> T where T: ElementaryFunctions { + return T.pow(x, n) +} + +@_alwaysEmitIntoClient +public func pow(_ x: T, _ n: Int) -> T where T: SIMD, T.Scalar: ElementaryFunctions { + var r = T() + for i in r.indices { r[i] = T.Scalar.pow(x[i], n) } + return r +} + +@_alwaysEmitIntoClient +public func root(_ x: T, _ n: Int) -> T where T: ElementaryFunctions { + return T.root(x, n) +} + +@_alwaysEmitIntoClient +public func root(_ x: T, _ n: Int) -> T where T: SIMD, T.Scalar: ElementaryFunctions { + var r = T() + for i in r.indices { r[i] = T.Scalar.root(x[i], n) } + return r +} + +// MARK: - Free functions defined on Real: +%for func in RealFunctions: + +@_alwaysEmitIntoClient +public func ${func.free_decl("T: Real")} { + return T.${func.swiftName}(${func.params()}) +} + +@_alwaysEmitIntoClient +public func ${func.free_decl("T: SIMD, T.Scalar: Real")} { + var r = T() + for i in r.indices { r[i] = T.Scalar.${func.swiftName}(${func.params("","[i]")}) } + return r +} +%end + +@_alwaysEmitIntoClient +public func atan2(y: T, x: T) -> T where T: Real { + return T.atan2(y: y, x: x) +} + +@_alwaysEmitIntoClient +public func atan2(y: T, x: T) -> T where T: SIMD, T.Scalar: Real { + var r = T() + for i in r.indices { r[i] = T.Scalar.atan2(y: y[i], x: x[i]) } + return r +} + +// logGamma is not available on Windows. +// TODO: logGamma, signGamma for SIMD types. +#if !os(Windows) +@_alwaysEmitIntoClient +public func logGamma(_ x: T) -> T where T: Real { + return T.logGamma(x) +} + +@_alwaysEmitIntoClient +public func signGamma(_ x: T) -> FloatingPointSign where T: Real { + return T.signGamma(x) +} +#endif + +// MARK: - Free functions defined on FloatingPoint: +% for (func,dir) in [("ceil", ".up"), ("floor", ".down"), ("round", ""), ("trunc", ".towardZero")]: + +@_alwaysEmitIntoClient +public func ${func}(_ x: T) -> T where T: FloatingPoint { + return x.rounded(${dir}) +} + +@_alwaysEmitIntoClient +public func ${func}(_ x: T) -> T where T: SIMD, T.Scalar: FloatingPoint { + return x.rounded(${dir}) +} +%end + +@_alwaysEmitIntoClient +public func fma(_ x: T, _ y: T, _ z: T) -> T where T: FloatingPoint { + return z.addingProduct(x, y) +} + +@_alwaysEmitIntoClient +public func fma(_ x: T, _ y: T, _ z: T) -> T where T: SIMD, T.Scalar: FloatingPoint { + return z.addingProduct(x, y) +} + +@_alwaysEmitIntoClient +public func remainder(_ dividend: T, _ divisor: T) -> T where T: FloatingPoint { + return dividend.remainder(dividingBy: divisor) +} + +@_alwaysEmitIntoClient +public func remainder(_ dividend: T, _ divisor: T) -> T where T: SIMD, T.Scalar: FloatingPoint { + var r = T() + for i in r.indices { r[i] = dividend[i].remainder(dividingBy: divisor[i]) } + return r +} + +@_alwaysEmitIntoClient +public func copysign(_ magnitude: T, _ sign: T) -> T where T: FloatingPoint { + return T(signOf: sign, magnitudeOf: magnitude) +} + +@_alwaysEmitIntoClient +public func copysign(_ magnitude: T, _ sign: T) -> T where T: SIMD, T.Scalar: FloatingPoint { + var r = T() + for i in r.indices { r[i] = copysign(magnitude[i], sign[i]) } + return r +} diff --git a/stdlib/public/core/Mathsable.swift.gyb b/stdlib/public/core/Mathsable.swift.gyb deleted file mode 100644 index 62b0b6bb5b76b..0000000000000 --- a/stdlib/public/core/Mathsable.swift.gyb +++ /dev/null @@ -1,84 +0,0 @@ -//===--- Mathsable.swift --------------------------------------*- swift -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import SwiftShims - -%{ -from SwiftMathsFunctions import * -}% - -/// A type that has basic maths functions available. -/// -/// "Basic maths functions" means roughly "the usual transcendental -/// functions provided by `` in C-family langauges." -public protocol Mathsable { - associatedtype Maths: MathsImplementations where Maths.Value == Self -} - -/// A type that provides the implementation trampolines for maths functions -/// on the related `Value` type. -public protocol MathsImplementations { - associatedtype Value -%for func in MathsFunctions: - static func ${func.decl("Value")} -%end -} - -%for type in all_floating_point_types(): -% if type.bits == 80: -#if (arch(i386) || arch(x86_64)) && !os(Windows) -% end -extension ${type.stdlib_name}: Mathsable { - /// Defines basic maths functions for ${type.stdlib_name} - @_frozen - public enum Maths: MathsImplementations { - public typealias Value = ${type.stdlib_name} -% for func in MathsFunctions: - @_alwaysEmitIntoClient - public static func ${func.decl("Value")} { - return ${func.impl(type)} - } -% end - } -} - -% if type.bits == 80: -#endif -% end -%end - -/// Defines basic maths functions operating elementwise on SIMD vector types. -@_fixed_layout -public struct _SIMDMaths: MathsImplementations -where V: SIMD, V.Scalar: Mathsable { - - public typealias Value = V -%for func in MathsFunctions: - - @_alwaysEmitIntoClient - public static func ${func.decl("V")} { - var r = V() - for i in x.indices { - r[i] = V.Scalar.Maths.${func.name}(${func.params("", "[i]")}) - } - return r - } -%end -} - -extension SIMD where Scalar: Mathsable { - public typealias Maths = _SIMDMaths -} - -%for n in [2,3,4,8,16,32,64]: -extension SIMD${n}: Mathsable where Scalar: Mathsable { } -%end diff --git a/test/IDE/complete_repl_identifier_prefix_1.swift b/test/IDE/complete_repl_identifier_prefix_1.swift index 6d2bb2527bdd9..99119f30619a8 100644 --- a/test/IDE/complete_repl_identifier_prefix_1.swift +++ b/test/IDE/complete_repl_identifier_prefix_1.swift @@ -2,6 +2,8 @@ // CHECK: Begin completions // CHECK-NEXT: {{^}}true: Bool{{$}} +// CHECK-NEXT: {{^}}trunc(x: FloatingPoint) -> FloatingPoint +// CHECK-NEXT: {{^}}trunc(x: SIMD) -> SIMD // CHECK-NEXT: End completions tru diff --git a/test/IRGen/builtin_math.swift b/test/IRGen/builtin_math.swift index 93a7938f69389..1e3dbeacaf378 100644 --- a/test/IRGen/builtin_math.swift +++ b/test/IRGen/builtin_math.swift @@ -29,7 +29,7 @@ public func test1(f : Float) -> Float { // CHECK: call double @llvm.exp.f64 public func test2(f : Double) -> Double { - return _exp(f) + return exp(f) } // CHECK-LABEL: define {{.*}}test3 diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift index 1712d39a7adf2..ca41457e249b2 100644 --- a/test/Parse/recovery.swift +++ b/test/Parse/recovery.swift @@ -33,8 +33,7 @@ func useContainer() -> () { func exists() -> Bool { return true } } -// expected-note @+2 {{did you mean 'test'?}} -// expected-note @+1 {{'test' declared here}} +// expected-note @+1 {{did you mean 'test'?}} func test(a: BadAttributes) -> () { _ = a.exists() // no-warning } @@ -619,7 +618,7 @@ func foo1(bar!=baz) {} // expected-note {{did you mean 'foo1'?}} func foo2(bar! = baz) {}// expected-note {{did you mean 'foo2'?}} // rdar://19605567 -// expected-error@+1{{use of unresolved identifier 'esp'; did you mean 'test'?}} +// expected-error@+1{{use of unresolved identifier 'esp'; did you mean 'exp'?}} switch esp { case let (jeb): // expected-error@+5{{top-level statement cannot begin with a closure expression}} diff --git a/test/SourceKit/Sema/sema_symlink.swift.response b/test/SourceKit/Sema/sema_symlink.swift.response index 87aebf74e748e..782720eee456c 100644 --- a/test/SourceKit/Sema/sema_symlink.swift.response +++ b/test/SourceKit/Sema/sema_symlink.swift.response @@ -12,7 +12,7 @@ key.column: 16, key.filepath: real.swift, key.severity: source.diagnostic.severity.error, - key.description: "use of unresolved identifier 'goo'; did you mean 'Bool'?", + key.description: "use of unresolved identifier 'goo'", key.diagnostic_stage: source.diagnostic.stage.swift.sema, key.ranges: [ { @@ -20,20 +20,27 @@ key.length: 3 } ], - key.fixits: [ - { - key.offset: 15, - key.length: 3, - key.sourcetext: "Bool" - } - ], key.diagnostics: [ { key.line: 1, key.column: 16, key.filepath: real.swift, key.severity: source.diagnostic.severity.note, - key.description: "'Bool' declared here (Swift.Bool)" + key.description: "did you mean 'root'? (Swift.root)" + }, + { + key.line: 1, + key.column: 16, + key.filepath: real.swift, + key.severity: source.diagnostic.severity.note, + key.description: "did you mean 'root'? (Swift.root)" + }, + { + key.line: 1, + key.column: 16, + key.filepath: real.swift, + key.severity: source.diagnostic.severity.note, + key.description: "did you mean 'Bool'? (Swift.Bool)" } ] } diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected index 8b137891791fe..57bbea3d3ca49 100644 --- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected @@ -1 +1,222 @@ +Constructor _StringObject.CountAndFlags.init(count:) has been removed +Constructor _StringObject.CountAndFlags.init(count:isASCII:) has been removed +Func BinaryInteger.addWithOverflow(_:_:) has been removed +Func BinaryInteger.divideWithOverflow(_:_:) has been removed +Func BinaryInteger.multiplyWithOverflow(_:_:) has been removed +Func BinaryInteger.remainderWithOverflow(_:_:) has been removed +Func BinaryInteger.subtractWithOverflow(_:_:) has been removed +Func FixedWidthInteger.<<(_:_:) has been removed +Func FixedWidthInteger.<<=(_:_:) has been removed +Func FixedWidthInteger.>>(_:_:) has been removed +Func FixedWidthInteger.>>=(_:_:) has been removed +Func FixedWidthInteger.addWithOverflow(_:_:) has been removed +Func FixedWidthInteger.divideWithOverflow(_:_:) has been removed +Func FixedWidthInteger.multiplyWithOverflow(_:_:) has been removed +Func FixedWidthInteger.remainderWithOverflow(_:_:) has been removed +Func FixedWidthInteger.subtractWithOverflow(_:_:) has been removed +Func Int.<<(_:_:) has been removed +Func Int.<<=(_:_:) has been removed +Func Int.>>(_:_:) has been removed +Func Int.>>=(_:_:) has been removed +Func Int.toUIntMax() has been removed +Func Int16.<<(_:_:) has been removed +Func Int16.<<=(_:_:) has been removed +Func Int16.>>(_:_:) has been removed +Func Int16.>>=(_:_:) has been removed +Func Int16.toUIntMax() has been removed +Func Int32.<<(_:_:) has been removed +Func Int32.<<=(_:_:) has been removed +Func Int32.>>(_:_:) has been removed +Func Int32.>>=(_:_:) has been removed +Func Int32.toUIntMax() has been removed +Func Int64.<<(_:_:) has been removed +Func Int64.<<=(_:_:) has been removed +Func Int64.>>(_:_:) has been removed +Func Int64.>>=(_:_:) has been removed +Func Int64.toUIntMax() has been removed +Func Int8.<<(_:_:) has been removed +Func Int8.<<=(_:_:) has been removed +Func Int8.>>(_:_:) has been removed +Func Int8.>>=(_:_:) has been removed +Func Int8.toUIntMax() has been removed +Func _StringObject.Nibbles.largeSharedMortal() has been removed +Var _StringGuts.hasNativeStorage has been removed +Var _StringGuts.isNFC has been removed +Var _StringGuts.isNFCFastUTF8 has been removed +Var _StringObject.hasNativeStorage has been removed +Var _StringObject.isNFC has been removed +Var _StringObject.largeFastIsNative has been removed +Var _StringObject.largeFastIsShared has been removed +Var _StringObject.largeIsCocoa has been removed +Var _StringObject.objCBridgeableObject has been removed + +Var _StringObject._countAndFlags is no longer a stored property +Var _StringObject._countAndFlagsBits is added to a non-resilient type + +Class _DictionaryStorage has changed its super class from _RawDictionaryStorage to __RawDictionaryStorage +Class _EmptyDictionarySingleton has been renamed to Class __EmptyDictionarySingleton +Class _EmptyDictionarySingleton has changed its super class from _RawDictionaryStorage to __RawDictionaryStorage +Class _EmptySetSingleton has been renamed to Class __EmptySetSingleton +Class _EmptySetSingleton has changed its super class from _RawSetStorage to __RawSetStorage +Class _RawDictionaryStorage has been renamed to Class __RawDictionaryStorage +Class _RawSetStorage has been renamed to Class __RawSetStorage +Class _SetStorage has changed its super class from _RawSetStorage to __RawSetStorage +Constructor Dictionary._Variant.init(cocoa:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Constructor Dictionary.init(_cocoa:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Constructor Int.init(truncatingBitPattern:) has been removed +Constructor Int16.init(truncatingBitPattern:) has been removed +Constructor Int32.init(truncatingBitPattern:) has been removed +Constructor Int8.init(truncatingBitPattern:) has been removed +Constructor Set._Variant.init(cocoa:) has parameter 0 type change from _CocoaSet to __CocoaSet +Constructor Set.init(_cocoa:) has parameter 0 type change from _CocoaSet to __CocoaSet +Constructor UInt.init(truncatingBitPattern:) has been removed +Constructor UInt16.init(truncatingBitPattern:) has been removed +Constructor UInt32.init(truncatingBitPattern:) has been removed +Constructor UInt8.init(truncatingBitPattern:) has been removed +Constructor _CocoaDictionary.init(_:) has return type change from _CocoaDictionary to __CocoaDictionary +Constructor _CocoaSet.init(_:) has return type change from _CocoaSet to __CocoaSet +Constructor _NativeDictionary.init(_:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Constructor _NativeDictionary.init(_:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage +Constructor _NativeDictionary.init(_:capacity:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Constructor _NativeSet.init(_:) has parameter 0 type change from _CocoaSet to __CocoaSet +Constructor _NativeSet.init(_:) has parameter 0 type change from _RawSetStorage to __RawSetStorage +Constructor _NativeSet.init(_:capacity:) has parameter 0 type change from _CocoaSet to __CocoaSet +Func Set._Variant._migrateToNative(_:removing:) has parameter 0 type change from _CocoaSet to __CocoaSet +Func SignedInteger.&+(_:_:) has been removed +Func SignedInteger.&-(_:_:) has been removed +Func UInt.<<(_:_:) has been removed +Func UInt.<<=(_:_:) has been removed +Func UInt.>>(_:_:) has been removed +Func UInt.>>=(_:_:) has been removed +Func UInt.toIntMax() has been removed +Func UInt16.<<(_:_:) has been removed +Func UInt16.<<=(_:_:) has been removed +Func UInt16.>>(_:_:) has been removed +Func UInt16.>>=(_:_:) has been removed +Func UInt16.toIntMax() has been removed +Func UInt32.<<(_:_:) has been removed +Func UInt32.<<=(_:_:) has been removed +Func UInt32.>>(_:_:) has been removed +Func UInt32.>>=(_:_:) has been removed +Func UInt32.toIntMax() has been removed +Func UInt64.<<(_:_:) has been removed +Func UInt64.<<=(_:_:) has been removed +Func UInt64.>>(_:_:) has been removed +Func UInt64.>>=(_:_:) has been removed +Func UInt64.toIntMax() has been removed +Func UInt8.<<(_:_:) has been removed +Func UInt8.<<=(_:_:) has been removed +Func UInt8.>>(_:_:) has been removed +Func UInt8.>>=(_:_:) has been removed +Func UInt8.toIntMax() has been removed +Func _CocoaDictionary.isEqual(to:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Func _CocoaSet.isEqual(to:) has parameter 0 type change from _CocoaSet to __CocoaSet +Func _DictionaryStorage.convert(_:capacity:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Func _DictionaryStorage.copy(original:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage +Func _DictionaryStorage.resize(original:capacity:move:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage +Func _NativeDictionary.isEqual(to:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary +Func _NativeSet.isEqual(to:) has parameter 0 type change from _CocoaSet to __CocoaSet +Func _SetStorage.convert(_:capacity:) has parameter 0 type change from _CocoaSet to __CocoaSet +Func _SetStorage.copy(original:) has parameter 0 type change from _RawSetStorage to __RawSetStorage +Func _SetStorage.resize(original:capacity:move:) has parameter 0 type change from _RawSetStorage to __RawSetStorage +Struct _CocoaDictionary has been renamed to Struct __CocoaDictionary +Struct _CocoaSet has been renamed to Struct __CocoaSet +Var Dictionary._Variant.asCocoa has declared type change from _CocoaDictionary to __CocoaDictionary +Var Dictionary._Variant.object has declared type change from _BridgeStorage<_RawDictionaryStorage> to _BridgeStorage<__RawDictionaryStorage> +Var Int._sizeInBits has been removed +Var Int._sizeInBytes has been removed +Var Int16._sizeInBits has been removed +Var Int16._sizeInBytes has been removed +Var Int32._sizeInBits has been removed +Var Int32._sizeInBytes has been removed +Var Int64._sizeInBits has been removed +Var Int64._sizeInBytes has been removed +Var Int8._sizeInBits has been removed +Var Int8._sizeInBytes has been removed +Var Set._Variant.asCocoa has declared type change from _CocoaSet to __CocoaSet +Var Set._Variant.object has declared type change from _BridgeStorage<_RawSetStorage> to _BridgeStorage<__RawSetStorage> +Var UInt._sizeInBits has been removed +Var UInt._sizeInBytes has been removed +Var UInt16._sizeInBits has been removed +Var UInt16._sizeInBytes has been removed +Var UInt32._sizeInBits has been removed +Var UInt32._sizeInBytes has been removed +Var UInt64._sizeInBits has been removed +Var UInt64._sizeInBytes has been removed +Var UInt8._sizeInBits has been removed +Var UInt8._sizeInBytes has been removed +Var _CocoaDictionary.Index.dictionary has declared type change from _CocoaDictionary to __CocoaDictionary +Var _NativeDictionary._storage has declared type change from _RawDictionaryStorage to __RawDictionaryStorage +Var _NativeSet._storage has declared type change from _RawSetStorage to __RawSetStorage +Var _RawDictionaryStorage.empty has declared type change from _EmptyDictionarySingleton to __EmptyDictionarySingleton +Var _RawSetStorage.empty has declared type change from _EmptySetSingleton to __EmptySetSingleton + +Func tryReallocateUniquelyReferenced(buffer:newMinimumCapacity:) has been removed + +Protocol SIMD has added inherited protocol Decodable +Protocol SIMD has added inherited protocol Encodable +Protocol SIMD has generic signature change from <τ_0_0 : CustomStringConvertible, τ_0_0 : ExpressibleByArrayLiteral, τ_0_0 : Hashable, τ_0_0 : SIMDStorage, τ_0_0.MaskStorage : SIMD, τ_0_0.MaskStorage.Scalar : FixedWidthInteger, τ_0_0.MaskStorage.Scalar : SignedInteger> to <τ_0_0 : CustomStringConvertible, τ_0_0 : Decodable, τ_0_0 : Encodable, τ_0_0 : ExpressibleByArrayLiteral, τ_0_0 : Hashable, τ_0_0 : SIMDStorage, τ_0_0.MaskStorage : SIMD, τ_0_0.MaskStorage.Scalar : FixedWidthInteger, τ_0_0.MaskStorage.Scalar : SignedInteger> +Protocol SIMDStorage has generic signature change from <τ_0_0.Scalar : Hashable> to <τ_0_0.Scalar : Decodable, τ_0_0.Scalar : Encodable, τ_0_0.Scalar : Hashable> + +Func Sequence.flatMap(_:) has been removed +Subscript String.UnicodeScalarView.subscript(_:) has been removed +Subscript Substring.subscript(_:) has been removed + +Func Collection.makeIterator() has self access kind changing from NonMutating to __Consuming + +Func Sequence.count(where:) has been removed + +Constructor _Pointer.init(_:) has been removed + +Func _cos(_:) has been removed +Func _cos(_:) has been renamed to Func cos(_:) +Func _cos(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _cos(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _cos(_:) has parameter 0 type change from Double to τ_0_0 +Func _cos(_:) has parameter 0 type change from Float to τ_0_0 +Func _cos(_:) has return type change from Double to τ_0_0 +Func _cos(_:) has return type change from Float to τ_0_0 +Func _exp(_:) has been removed +Func _exp(_:) has been renamed to Func exp(_:) +Func _exp(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _exp(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _exp(_:) has parameter 0 type change from Double to τ_0_0 +Func _exp(_:) has parameter 0 type change from Float to τ_0_0 +Func _exp(_:) has return type change from Double to τ_0_0 +Func _exp(_:) has return type change from Float to τ_0_0 +Func _exp2(_:) has been removed +Func _exp2(_:) has been renamed to Func exp2(_:) +Func _exp2(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _exp2(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _exp2(_:) has parameter 0 type change from Double to τ_0_0 +Func _exp2(_:) has parameter 0 type change from Float to τ_0_0 +Func _exp2(_:) has return type change from Double to τ_0_0 +Func _exp2(_:) has return type change from Float to τ_0_0 +Func _log(_:) has been removed +Func _log10(_:) has been removed +Func _log10(_:) has been renamed to Func log10(_:) +Func _log10(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _log10(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _log10(_:) has parameter 0 type change from Double to τ_0_0 +Func _log10(_:) has parameter 0 type change from Float to τ_0_0 +Func _log10(_:) has return type change from Double to τ_0_0 +Func _log10(_:) has return type change from Float to τ_0_0 +Func _log2(_:) has been removed +Func _log2(_:) has been renamed to Func log2(_:) +Func _log2(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _log2(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _log2(_:) has parameter 0 type change from Double to τ_0_0 +Func _log2(_:) has parameter 0 type change from Float to τ_0_0 +Func _log2(_:) has return type change from Double to τ_0_0 +Func _log2(_:) has return type change from Float to τ_0_0 +Func _nearbyint(_:) has been removed +Func _rint(_:) has been removed +Func _sin(_:) has been removed +Func _sin(_:) has been renamed to Func sin(_:) +Func _sin(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> +Func _sin(_:) has generic signature change from to <τ_0_0 where τ_0_0 : SIMD, τ_0_0.Scalar : ElementaryFunctions> +Func _sin(_:) has parameter 0 type change from Double to τ_0_0 +Func _sin(_:) has parameter 0 type change from Float to τ_0_0 +Func _sin(_:) has return type change from Double to τ_0_0 +Func _sin(_:) has return type change from Float to τ_0_0 diff --git a/test/stdlib/tgmath.swift.gyb b/test/stdlib/tgmath.swift.gyb index c3382face8e38..6d233c667ddfd 100644 --- a/test/stdlib/tgmath.swift.gyb +++ b/test/stdlib/tgmath.swift.gyb @@ -18,7 +18,7 @@ // REQUIRES: executable_test #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - import Darwin.C.tgmath + import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) import Glibc #elseif os(Windows) @@ -61,7 +61,7 @@ unary = [ 'cosh', 'sinh', 'tanh', 'exp', 'exp2', 'expm1', 'log', 'log2', 'log1p', 'log10', 'logb', - 'fabs', 'cbrt', 'sqrt', + 'fabs', 'cbrt', 'erf', 'erfc', 'tgamma', 'ceil', 'floor', 'nearbyint', 'rint', 'trunc', @@ -172,6 +172,7 @@ internal extension TGMath { } %for T in ['Float', 'Double', 'CGFloat', 'Float80']: +% Module = 'CoreGraphics' if T == 'CGFloat' else 'Darwin' % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) @@ -182,32 +183,32 @@ internal extension TGMath { extension ${T}: TGMath { % for f in unary: - static func _${f}(_ x: ${T}) -> ${T} { return ${f}(x) } + static func _${f}(_ x: ${T}) -> ${T} { return ${Module}.${f}(x) } % end %for f in binary: - static func _${f}(_ x: ${T}, _ y: ${T}) -> ${T} { return ${f}(x, y) } + static func _${f}(_ x: ${T}, _ y: ${T}) -> ${T} { return ${Module}.${f}(x, y) } %end - static func _remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { return remquo(x, y) } - static func _fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} { return fma(x, y, z) } + static func _remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { return ${Module}.remquo(x, y) } + static func _fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} { return ${Module}.fma(x, y, z) } #if !os(Windows) - static func _lgamma(_ x: ${T}) -> (${T}, Int) { return lgamma(x) } + static func _lgamma(_ x: ${T}) -> (${T}, Int) { return ${Module}.lgamma(x) } #endif - static func _modf(_ x: ${T}) -> (${T}, ${T}) { return modf(x) } - static func _scalbn(_ x: ${T}, _ n: Int) -> ${T} { return scalbn(x, n) } - static func _frexp(_ x: ${T}) -> (${T}, Int) { return frexp(x) } - static func _ilogb(_ x: ${T}) -> Int { return ilogb(x) } + static func _modf(_ x: ${T}) -> (${T}, ${T}) { return ${Module}.modf(x) } + static func _scalbn(_ x: ${T}, _ n: Int) -> ${T} { return ${Module}.scalbn(x, n) } + static func _frexp(_ x: ${T}) -> (${T}, Int) { return ${Module}.frexp(x) } + static func _ilogb(_ x: ${T}) -> Int { return ${Module}.ilogb(x) } } MathTests.test("${T}") { ${T}.allTests() % if T in ['Double','CGFloat']: // Functions that are defined only for Double and CGFloat - expectEqualWithTolerance(0.99750156206604, j0(0.1), ulps: 16) - expectEqualWithTolerance(0.049937526036242, j1(0.1), ulps: 16) - expectEqualWithTolerance(1.2229926610356451e-22, jn(11, 0.1), ulps: 16) - expectEqualWithTolerance(-1.5342386513503667, y0(0.1), ulps: 16) - expectEqualWithTolerance(-6.458951094702027, y1(0.1), ulps: 16) - expectEqualWithTolerance(-2.3662012944869576e+20, yn(11, 0.1), ulps: 16) + expectEqualWithTolerance(0.99750156206604, ${Module}.j0(0.1), ulps: 16) + expectEqualWithTolerance(0.049937526036242, ${Module}.j1(0.1), ulps: 16) + expectEqualWithTolerance(1.2229926610356451e-22, ${Module}.jn(11, 0.1), ulps: 16) + expectEqualWithTolerance(-1.5342386513503667, ${Module}.y0(0.1), ulps: 16) + expectEqualWithTolerance(-6.458951094702027, ${Module}.y1(0.1), ulps: 16) + expectEqualWithTolerance(-2.3662012944869576e+20, ${Module}.yn(11, 0.1), ulps: 16) % end } diff --git a/utils/SwiftMathFunctions.py b/utils/SwiftMathFunctions.py new file mode 100644 index 0000000000000..f8074b9db84ec --- /dev/null +++ b/utils/SwiftMathFunctions.py @@ -0,0 +1,62 @@ +from SwiftFloatingPointTypes import all_floating_point_types + +class SwiftMathFunction(object): + def __init__(self, name, kind=None, swiftName=None, args="x", comment=None, platforms=None): + self.name = name + self.swiftName = swiftName if swiftName is not None else name + self.kind = kind if kind is not None else "library" + self.args = args + self.comment = comment if comment is not None else "/// The " + str(self.swiftName) + " function." + self.platforms = platforms + + def params(self, prefix="", suffix=""): + return ", ".join( + map(lambda a: prefix + a + suffix, self.args) + ) + + def decl(self, type): + return self.swiftName + "(" + self.params("_ ", ": " + type) + ") -> " + type + + def free_decl(self, constraint="T: ElementaryFunctions"): + return self.swiftName + "(" + self.params("_ ", ": T") + ") -> T where " + constraint + + def impl(self, type): + if self.kind == "intrinsic": + builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) + return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" + return "_swift_stdlib_" + self.name + type.cFuncSuffix + "(" + self.params() + ")" + +ElementaryFunctions = [ + SwiftMathFunction(name="sqrt", kind="intrinsic", comment="/// The square root of `x`."), + SwiftMathFunction(name="cos", kind="intrinsic", comment="/// The cosine of `x`."), + SwiftMathFunction(name="sin", kind="intrinsic", comment="/// The sine of `x`."), + SwiftMathFunction(name="tan", comment="/// The tangent of `x`."), + SwiftMathFunction(name="acos"), + SwiftMathFunction(name="asin"), + SwiftMathFunction(name="atan"), + SwiftMathFunction(name="cosh"), + SwiftMathFunction(name="sinh"), + SwiftMathFunction(name="tanh"), + SwiftMathFunction(name="acosh"), + SwiftMathFunction(name="asinh"), + SwiftMathFunction(name="atanh"), + SwiftMathFunction(name="exp", kind="intrinsic"), + SwiftMathFunction(name="exp2", kind="intrinsic"), + SwiftMathFunction(name="exp10"), + SwiftMathFunction(name="expm1"), + SwiftMathFunction(name="log", kind="intrinsic"), + SwiftMathFunction(name="log2", kind="intrinsic"), + SwiftMathFunction(name="log10", kind="intrinsic"), + SwiftMathFunction(name="log1p"), +# SwiftMathFunction(name="pow", kind="intrinsic", args="xy"), Handled separately for edge cases. +# SwiftMathFunction(name="root", args="xn"), Handled separately for implementation. +] + +RealFunctions = [ +# SwiftMathFunction(name="atan2"), Handled separately for explicit arg labels. + SwiftMathFunction(name="erf"), + SwiftMathFunction(name="erfc"), + SwiftMathFunction(name="hypot", args="xy"), + SwiftMathFunction(name="tgamma", swiftName="gamma"), +# SwiftMathFunction(name="lgamma"), Handled separately to handle sign result. +] diff --git a/utils/SwiftMathsFunctions.py b/utils/SwiftMathsFunctions.py deleted file mode 100644 index 9aa6c42550384..0000000000000 --- a/utils/SwiftMathsFunctions.py +++ /dev/null @@ -1,46 +0,0 @@ -from SwiftFloatingPointTypes import all_floating_point_types - -class SwiftMathsFunction(object): - def __init__(self, name, kind=None, swiftName=None, args="x"): - self.name = name - self.swiftName = swiftName if swiftName is not None else name - self.kind = kind if kind is not None else "library" - self.args = args - - def params(self, prefix="", suffix=""): - return ", ".join( - map(lambda a: prefix + a + suffix, self.args) - ) - - def decl(self, type): - return self.swiftName + "(" + self.params("_ ", ": " + type) + ") -> " + type - - def free_decl(self, protocol="Mathsable"): - return self.swiftName + "(" + self.params("_ ", ": T") + ") -> T where T: " + protocol - - def impl(self, type): - if self.kind == "intrinsic": - builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) - return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" - if self.kind == "builtin": - builtin = "Builtin." + self.name + "_FPIEEE" + str(type.bits) - return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" - return "_swift_stdlib_" + self.name + type.cFuncSuffix + "(" + self.params() + ")" - -MathsFunctions = [ - SwiftMathsFunction(name="cos", kind="intrinsic"), - SwiftMathsFunction(name="sin", kind="intrinsic"), - SwiftMathsFunction(name="tan"), - SwiftMathsFunction(name="acos"), - SwiftMathsFunction(name="asin"), - SwiftMathsFunction(name="atan"), - SwiftMathsFunction(name="atan2", args="yx"), - SwiftMathsFunction(name="exp", kind="intrinsic"), - SwiftMathsFunction(name="exp2", kind="intrinsic"), - SwiftMathsFunction(name="log", kind="intrinsic"), - SwiftMathsFunction(name="log10", kind="intrinsic"), - SwiftMathsFunction(name="log2", kind="intrinsic"), - SwiftMathsFunction(name="pow", kind="intrinsic", args="xy"), -] - - From 10fd13196456de9e03949cec35c58e3c3d2a24d0 Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Tue, 2 Apr 2019 17:46:34 -0400 Subject: [PATCH 06/11] Test fixes. --- test/stdlib/MathFunctions.swift.gyb | 168 ++++++++++++++++++++++++++++ test/stdlib/tgmath.swift.gyb | 1 - 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 test/stdlib/MathFunctions.swift.gyb diff --git a/test/stdlib/MathFunctions.swift.gyb b/test/stdlib/MathFunctions.swift.gyb new file mode 100644 index 0000000000000..03d6b8eff91bf --- /dev/null +++ b/test/stdlib/MathFunctions.swift.gyb @@ -0,0 +1,168 @@ +//===--- Math.swift.gyb ---------------------------------------*- swift -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// -*- swift -*- +// RUN: %empty-directory(%t) +// RUN: %gyb %s -o %t/tgmath.swift +// RUN: %line-directive %t/tgmath.swift -- %target-build-swift %t/tgmath.swift -o %t/a.out +// RUN: %target-codesign %t/a.out +// RUN: %line-directive %t/tgmath.swift -- %target-run %t/a.out +// REQUIRES: executable_test + +#if (arch(i386) || arch(x86_64)) && !os(Windows) + typealias TestLiteralType = Float80 +#else + typealias TestLiteralType = Double +#endif + +import StdlibUnittest + +let MathTests = TestSuite("Math") + +func expectEqualWithTolerance(_ expected: TestLiteralType, _ actual: T, + ulps allowed: T = 3, + file: String = #file, line: UInt = #line) + where T: BinaryFloatingPoint { + if actual == T(expected) || actual.isNaN && expected.isNaN { + return + } + // Compute error in ulp, compare to tolerance. + let absoluteError = T(abs(TestLiteralType(actual) - expected)) + let ulpError = absoluteError / T(expected).ulp + expectTrue(ulpError <= allowed, + "\(actual) != \(expected) as \(T.self)" + + "\n \(ulpError)-ulp error exceeds \(allowed)-ulp tolerance.", + file: file, line: line) +} + +%from SwiftMathFunctions import * + +internal extension ElementaryFunctions where Self: BinaryFloatingPoint { + static func elementaryFunctionTests() { + /* Default tolerance is 3 ulps unless specified otherwise. It's OK to relax + * this as needed for new platforms, as these tests are *not* intended to + * validate the math library--they are only intended to check that the + * Swift bindings are calling the right functions in the math library. */ + expectEqualWithTolerance(1.1863995522992575361931268186727044683, Self.acos(0.375)) + expectEqualWithTolerance(0.3843967744956390830381948729670469737, Self.asin(0.375)) + expectEqualWithTolerance(0.3587706702705722203959200639264604997, Self.atan(0.375)) + expectEqualWithTolerance(0.9305076219123142911494767922295555080, Self.cos(0.375)) + expectEqualWithTolerance(0.3662725290860475613729093517162641571, Self.sin(0.375)) + expectEqualWithTolerance(0.3936265759256327582294137871012180981, Self.tan(0.375)) + expectEqualWithTolerance(0.4949329230945269058895630995767185785, Self.acosh(1.125)) + expectEqualWithTolerance(0.9670596312833237113713762009167286709, Self.asinh(1.125)) + expectEqualWithTolerance(0.7331685343967135223291211023213964500, Self.atanh(0.625)) + expectEqualWithTolerance(1.0711403467045867672994980155670160493, Self.cosh(0.375)) + expectEqualWithTolerance(0.3838510679136145687542956764205024589, Self.sinh(0.375)) + expectEqualWithTolerance(0.3583573983507859463193602315531580424, Self.tanh(0.375)) + expectEqualWithTolerance(1.4549914146182013360537936919875185083, Self.exp(0.375)) + expectEqualWithTolerance(1.2968395546510096659337541177924511598, Self.exp2(0.375)) + expectEqualWithTolerance(2.3713737056616552616517527574788898386, Self.exp10(0.375)) + expectEqualWithTolerance(0.4549914146182013360537936919875185083, Self.expm1(0.375)) + expectEqualWithTolerance(-0.980829253011726236856451127452003999, Self.log(0.375)) + expectEqualWithTolerance(-1.415037499278843818546261056052183491, Self.log2(0.375)) + expectEqualWithTolerance(0.3184537311185346158102472135905995955, Self.log1p(0.375)) + expectEqualWithTolerance(-0.425968732272281148346188780918363771, Self.log10(0.375)) + expectEqualWithTolerance(0.7211247851537041911608191553900547941, Self.root(0.375, 3)) + expectEqualWithTolerance(0.6123724356957945245493210186764728479, Self.sqrt(0.375)) + expectEqualWithTolerance(0.54171335479545025876069682133938570, Self.pow(0.375, 0.625)) + expectEqualWithTolerance(-0.052734375, Self.pow(-0.375, 3)) + + expectEqual(Self.acos(0.375), acos(0.375)) + expectEqual(Self.asin(0.375), asin(0.375)) + expectEqual(Self.atan(0.375), atan(0.375)) + expectEqual(Self.cos(0.375), cos(0.375)) + expectEqual(Self.sin(0.375), sin(0.375)) + expectEqual(Self.tan(0.375), tan(0.375)) + expectEqual(Self.acosh(1.125), acosh(1.125)) + expectEqual(Self.asinh(1.125), asinh(1.125)) + expectEqual(Self.atanh(0.625), atanh(0.625)) + expectEqual(Self.cosh(0.375), cosh(0.375)) + expectEqual(Self.sinh(0.375), sinh(0.375)) + expectEqual(Self.tanh(0.375), tanh(0.375)) + expectEqual(Self.exp(0.375), exp(0.375)) + expectEqual(Self.exp2(0.375), exp2(0.375)) + expectEqual(Self.exp10(0.375), exp10(0.375)) + expectEqual(Self.expm1(0.375), expm1(0.375)) + expectEqual(Self.log(0.375), log(0.375)) + expectEqual(Self.log2(0.375), log2(0.375)) + expectEqual(Self.log1p(0.375), log1p(0.375)) + expectEqual(Self.log10(0.375), log10(0.375)) + expectEqual(Self.sqrt(0.375), sqrt(0.375)) + expectEqual(Self.pow(0.375, 0.625), pow(0.375, 0.625)) + expectEqual(Self.root(0.375, 3), root(0.375, 3)) + expectEqual(Self.pow(-0.375, 3), pow(-0.375, 3)) + } +} + +internal extension Real where Self: BinaryFloatingPoint { + static func realFunctionTests() { + expectEqualWithTolerance(0.54041950027058415544357836460859991, Self.atan2(y: 0.375, x: 0.625)) + expectEqualWithTolerance(0.72886898685566255885926910969319788, Self.hypot(0.375, 0.625)) + expectEqualWithTolerance(0.4041169094348222983238250859191217675, Self.erf(0.375)) + expectEqualWithTolerance(0.5958830905651777016761749140808782324, Self.erfc(0.375)) + expectEqualWithTolerance(2.3704361844166009086464735041766525098, Self.gamma(0.375)) +#if !os(Windows) + expectEqualWithTolerance( -0.11775527074107877445136203331798850, Self.logGamma(1.375), ulps: 16) + expectEqual(.plus, Self.signGamma(1.375)) + expectEqual(.minus, Self.signGamma(-2.375)) +#endif + + expectEqual(Self.atan2(y: 0.375, x: 0.625), atan2(y: 0.375, x: 0.625)) + expectEqual(Self.hypot(0.375, 0.625), hypot(0.375, 0.625)) + expectEqual(Self.erf(0.375), erf(0.375)) + expectEqual(Self.erfc(0.375), erfc(0.375)) + expectEqual(Self.gamma(0.375), gamma(0.375)) +#if !os(Windows) + expectEqual(Self.logGamma(1.375), logGamma(1.375)) + expectEqual(Self.signGamma(1.375), signGamma(1.375)) + expectEqual(Self.signGamma(-2.375), signGamma(-2.375)) +#endif + } +} + +internal extension BinaryFloatingPoint { + static func floatingPointFunctionTests() { + expectEqual(1 as Self, ceil(0.375)) + expectEqual(0 as Self, floor(0.375)) + expectEqual(0 as Self, Swift.round(0.375)) + expectEqual(0 as Self, trunc(0.375)) + expectEqual(0 as Self, ceil(-0.625)) + expectEqual(-1 as Self, floor(-0.625)) + expectEqual(-1 as Self, Swift.round(-0.625)) + expectEqual(0 as Self, trunc(-0.625)) + expectEqual(1 as Self, ceil(0.5)) + expectEqual(0 as Self, floor(0.5)) + expectEqual(1 as Self, Swift.round(0.5)) + expectEqual(0 as Self, trunc(0.5)) + } +} + +%for T in ['Float', 'Double', 'CGFloat', 'Float80']: +% if T == 'Float80': +#if (arch(i386) || arch(x86_64)) && !os(Windows) +% elif T == 'CGFloat': +#if canImport(CoreGraphics) + import CoreGraphics +% end + +MathTests.test("${T}") { + ${T}.elementaryFunctionTests() + ${T}.realFunctionTests() + ${T}.floatingPointFunctionTests() +} + +% if T in ['CGFloat', 'Float80']: +#endif +% end +%end + +runAllTests() diff --git a/test/stdlib/tgmath.swift.gyb b/test/stdlib/tgmath.swift.gyb index 6d233c667ddfd..b4b7f123cab61 100644 --- a/test/stdlib/tgmath.swift.gyb +++ b/test/stdlib/tgmath.swift.gyb @@ -118,7 +118,6 @@ internal extension TGMath { expectEqual(-2, Self._logb(0.375)) expectEqual(0.375, Self._fabs(-0.375)) expectEqualWithTolerance(0.7211247851537041911608191553900547941, Self._cbrt(0.375)) - expectEqualWithTolerance(0.6123724356957945245493210186764728479, Self._sqrt(0.375)) expectEqualWithTolerance(0.4041169094348222983238250859191217675, Self._erf(0.375)) expectEqualWithTolerance(0.5958830905651777016761749140808782324, Self._erfc(0.375)) expectEqualWithTolerance(2.3704361844166009086464735041766525098, Self._tgamma(0.375)) From 42abd7f4944d436e1157f0646239be5571aab6a3 Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 3 Apr 2019 08:10:32 -0400 Subject: [PATCH 07/11] update stability-stdlib-abi.swift.expected to match new baseline --- .../stability-stdlib-abi.swift.expected | 171 ------------------ 1 file changed, 171 deletions(-) diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected index 57bbea3d3ca49..345e89537256c 100644 --- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected @@ -1,174 +1,3 @@ -Constructor _StringObject.CountAndFlags.init(count:) has been removed -Constructor _StringObject.CountAndFlags.init(count:isASCII:) has been removed -Func BinaryInteger.addWithOverflow(_:_:) has been removed -Func BinaryInteger.divideWithOverflow(_:_:) has been removed -Func BinaryInteger.multiplyWithOverflow(_:_:) has been removed -Func BinaryInteger.remainderWithOverflow(_:_:) has been removed -Func BinaryInteger.subtractWithOverflow(_:_:) has been removed -Func FixedWidthInteger.<<(_:_:) has been removed -Func FixedWidthInteger.<<=(_:_:) has been removed -Func FixedWidthInteger.>>(_:_:) has been removed -Func FixedWidthInteger.>>=(_:_:) has been removed -Func FixedWidthInteger.addWithOverflow(_:_:) has been removed -Func FixedWidthInteger.divideWithOverflow(_:_:) has been removed -Func FixedWidthInteger.multiplyWithOverflow(_:_:) has been removed -Func FixedWidthInteger.remainderWithOverflow(_:_:) has been removed -Func FixedWidthInteger.subtractWithOverflow(_:_:) has been removed -Func Int.<<(_:_:) has been removed -Func Int.<<=(_:_:) has been removed -Func Int.>>(_:_:) has been removed -Func Int.>>=(_:_:) has been removed -Func Int.toUIntMax() has been removed -Func Int16.<<(_:_:) has been removed -Func Int16.<<=(_:_:) has been removed -Func Int16.>>(_:_:) has been removed -Func Int16.>>=(_:_:) has been removed -Func Int16.toUIntMax() has been removed -Func Int32.<<(_:_:) has been removed -Func Int32.<<=(_:_:) has been removed -Func Int32.>>(_:_:) has been removed -Func Int32.>>=(_:_:) has been removed -Func Int32.toUIntMax() has been removed -Func Int64.<<(_:_:) has been removed -Func Int64.<<=(_:_:) has been removed -Func Int64.>>(_:_:) has been removed -Func Int64.>>=(_:_:) has been removed -Func Int64.toUIntMax() has been removed -Func Int8.<<(_:_:) has been removed -Func Int8.<<=(_:_:) has been removed -Func Int8.>>(_:_:) has been removed -Func Int8.>>=(_:_:) has been removed -Func Int8.toUIntMax() has been removed -Func _StringObject.Nibbles.largeSharedMortal() has been removed -Var _StringGuts.hasNativeStorage has been removed -Var _StringGuts.isNFC has been removed -Var _StringGuts.isNFCFastUTF8 has been removed -Var _StringObject.hasNativeStorage has been removed -Var _StringObject.isNFC has been removed -Var _StringObject.largeFastIsNative has been removed - -Var _StringObject.largeFastIsShared has been removed -Var _StringObject.largeIsCocoa has been removed -Var _StringObject.objCBridgeableObject has been removed - -Var _StringObject._countAndFlags is no longer a stored property -Var _StringObject._countAndFlagsBits is added to a non-resilient type - -Class _DictionaryStorage has changed its super class from _RawDictionaryStorage to __RawDictionaryStorage -Class _EmptyDictionarySingleton has been renamed to Class __EmptyDictionarySingleton -Class _EmptyDictionarySingleton has changed its super class from _RawDictionaryStorage to __RawDictionaryStorage -Class _EmptySetSingleton has been renamed to Class __EmptySetSingleton -Class _EmptySetSingleton has changed its super class from _RawSetStorage to __RawSetStorage -Class _RawDictionaryStorage has been renamed to Class __RawDictionaryStorage -Class _RawSetStorage has been renamed to Class __RawSetStorage -Class _SetStorage has changed its super class from _RawSetStorage to __RawSetStorage -Constructor Dictionary._Variant.init(cocoa:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Constructor Dictionary.init(_cocoa:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Constructor Int.init(truncatingBitPattern:) has been removed -Constructor Int16.init(truncatingBitPattern:) has been removed -Constructor Int32.init(truncatingBitPattern:) has been removed -Constructor Int8.init(truncatingBitPattern:) has been removed -Constructor Set._Variant.init(cocoa:) has parameter 0 type change from _CocoaSet to __CocoaSet -Constructor Set.init(_cocoa:) has parameter 0 type change from _CocoaSet to __CocoaSet -Constructor UInt.init(truncatingBitPattern:) has been removed -Constructor UInt16.init(truncatingBitPattern:) has been removed -Constructor UInt32.init(truncatingBitPattern:) has been removed -Constructor UInt8.init(truncatingBitPattern:) has been removed -Constructor _CocoaDictionary.init(_:) has return type change from _CocoaDictionary to __CocoaDictionary -Constructor _CocoaSet.init(_:) has return type change from _CocoaSet to __CocoaSet -Constructor _NativeDictionary.init(_:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Constructor _NativeDictionary.init(_:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage -Constructor _NativeDictionary.init(_:capacity:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Constructor _NativeSet.init(_:) has parameter 0 type change from _CocoaSet to __CocoaSet -Constructor _NativeSet.init(_:) has parameter 0 type change from _RawSetStorage to __RawSetStorage -Constructor _NativeSet.init(_:capacity:) has parameter 0 type change from _CocoaSet to __CocoaSet -Func Set._Variant._migrateToNative(_:removing:) has parameter 0 type change from _CocoaSet to __CocoaSet -Func SignedInteger.&+(_:_:) has been removed -Func SignedInteger.&-(_:_:) has been removed -Func UInt.<<(_:_:) has been removed -Func UInt.<<=(_:_:) has been removed -Func UInt.>>(_:_:) has been removed -Func UInt.>>=(_:_:) has been removed -Func UInt.toIntMax() has been removed -Func UInt16.<<(_:_:) has been removed -Func UInt16.<<=(_:_:) has been removed -Func UInt16.>>(_:_:) has been removed -Func UInt16.>>=(_:_:) has been removed -Func UInt16.toIntMax() has been removed -Func UInt32.<<(_:_:) has been removed -Func UInt32.<<=(_:_:) has been removed -Func UInt32.>>(_:_:) has been removed -Func UInt32.>>=(_:_:) has been removed -Func UInt32.toIntMax() has been removed -Func UInt64.<<(_:_:) has been removed -Func UInt64.<<=(_:_:) has been removed -Func UInt64.>>(_:_:) has been removed -Func UInt64.>>=(_:_:) has been removed -Func UInt64.toIntMax() has been removed -Func UInt8.<<(_:_:) has been removed -Func UInt8.<<=(_:_:) has been removed -Func UInt8.>>(_:_:) has been removed -Func UInt8.>>=(_:_:) has been removed -Func UInt8.toIntMax() has been removed -Func _CocoaDictionary.isEqual(to:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Func _CocoaSet.isEqual(to:) has parameter 0 type change from _CocoaSet to __CocoaSet -Func _DictionaryStorage.convert(_:capacity:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Func _DictionaryStorage.copy(original:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage -Func _DictionaryStorage.resize(original:capacity:move:) has parameter 0 type change from _RawDictionaryStorage to __RawDictionaryStorage -Func _NativeDictionary.isEqual(to:) has parameter 0 type change from _CocoaDictionary to __CocoaDictionary -Func _NativeSet.isEqual(to:) has parameter 0 type change from _CocoaSet to __CocoaSet -Func _SetStorage.convert(_:capacity:) has parameter 0 type change from _CocoaSet to __CocoaSet -Func _SetStorage.copy(original:) has parameter 0 type change from _RawSetStorage to __RawSetStorage -Func _SetStorage.resize(original:capacity:move:) has parameter 0 type change from _RawSetStorage to __RawSetStorage -Struct _CocoaDictionary has been renamed to Struct __CocoaDictionary -Struct _CocoaSet has been renamed to Struct __CocoaSet -Var Dictionary._Variant.asCocoa has declared type change from _CocoaDictionary to __CocoaDictionary -Var Dictionary._Variant.object has declared type change from _BridgeStorage<_RawDictionaryStorage> to _BridgeStorage<__RawDictionaryStorage> -Var Int._sizeInBits has been removed -Var Int._sizeInBytes has been removed -Var Int16._sizeInBits has been removed -Var Int16._sizeInBytes has been removed -Var Int32._sizeInBits has been removed -Var Int32._sizeInBytes has been removed -Var Int64._sizeInBits has been removed -Var Int64._sizeInBytes has been removed -Var Int8._sizeInBits has been removed -Var Int8._sizeInBytes has been removed -Var Set._Variant.asCocoa has declared type change from _CocoaSet to __CocoaSet -Var Set._Variant.object has declared type change from _BridgeStorage<_RawSetStorage> to _BridgeStorage<__RawSetStorage> -Var UInt._sizeInBits has been removed -Var UInt._sizeInBytes has been removed -Var UInt16._sizeInBits has been removed -Var UInt16._sizeInBytes has been removed -Var UInt32._sizeInBits has been removed -Var UInt32._sizeInBytes has been removed -Var UInt64._sizeInBits has been removed -Var UInt64._sizeInBytes has been removed -Var UInt8._sizeInBits has been removed -Var UInt8._sizeInBytes has been removed -Var _CocoaDictionary.Index.dictionary has declared type change from _CocoaDictionary to __CocoaDictionary -Var _NativeDictionary._storage has declared type change from _RawDictionaryStorage to __RawDictionaryStorage -Var _NativeSet._storage has declared type change from _RawSetStorage to __RawSetStorage -Var _RawDictionaryStorage.empty has declared type change from _EmptyDictionarySingleton to __EmptyDictionarySingleton -Var _RawSetStorage.empty has declared type change from _EmptySetSingleton to __EmptySetSingleton - -Func tryReallocateUniquelyReferenced(buffer:newMinimumCapacity:) has been removed - -Protocol SIMD has added inherited protocol Decodable -Protocol SIMD has added inherited protocol Encodable -Protocol SIMD has generic signature change from <τ_0_0 : CustomStringConvertible, τ_0_0 : ExpressibleByArrayLiteral, τ_0_0 : Hashable, τ_0_0 : SIMDStorage, τ_0_0.MaskStorage : SIMD, τ_0_0.MaskStorage.Scalar : FixedWidthInteger, τ_0_0.MaskStorage.Scalar : SignedInteger> to <τ_0_0 : CustomStringConvertible, τ_0_0 : Decodable, τ_0_0 : Encodable, τ_0_0 : ExpressibleByArrayLiteral, τ_0_0 : Hashable, τ_0_0 : SIMDStorage, τ_0_0.MaskStorage : SIMD, τ_0_0.MaskStorage.Scalar : FixedWidthInteger, τ_0_0.MaskStorage.Scalar : SignedInteger> -Protocol SIMDStorage has generic signature change from <τ_0_0.Scalar : Hashable> to <τ_0_0.Scalar : Decodable, τ_0_0.Scalar : Encodable, τ_0_0.Scalar : Hashable> - -Func Sequence.flatMap(_:) has been removed -Subscript String.UnicodeScalarView.subscript(_:) has been removed -Subscript Substring.subscript(_:) has been removed - -Func Collection.makeIterator() has self access kind changing from NonMutating to __Consuming - -Func Sequence.count(where:) has been removed - -Constructor _Pointer.init(_:) has been removed - Func _cos(_:) has been removed Func _cos(_:) has been renamed to Func cos(_:) Func _cos(_:) has generic signature change from to <τ_0_0 where τ_0_0 : ElementaryFunctions> From 0c7c1f0365d9be11111037f9867b54ab3517f41e Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 3 Apr 2019 08:17:05 -0400 Subject: [PATCH 08/11] Update tgmath.swift.gyb to work with Glibc and MSVCRT. --- test/stdlib/tgmath.swift.gyb | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/test/stdlib/tgmath.swift.gyb b/test/stdlib/tgmath.swift.gyb index b4b7f123cab61..e66c7ca0354f0 100644 --- a/test/stdlib/tgmath.swift.gyb +++ b/test/stdlib/tgmath.swift.gyb @@ -171,7 +171,6 @@ internal extension TGMath { } %for T in ['Float', 'Double', 'CGFloat', 'Float80']: -% Module = 'CoreGraphics' if T == 'CGFloat' else 'Darwin' % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) @@ -181,6 +180,8 @@ internal extension TGMath { % end extension ${T}: TGMath { +#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +% Module = 'CoreGraphics' if T == 'CGFloat' else 'Darwin' % for f in unary: static func _${f}(_ x: ${T}) -> ${T} { return ${Module}.${f}(x) } % end @@ -189,13 +190,39 @@ extension ${T}: TGMath { %end static func _remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { return ${Module}.remquo(x, y) } static func _fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} { return ${Module}.fma(x, y, z) } -#if !os(Windows) static func _lgamma(_ x: ${T}) -> (${T}, Int) { return ${Module}.lgamma(x) } -#endif static func _modf(_ x: ${T}) -> (${T}, ${T}) { return ${Module}.modf(x) } static func _scalbn(_ x: ${T}, _ n: Int) -> ${T} { return ${Module}.scalbn(x, n) } static func _frexp(_ x: ${T}) -> (${T}, Int) { return ${Module}.frexp(x) } static func _ilogb(_ x: ${T}) -> Int { return ${Module}.ilogb(x) } +#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) +% for f in unary: + static func _${f}(_ x: ${T}) -> ${T} { return Glibc.${f}(x) } +% end +%for f in binary: + static func _${f}(_ x: ${T}, _ y: ${T}) -> ${T} { return Glibc.${f}(x, y) } +%end + static func _remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { return Glibc.remquo(x, y) } + static func _fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} { return Glibc.fma(x, y, z) } + static func _lgamma(_ x: ${T}) -> (${T}, Int) { return Glibc.lgamma(x) } + static func _modf(_ x: ${T}) -> (${T}, ${T}) { return Glibc.modf(x) } + static func _scalbn(_ x: ${T}, _ n: Int) -> ${T} { return Glibc.scalbn(x, n) } + static func _frexp(_ x: ${T}) -> (${T}, Int) { return Glibc.frexp(x) } + static func _ilogb(_ x: ${T}) -> Int { return Glibc.ilogb(x) } +#elseif os(Windows) +% for f in unary: + static func _${f}(_ x: ${T}) -> ${T} { return MSVCRT.${f}(x) } +% end +%for f in binary: + static func _${f}(_ x: ${T}, _ y: ${T}) -> ${T} { return MSVCRT.${f}(x, y) } +%end + static func _remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { return MSVCRT.remquo(x, y) } + static func _fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} { return MSVCRT.fma(x, y, z) } + static func _modf(_ x: ${T}) -> (${T}, ${T}) { return MSVCRT.modf(x) } + static func _scalbn(_ x: ${T}, _ n: Int) -> ${T} { return MSVCRT.scalbn(x, n) } + static func _frexp(_ x: ${T}) -> (${T}, Int) { return MSVCRT.frexp(x) } + static func _ilogb(_ x: ${T}) -> Int { return MSVCRT.ilogb(x) } +#endif } MathTests.test("${T}") { From 2bc6040556db7b07d8ed35929ab33e015dfe21db Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 3 Apr 2019 09:32:44 -0400 Subject: [PATCH 09/11] More test fixup for Linux. --- test/stdlib/tgmath.swift.gyb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/stdlib/tgmath.swift.gyb b/test/stdlib/tgmath.swift.gyb index e66c7ca0354f0..91748cbe6bf99 100644 --- a/test/stdlib/tgmath.swift.gyb +++ b/test/stdlib/tgmath.swift.gyb @@ -229,12 +229,12 @@ MathTests.test("${T}") { ${T}.allTests() % if T in ['Double','CGFloat']: // Functions that are defined only for Double and CGFloat - expectEqualWithTolerance(0.99750156206604, ${Module}.j0(0.1), ulps: 16) - expectEqualWithTolerance(0.049937526036242, ${Module}.j1(0.1), ulps: 16) - expectEqualWithTolerance(1.2229926610356451e-22, ${Module}.jn(11, 0.1), ulps: 16) - expectEqualWithTolerance(-1.5342386513503667, ${Module}.y0(0.1), ulps: 16) - expectEqualWithTolerance(-6.458951094702027, ${Module}.y1(0.1), ulps: 16) - expectEqualWithTolerance(-2.3662012944869576e+20, ${Module}.yn(11, 0.1), ulps: 16) + expectEqualWithTolerance(0.99750156206604, j0(0.1), ulps: 16) + expectEqualWithTolerance(0.049937526036242, j1(0.1), ulps: 16) + expectEqualWithTolerance(1.2229926610356451e-22, jn(11, 0.1), ulps: 16) + expectEqualWithTolerance(-1.5342386513503667, y0(0.1), ulps: 16) + expectEqualWithTolerance(-6.458951094702027, y1(0.1), ulps: 16) + expectEqualWithTolerance(-2.3662012944869576e+20, yn(11, 0.1), ulps: 16) % end } From 45a76fe9f4f57a51079ea6896920af8a4fca4311 Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 3 Apr 2019 09:34:25 -0400 Subject: [PATCH 10/11] fixup IRGen test for exp on linux --- test/IRGen/builtin_math.swift | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/IRGen/builtin_math.swift b/test/IRGen/builtin_math.swift index 1e3dbeacaf378..b1d4afca51c21 100644 --- a/test/IRGen/builtin_math.swift +++ b/test/IRGen/builtin_math.swift @@ -13,13 +13,7 @@ // Make sure we use an intrinsic for functions such as exp. // CHECK-LABEL: define {{.*}}test1 -// CHECK-ios: call float @llvm.exp.f32 -// CHECK-macosx: call float @llvm.exp.f32 -// CHECK-tvos: call float @llvm.exp.f32 -// CHECK-watchos: call float @llvm.exp.f32 -// CHECK-darwin: call float @llvm.exp.f32 -// CHECK-linux-gnu: call float @expf -// CHECK-windows: call float @expf +// CHECK: call float @llvm.exp.f32 public func test1(f : Float) -> Float { return exp(f) From bcc7e2c901d1c159ecbc31dad31ddef1e6faf1ac Mon Sep 17 00:00:00 2001 From: "Steve (Numerics) Canon" Date: Wed, 3 Apr 2019 15:15:28 -0400 Subject: [PATCH 11/11] Obscene rant about linters. --- stdlib/public/core/MathFunctions.swift.gyb | 1 + utils/SwiftMathFunctions.py | 120 +++++++++++---------- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/stdlib/public/core/MathFunctions.swift.gyb b/stdlib/public/core/MathFunctions.swift.gyb index c4a9ccdb9834e..78ca7245b7324 100644 --- a/stdlib/public/core/MathFunctions.swift.gyb +++ b/stdlib/public/core/MathFunctions.swift.gyb @@ -12,6 +12,7 @@ import SwiftShims %from SwiftMathFunctions import * +%from SwiftFloatingPointTypes import all_floating_point_types /// A type that has elementary functions available. /// diff --git a/utils/SwiftMathFunctions.py b/utils/SwiftMathFunctions.py index f8074b9db84ec..c1b82b22e9c6f 100644 --- a/utils/SwiftMathFunctions.py +++ b/utils/SwiftMathFunctions.py @@ -1,62 +1,74 @@ -from SwiftFloatingPointTypes import all_floating_point_types - class SwiftMathFunction(object): - def __init__(self, name, kind=None, swiftName=None, args="x", comment=None, platforms=None): - self.name = name - self.swiftName = swiftName if swiftName is not None else name - self.kind = kind if kind is not None else "library" - self.args = args - self.comment = comment if comment is not None else "/// The " + str(self.swiftName) + " function." - self.platforms = platforms + def __init__(self, name, kind=None, swiftName=None, args="x", comment=None, + platforms=None): + self.name = name + self.swiftName = swiftName if swiftName is not None else name + self.kind = kind if kind is not None else "library" + self.args = args + if comment is not None: + self.comment = comment + else: + self.comment = "/// The " + str(self.swiftName) + " function." + self.platforms = platforms + + def params(self, prefix="", suffix=""): + return ", ".join(map(lambda a: prefix + a + suffix, self.args)) + + def decl(self, type): + return self.swiftName + "(" + self.params("_ ", ": " + type) + \ + ") -> " + type + + def free_decl(self, constraint="T: ElementaryFunctions"): + return self.swiftName + "(" + self.params("_ ", ": T") + \ + ") -> T where " + constraint + + def impl(self, type): + if self.kind == "intrinsic": + builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) + return type.stdlib_name + "(" + builtin + "(" + \ + self.params("", "._value") + "))" + return "_swift_stdlib_" + self.name + type.cFuncSuffix + "(" + \ + self.params() + ")" - def params(self, prefix="", suffix=""): - return ", ".join( - map(lambda a: prefix + a + suffix, self.args) - ) - - def decl(self, type): - return self.swiftName + "(" + self.params("_ ", ": " + type) + ") -> " + type - - def free_decl(self, constraint="T: ElementaryFunctions"): - return self.swiftName + "(" + self.params("_ ", ": T") + ") -> T where " + constraint - - def impl(self, type): - if self.kind == "intrinsic": - builtin = "Builtin.int_" + self.name + "_FPIEEE" + str(type.bits) - return type.stdlib_name + "(" + builtin + "(" + self.params("","._value") + "))" - return "_swift_stdlib_" + self.name + type.cFuncSuffix + "(" + self.params() + ")" ElementaryFunctions = [ - SwiftMathFunction(name="sqrt", kind="intrinsic", comment="/// The square root of `x`."), - SwiftMathFunction(name="cos", kind="intrinsic", comment="/// The cosine of `x`."), - SwiftMathFunction(name="sin", kind="intrinsic", comment="/// The sine of `x`."), - SwiftMathFunction(name="tan", comment="/// The tangent of `x`."), - SwiftMathFunction(name="acos"), - SwiftMathFunction(name="asin"), - SwiftMathFunction(name="atan"), - SwiftMathFunction(name="cosh"), - SwiftMathFunction(name="sinh"), - SwiftMathFunction(name="tanh"), - SwiftMathFunction(name="acosh"), - SwiftMathFunction(name="asinh"), - SwiftMathFunction(name="atanh"), - SwiftMathFunction(name="exp", kind="intrinsic"), - SwiftMathFunction(name="exp2", kind="intrinsic"), - SwiftMathFunction(name="exp10"), - SwiftMathFunction(name="expm1"), - SwiftMathFunction(name="log", kind="intrinsic"), - SwiftMathFunction(name="log2", kind="intrinsic"), - SwiftMathFunction(name="log10", kind="intrinsic"), - SwiftMathFunction(name="log1p"), -# SwiftMathFunction(name="pow", kind="intrinsic", args="xy"), Handled separately for edge cases. -# SwiftMathFunction(name="root", args="xn"), Handled separately for implementation. + SwiftMathFunction(name="sqrt", kind="intrinsic", + comment="/// The square root of `x`."), + SwiftMathFunction(name="cos", kind="intrinsic", + comment="/// The cosine of `x`."), + SwiftMathFunction(name="sin", kind="intrinsic", + comment="/// The sine of `x`."), + SwiftMathFunction(name="tan", + comment="/// The tangent of `x`."), + SwiftMathFunction(name="acos"), + SwiftMathFunction(name="asin"), + SwiftMathFunction(name="atan"), + SwiftMathFunction(name="cosh"), + SwiftMathFunction(name="sinh"), + SwiftMathFunction(name="tanh"), + SwiftMathFunction(name="acosh"), + SwiftMathFunction(name="asinh"), + SwiftMathFunction(name="atanh"), + SwiftMathFunction(name="exp", kind="intrinsic"), + SwiftMathFunction(name="exp2", kind="intrinsic"), + SwiftMathFunction(name="exp10"), + SwiftMathFunction(name="expm1"), + SwiftMathFunction(name="log", kind="intrinsic"), + SwiftMathFunction(name="log2", kind="intrinsic"), + SwiftMathFunction(name="log10", kind="intrinsic"), + SwiftMathFunction(name="log1p"), + # SwiftMathFunction(name="pow", kind="intrinsic", args="xy"), Handled + # separately for edge cases. + # SwiftMathFunction(name="root", args="xn"), Handled separately for + # implementation. ] RealFunctions = [ -# SwiftMathFunction(name="atan2"), Handled separately for explicit arg labels. - SwiftMathFunction(name="erf"), - SwiftMathFunction(name="erfc"), - SwiftMathFunction(name="hypot", args="xy"), - SwiftMathFunction(name="tgamma", swiftName="gamma"), -# SwiftMathFunction(name="lgamma"), Handled separately to handle sign result. + # SwiftMathFunction(name="atan2"), Handled separately for explicit + # argument labels. + SwiftMathFunction(name="erf"), + SwiftMathFunction(name="erfc"), + SwiftMathFunction(name="hypot", args="xy"), + SwiftMathFunction(name="tgamma", swiftName="gamma"), + # SwiftMathFunction(name="lgamma"), Handled separately for sign result. ]