Skip to content

Commit 5564f94

Browse files
stephentyroneatrick
authored andcommitted
Intrinsics instead of shims (#3530)
* Use intrinsics instead of Libc stubs where we can. This replaces most of the stubs used for basic operations on these types with intrinsics, eliminating a level of indirection for fma, ceil, floor, round, trunc. square root and remainder still require stubs because there is no remainder intrinsic and we can't use the square root intrinsic because its behavior is undefined for negative inputs. A previous commit apparently either the compiler annotates static inline stubs wrong or the SIL verifier can't handle them, so that change was backed out. * Explicitly CHECK-NOT @llvm.sqrt instead of looking for @sqrt.
1 parent e0ca8fb commit 5564f94

File tree

4 files changed

+16
-135
lines changed

4 files changed

+16
-135
lines changed

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,40 +86,16 @@ _swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound);
8686
// Math library functions
8787
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_remainderf(float, float);
8888
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_squareRootf(float);
89-
SWIFT_RUNTIME_STDLIB_INTERFACE
90-
float _swift_stdlib_addProductf(float, float, float);
91-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundf(float);
92-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundevenf(float);
93-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_truncf(float);
94-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_roundawayf(float);
95-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_ceilf(float);
96-
SWIFT_RUNTIME_STDLIB_INTERFACE float _swift_stdlib_floorf(float);
9789

9890
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_remainder(double, double);
9991
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_squareRoot(double);
100-
SWIFT_RUNTIME_STDLIB_INTERFACE
101-
double _swift_stdlib_addProduct(double, double, double);
102-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_round(double);
103-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_roundeven(double);
104-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_trunc(double);
105-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_roundaway(double);
106-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_ceil(double);
107-
SWIFT_RUNTIME_STDLIB_INTERFACE double _swift_stdlib_floor(double);
10892

10993
// TODO: Remove horrible workaround when importer does Float80 <-> long double.
11094
#if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER
11195
SWIFT_RUNTIME_STDLIB_INTERFACE
11296
void _swift_stdlib_remainderl(void *_self, const void *_other);
11397
SWIFT_RUNTIME_STDLIB_INTERFACE
11498
void _swift_stdlib_squareRootl(void *_self);
115-
SWIFT_RUNTIME_STDLIB_INTERFACE
116-
void _swift_stdlib_addProductl(void *_self, const void *_lhs, const void *_rhs);
117-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundl(void *_self);
118-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundevenl(void *_self);
119-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_truncl(void *_self);
120-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_roundawayl(void *_self);
121-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_ceill(void *_self);
122-
SWIFT_RUNTIME_STDLIB_INTERFACE void _swift_stdlib_floorl(void *_self);
12399
#endif
124100

