diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp index 124c0e5df7961..b195b67f05fb5 100644 --- a/lib/SIL/SILVerifier.cpp +++ b/lib/SIL/SILVerifier.cpp @@ -3263,7 +3263,7 @@ class SILVerifier : public SILVerifierBase { assert(F->isAvailableExternally() && "external declaration of internal SILFunction not allowed"); assert(!hasSharedVisibility(F->getLinkage()) && - "external declarations of SILFunctions with shared visibility is not " + "external declaration of SILFunction with shared visibility is not " "allowed"); // If F is an external declaration, there is nothing further to do, // return. diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h index a36af96e12d24..48391cf7c1b41 100644 --- a/stdlib/public/SwiftShims/LibcShims.h +++ b/stdlib/public/SwiftShims/LibcShims.h @@ -83,43 +83,63 @@ SWIFT_RUNTIME_STDLIB_INTERFACE __swift_uint32_t _swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound); -// Math library functions -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_remainderf(float, float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_squareRootf(float); +#if defined __APPLE__ +static inline float _swift_stdlib_remainderf(float x, float y) { + return __builtin_remainderf(x, y); +} + +static inline float _swift_stdlib_sqrtf(float x) { + return __builtin_sqrtf(x); +} + +static inline double _swift_stdlib_remainder(double x, double y) { + return __builtin_remainder(x, y); +} + +static inline double _swift_stdlib_sqrt(double x) { + return __builtin_sqrt(x); +} + +# if defined __i386__ || defined __x86_64__ +// We use void* for these because the importer doesn't know how to map Float80 +// to long double. +static inline void _swift_stdlib_remainderl(void *x, const void *y) { + long double *ptr = (long double *)x; + *ptr = __builtin_remainderl(*ptr, *(const long double *)y); +} + +static inline void _swift_stdlib_sqrtl(void *x) { + long double *ptr = (long double *)x; + *ptr = __builtin_sqrtl(*ptr); +} +# endif // defined __i386__ || defined __x86_64__ +#else +// We want the math shims to be static inline for performance reasons, but +// that causes test failures on Linux at present, and depends on a compiler +// feature (__builtin_xxxx) that may not be available on other platforms. +// They are therefore declared as SWIFT_RUNTIME_STDLIB_INTERFACE functions +// on non-Apple platforms for now. SWIFT_RUNTIME_STDLIB_INTERFACE -float _swift_stdlib_addProductf(float, float, float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundf(float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundevenf(float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_truncf(float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundawayf(float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_ceilf(float); -SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_floorf(float); - -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_remainder(double, double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_squareRoot(double); +float _swift_stdlib_remainderf(float x, float y); + SWIFT_RUNTIME_STDLIB_INTERFACE -double _swift_stdlib_addProduct(double, double, double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_round(double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_roundeven(double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_trunc(double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_roundaway(double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_ceil(double); -SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_floor(double); - -// TODO: Remove horrible workaround when importer does Float80 <-> long double. -#if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER +float _swift_stdlib_sqrtf(float x); + SWIFT_RUNTIME_STDLIB_INTERFACE -void _swift_stdlib_remainderl(void *_self, const void *_other); +double _swift_stdlib_remainder(double x, double y); + SWIFT_RUNTIME_STDLIB_INTERFACE -void _swift_stdlib_squareRootl(void *_self); +double _swift_stdlib_sqrt(double x); + +# if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER +// We use void* for these because the importer doesn't know how to map Float80 +// to long double. SWIFT_RUNTIME_STDLIB_INTERFACE -void _swift_stdlib_addProductl(void *_self, const void *_lhs, const void *_rhs); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundl(void *_self); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundevenl(void *_self); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_truncl(void *_self); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundawayl(void *_self); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_ceill(void *_self); -SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_floorl(void *_self); +void _swift_stdlib_remainderl(void *x, const void *y); + +SWIFT_RUNTIME_STDLIB_INTERFACE +void _swift_stdlib_sqrtl(void *x); +# endif // defined __i386__ || defined __x86_64__ #endif #ifdef __cplusplus @@ -127,4 +147,3 @@ SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_floorl(void *_self); #endif #endif // SWIFT_STDLIB_SHIMS_LIBCSHIMS_H - diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb index 8a8740999b79f..33539373cb3be 100644 --- a/stdlib/public/core/FloatingPointTypes.swift.gyb +++ b/stdlib/public/core/FloatingPointTypes.swift.gyb @@ -510,37 +510,30 @@ extension ${Self}: BinaryFloatingPoint { @_transparent public mutating func round(_ rule: FloatingPointRoundingRule) { -%if bits == 80: switch rule { case .toNearestOrAwayFromZero: - _swift_stdlib_roundl(&self) + _value = Builtin.int_round_FPIEEE${bits}(_value) case .toNearestOrEven: - _swift_stdlib_roundevenl(&self) + // TODO: switch to roundeven( ) or corresponding builtin when + // available; rint assumes default floating-point environment. + // This is pretty OK at present, since there's no Swifty way + // to fuss with the environment, but we should fix it in the + // long term. + _value = Builtin.int_rint_FPIEEE${bits}(_value) case .towardZero: - _swift_stdlib_truncl(&self) + _value = Builtin.int_trunc_FPIEEE${bits}(_value) case .awayFromZero: - _swift_stdlib_roundawayl(&self) - case .up: - _swift_stdlib_ceill(&self) - case .down: - _swift_stdlib_floorl(&self) - } -%else: - switch rule { - case .toNearestOrAwayFromZero: - self = _swift_stdlib_round${cFuncSuffix(bits)}(self) - case .toNearestOrEven: - self = _swift_stdlib_roundeven${cFuncSuffix(bits)}(self) - case .towardZero: - self = _swift_stdlib_trunc${cFuncSuffix(bits)}(self) - case .awayFromZero: - self = _swift_stdlib_roundaway${cFuncSuffix(bits)}(self) + if sign == .minus { + _value = Builtin.int_floor_FPIEEE${bits}(_value) + } + else { + _value = Builtin.int_ceil_FPIEEE${bits}(_value) + } case .up: - self = _swift_stdlib_ceil${cFuncSuffix(bits)}(self) + _value = Builtin.int_ceil_FPIEEE${bits}(_value) case .down: - self = _swift_stdlib_floor${cFuncSuffix(bits)}(self) + _value = Builtin.int_floor_FPIEEE${bits}(_value) } -%end } @_transparent @@ -586,21 +579,16 @@ extension ${Self}: BinaryFloatingPoint { @_transparent public mutating func formSquareRoot( ) { %if bits == 80: - _swift_stdlib_squareRootl(&self) + _swift_stdlib_sqrtl(&self) %else: - self = _swift_stdlib_squareRoot${cFuncSuffix(bits)}(self) + self = _swift_stdlib_sqrt${cFuncSuffix(bits)}(self) %end + } @_transparent public mutating func addProduct(_ lhs: ${Self}, _ rhs: ${Self}) { -%if bits == 80: - var lhs = lhs - var rhs = rhs - _swift_stdlib_addProductl(&self, &lhs, &rhs) -%else: - self = _swift_stdlib_addProduct${cFuncSuffix(bits)}(self, lhs, rhs) -%end + _value = Builtin.int_fma_FPIEEE${bits}(lhs._value, rhs._value, _value) } @_transparent diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp index 9b432b1550e12..aba1dee843a81 100644 --- a/stdlib/public/stubs/LibcShims.cpp +++ b/stdlib/public/stubs/LibcShims.cpp @@ -125,104 +125,37 @@ swift::_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound) { return RandomUniform(getGlobalMT19937()); } -float swift::_swift_stdlib_remainderf(float dividend, float divisor) { - return std::remainder(dividend, divisor); +#if !defined __APPLE__ +// These functions are static inline on Apple platforms, and therefore +// function bodies are not needed here. They should ideally be made static +// inlines on other platforms as well. +float swift::_swift_stdlib_remainderf(float x, float y) { + return std::remainder(x, y); } -float swift::_swift_stdlib_squareRootf(float x) { return std::sqrt(x); } - -float swift::_swift_stdlib_addProductf(float addend, float lhs, float rhs) { - return std::fma(lhs, rhs, addend); -} - -float swift::_swift_stdlib_roundf(float x) { return std::round(x); } - -float swift::_swift_stdlib_roundevenf(float x) { - // TODO: switch to roundevenf( ) when available in backing C libraries, or - // open-code here to correctly handle non-default fenv. - return std::rint(x); -} - -float swift::_swift_stdlib_truncf(float x) { return std::trunc(x); } - -float swift::_swift_stdlib_roundawayf(float x) { - // No corresponding C function, but trivial to fake. - return x < 0 ? std::floor(x) : std::ceil(x); -} - -float swift::_swift_stdlib_ceilf(float x) { return std::ceil(x); } - -float swift::_swift_stdlib_floorf(float x) { return std::floor(x); } - -double swift::_swift_stdlib_remainder(double dividend, double divisor) { - return std::remainder(dividend, divisor); -} - -double swift::_swift_stdlib_squareRoot(double x) { return std::sqrt(x); } - -double swift::_swift_stdlib_addProduct(double addend, double lhs, double rhs) { - return std::fma(lhs, rhs, addend); -} - -double swift::_swift_stdlib_round(double x) { return std::round(x); } - -double swift::_swift_stdlib_roundeven(double x) { - // TODO: switch to roundevenf( ) when available in backing C libraries, or - // open-code here to correctly handle non-default fenv. - return std::rint(x); -} - -double swift::_swift_stdlib_trunc(double x) { return std::trunc(x); } - -double swift::_swift_stdlib_roundaway(double x) { - // No corresponding C function, but trivial to fake. - return x < 0 ? std::floor(x) : std::ceil(x); -} - -double swift::_swift_stdlib_ceil(double x) { return std::ceil(x); } - -double swift::_swift_stdlib_floor(double x) { return std::floor(x); } - -#if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER -void swift::_swift_stdlib_remainderl(void *_self, const void *_other) { - *(long double *)_self = std::remainder(*(long double *)_self, - *(const long double *)_other); -} - -void swift::_swift_stdlib_squareRootl(void *_self) { - *(long double *)_self = std::sqrt(*(long double *)_self); -} - -void -swift::_swift_stdlib_addProductl(void *_self, - const void *_lhs, const void *_rhs) { - *(long double *)_self = std::fma(*(const long double *)_lhs, - *(const long double *)_rhs, - *(long double *)_self); -} - -void swift::_swift_stdlib_roundl(void *_self) { - *(long double *)_self = std::round(*(long double *)_self); -} - -void swift::_swift_stdlib_roundevenl(void *_self) { - *(long double *)_self = std::rint(*(long double *)_self); +float swift::_swift_stdlib_sqrtf(float x) { + return std::sqrt(x); } -void swift::_swift_stdlib_truncl(void *_self) { - *(long double *)_self = std::trunc(*(long double *)_self); +double swift::_swift_stdlib_remainder(double x, double y) { + return std::remainder(x, y); } -void swift::_swift_stdlib_roundawayl(void *_self) { - long double *ptr = (long double *)_self; - *ptr = *ptr < 0 ? std::floor(*ptr) : std::ceil(*ptr); +double swift::_swift_stdlib_sqrt(double x) { + return std::sqrt(x); } -void swift::_swift_stdlib_ceill(void *_self) { - *(long double *)_self = std::ceil(*(long double *)_self); +# if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER +// We use void* for these because the importer doesn't know how to map Float80 +// to long double. +void swift::_swift_stdlib_remainderl(void *x, const void *y) { + long double *ptr = (long double *)x; + *ptr = std::remainder(*ptr, *(const long double *)y); } -void swift::_swift_stdlib_floorl(void *_self) { - *(long double *)_self = std::floor(*(long double *)_self); +void swift::_swift_stdlib_sqrtl(void *x) { + long double *ptr = (long double *)x; + *ptr = std::sqrt(*ptr); } -#endif // Have Float80 +# endif +#endif // !defined __APPLE__