Skip to content

Commit a30c4cd

Browse files
committed
Merge pull request #2898 from atrick/armv7fp
2 parents 3f198ad + 03a74ab commit a30c4cd

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,15 @@ extension ${Self}: BinaryFloatingPoint {
464464
public var nextUp: ${Self} {
465465
if isNaN { return self }
466466
if sign == .minus {
467+
#if arch(arm)
468+
// On arm, subnormals are flushed to zero.
469+
if (exponentBitPattern == 1 && significandBitPattern == 0) ||
470+
(exponentBitPattern == 0 && significandBitPattern != 0) {
471+
return ${Self}(sign: .minus,
472+
exponentBitPattern: 0,
473+
significandBitPattern: 0)
474+
}
475+
#endif
467476
if significandBitPattern == 0 {
468477
if exponentBitPattern == 0 {
469478
return .leastNonzeroMagnitude
@@ -485,7 +494,6 @@ extension ${Self}: BinaryFloatingPoint {
485494
#if arch(arm)
486495
// On arm, subnormals are skipped.
487496
if exponentBitPattern == 0 {
488-
_sanityCheck(self < .leastNonzeroMagnitude, "subnormal out of range")
489497
return .leastNonzeroMagnitude
490498
}
491499
#endif

test/1_stdlib/FloatingPoint.swift.gyb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ FloatingPoint.test("Float/staticProperties") {
107107
expectBitwiseEqual(0x1.921f_b6__p1, Ty.pi)
108108
expectBitwiseEqual(0x1.0p-23, Ty.ulpOfOne)
109109
expectBitwiseEqual(0x1.0p-126, Ty.leastNormalMagnitude)
110+
#if arch(arm)
111+
expectBitwiseEqual(0x1.0p-126, Ty.leastNonzeroMagnitude)
112+
#else
110113
expectBitwiseEqual(0x1.0p-149, Ty.leastNonzeroMagnitude)
114+
#endif
111115

112116
// From the BinaryFloatingPoint protocol.
113117
expectEqual(8, Ty.exponentBitCount)
@@ -180,7 +184,11 @@ FloatingPoint.test("Double/staticProperties") {
180184
expectBitwiseEqual(0x1.921f_b544_42d1_8__p1, Ty.pi)
181185
expectBitwiseEqual(0x1.0p-52, Ty.ulpOfOne)
182186
expectBitwiseEqual(0x1.0p-1022, Ty.leastNormalMagnitude)
187+
#if arch(arm)
188+
expectBitwiseEqual(0x1.0p-1022, Ty.leastNonzeroMagnitude)
189+
#else
183190
expectBitwiseEqual(0x1.0p-1074, Ty.leastNonzeroMagnitude)
191+
#endif
184192

185193
// From the BinaryFloatingPoint protocol.
186194
expectEqual(11, Ty.exponentBitCount)
@@ -243,6 +251,24 @@ FloatingPoint.test("Double/HashValueZero") {
243251
expectEqual(zero.hashValue, negativeZero.hashValue)
244252
}
245253

254+
#if arch(arm)
255+
% for FloatSelf in ['Float32', 'Float64']:
256+
func testSubNormalFlush(_ f: ${FloatSelf}) {
257+
if !f.isSubnormal {
258+
return
259+
}
260+
switch f.sign {
261+
case .plus:
262+
expectBitwiseEqual(.leastNonzeroMagnitude, f.nextUp)
263+
expectBitwiseEqual(0.0, f.nextDown)
264+
case .minus:
265+
expectBitwiseEqual(-0.0, f.nextUp)
266+
expectBitwiseEqual(-.leastNonzeroMagnitude, f.nextDown)
267+
}
268+
}
269+
% end
270+
#endif
271+
246272
let floatNextUpDownTests: [(Float, Float)] = [
247273
(.nan, .nan),
248274
(.greatestFiniteMagnitude, .infinity),
@@ -254,6 +280,13 @@ let floatNextUpDownTests: [(Float, Float)] = [
254280
FloatingPoint.test("Float.nextUp, .nextDown")
255281
.forEach(in: floatNextUpDownTests) {
256282
(prev, succ) in
283+
#if arch(arm)
284+
if prev.isSubnormal || succ.isSubnormal {
285+
testSubNormalFlush(prev)
286+
testSubNormalFlush(succ)
287+
return
288+
}
289+
#endif
257290
expectBitwiseEqual(succ, prev.nextUp)
258291
expectBitwiseEqual(prev, succ.nextDown)
259292
expectBitwiseEqual(-succ, (-prev).nextDown)
@@ -271,6 +304,13 @@ let doubleNextUpDownTests: [(Double, Double)] = [
271304
FloatingPoint.test("Double.nextUp, .nextDown")
272305
.forEach(in: doubleNextUpDownTests) {
273306
(prev, succ) in
307+
#if arch(arm)
308+
if prev.isSubnormal || succ.isSubnormal {
309+
testSubNormalFlush(prev)
310+
testSubNormalFlush(succ)
311+
return
312+
}
313+
#endif
274314
expectBitwiseEqual(succ, prev.nextUp)
275315
expectBitwiseEqual(prev, succ.nextDown)
276316
expectBitwiseEqual(-succ, (-prev).nextDown)

0 commit comments

Comments
 (0)