125101
#ifdef __cplusplus

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -510,37 +510,25 @@ extension ${Self}: BinaryFloatingPoint {
510510

511511
@_transparent
512512
public mutating func round(_ rule: FloatingPointRoundingRule) {
513-
%if bits == 80:
514-
switch rule {
515-
case .toNearestOrAwayFromZero:
516-
_swift_stdlib_roundl(&self)
517-
case .toNearestOrEven:
518-
_swift_stdlib_roundevenl(&self)
519-
case .towardZero:
520-
_swift_stdlib_truncl(&self)
521-
case .awayFromZero:
522-
_swift_stdlib_roundawayl(&self)
523-
case .up:
524-
_swift_stdlib_ceill(&self)
525-
case .down:
526-
_swift_stdlib_floorl(&self)
527-
}
528-
%else:
529513
switch rule {
530514
case .toNearestOrAwayFromZero:
531-
self = _swift_stdlib_round${cFuncSuffix(bits)}(self)
515+
_value = Builtin.int_round_FPIEEE${bits}(_value)
532516
case .toNearestOrEven:
533-
self = _swift_stdlib_roundeven${cFuncSuffix(bits)}(self)
517+
_value = Builtin.int_rint_FPIEEE${bits}(_value)
534518
case .towardZero:
535-
self = _swift_stdlib_trunc${cFuncSuffix(bits)}(self)
519+
_value = Builtin.int_trunc_FPIEEE${bits}(_value)
536520
case .awayFromZero:
537-
self = _swift_stdlib_roundaway${cFuncSuffix(bits)}(self)
521+
if sign == .minus {
522+
_value = Builtin.int_floor_FPIEEE${bits}(_value)
523+
}
524+
else {
525+
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
526+
}
538527
case .up:
539-
self = _swift_stdlib_ceil${cFuncSuffix(bits)}(self)
528+
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
540529
case .down:
541-
self = _swift_stdlib_floor${cFuncSuffix(bits)}(self)
530+
_value = Builtin.int_floor_FPIEEE${bits}(_value)
542531
}
543-
%end
544532
}
545533

546534
@_transparent
@@ -594,13 +582,7 @@ extension ${Self}: BinaryFloatingPoint {
594582

595583
@_transparent
596584
public mutating func addProduct(_ lhs: ${Self}, _ rhs: ${Self}) {
597-
%if bits == 80:
598-
var lhs = lhs
599-
var rhs = rhs
600-
_swift_stdlib_addProductl(&self, &lhs, &rhs)
601-
%else:
602-
self = _swift_stdlib_addProduct${cFuncSuffix(bits)}(self, lhs, rhs)
603-
%end
585+
_value = Builtin.int_fma_FPIEEE${bits}(lhs._value, rhs._value, _value)
604586
}
605587

606588
@_transparent

stdlib/public/stubs/LibcShims.cpp

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -131,58 +131,12 @@ float swift::_swift_stdlib_remainderf(float dividend, float divisor) {
131131

132132
float swift::_swift_stdlib_squareRootf(float x) { return std::sqrt(x); }
133133

134-
float swift::_swift_stdlib_addProductf(float addend, float lhs, float rhs) {
135-
return std::fma(lhs, rhs, addend);
136-
}
137-
138-
float swift::_swift_stdlib_roundf(float x) { return std::round(x); }
139-
140-
float swift::_swift_stdlib_roundevenf(float x) {
141-
// TODO: switch to roundevenf( ) when available in backing C libraries, or
142-
// open-code here to correctly handle non-default fenv.
143-
return std::rint(x);
144-
}
145-
146-
float swift::_swift_stdlib_truncf(float x) { return std::trunc(x); }
147-
148-
float swift::_swift_stdlib_roundawayf(float x) {
149-
// No corresponding C function, but trivial to fake.
150-
return x < 0 ? std::floor(x) : std::ceil(x);
151-
}
152-
153-
float swift::_swift_stdlib_ceilf(float x) { return std::ceil(x); }
154-
155-
float swift::_swift_stdlib_floorf(float x) { return std::floor(x); }
156-
157134
double swift::_swift_stdlib_remainder(double dividend, double divisor) {
158135
return std::remainder(dividend, divisor);
159136
}
160137

161138
double swift::_swift_stdlib_squareRoot(double x) { return std::sqrt(x); }
162139

163-
double swift::_swift_stdlib_addProduct(double addend, double lhs, double rhs) {
164-
return std::fma(lhs, rhs, addend);
165-
}
166-
167-
double swift::_swift_stdlib_round(double x) { return std::round(x); }
168-
169-
double swift::_swift_stdlib_roundeven(double x) {
170-
// TODO: switch to roundevenf( ) when available in backing C libraries, or
171-
// open-code here to correctly handle non-default fenv.
172-
return std::rint(x);
173-
}
174-
175-
double swift::_swift_stdlib_trunc(double x) { return std::trunc(x); }
176-
177-
double swift::_swift_stdlib_roundaway(double x) {
178-
// No corresponding C function, but trivial to fake.
179-
return x < 0 ? std::floor(x) : std::ceil(x);
180-
}
181-
182-
double swift::_swift_stdlib_ceil(double x) { return std::ceil(x); }
183-
184-
double swift::_swift_stdlib_floor(double x) { return std::floor(x); }
185-
186140
#if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER
187141
void swift::_swift_stdlib_remainderl(void *_self, const void *_other) {
188142
*(long double *)_self = std::remainder(*(long double *)_self,
@@ -192,37 +146,4 @@ void swift::_swift_stdlib_remainderl(void *_self, const void *_other) {
192146
void swift::_swift_stdlib_squareRootl(void *_self) {
193147
*(long double *)_self = std::sqrt(*(long double *)_self);
194148
}
195-
196-
void
197-
swift::_swift_stdlib_addProductl(void *_self,
198-
const void *_lhs, const void *_rhs) {
199-
*(long double *)_self = std::fma(*(const long double *)_lhs,
200-
*(const long double *)_rhs,
201-
*(long double *)_self);
202-
}
203-
204-
void swift::_swift_stdlib_roundl(void *_self) {
205-
*(long double *)_self = std::round(*(long double *)_self);
206-
}
207-
208-
void swift::_swift_stdlib_roundevenl(void *_self) {
209-
*(long double *)_self = std::rint(*(long double *)_self);
210-
}
211-
212-
void swift::_swift_stdlib_truncl(void *_self) {
213-
*(long double *)_self = std::trunc(*(long double *)_self);
214-
}
215-
216-
void swift::_swift_stdlib_roundawayl(void *_self) {
217-
long double *ptr = (long double *)_self;
218-
*ptr = *ptr < 0 ? std::floor(*ptr) : std::ceil(*ptr);
219-
}
220-
221-
void swift::_swift_stdlib_ceill(void *_self) {
222-
*(long double *)_self = std::ceil(*(long double *)_self);
223-
}
224-
225-
void swift::_swift_stdlib_floorl(void *_self) {
226-
*(long double *)_self = std::floor(*(long double *)_self);
227-
}
228149
#endif // Have Float80

test/IRGen/builtin_math.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ public func test2(f : Double) -> Double {
2121
}
2222

2323
// LLVM's sqrt intrinsic does not have the same semantics as libm's sqrt.
24+
// In particular, llvm.sqrt(negative) is documented as being undef, but
25+
// we want sqrt(negative) to be defined to be NaN for IEEE 754 conformance.
2426

2527
// CHECK-LABEL: define {{.*}}test3
26-
// CHECK: call double @sqrt
28+
// CHECK-NOT: call double @llvm.sqrt.f64
2729

2830
public func test3(d : Double) -> Double {
2931
return sqrt(d)
3032
}
3133

3234
// CHECK-LABEL: define {{.*}}test4
33-
// CHECK: call float @sqrtf
35+
// CHECK-NOT: call float @llvm.sqrt.f32
3436

3537
public func test4(f : Float) -> Float {
3638
return sqrt(f)

0 commit comments

Comments
 (0)