From 8ebb45f36764e520777a46cb57e1f486500157c1 Mon Sep 17 00:00:00 2001 From: Max Moiseev Date: Fri, 23 Mar 2018 15:42:18 -0700 Subject: [PATCH 1/4] Move DoubleWidth to test/Prototypes --- stdlib/public/core/CMakeLists.txt | 1 - stdlib/public/core/GroupInfo.json | 1 - {stdlib/public/core => test/Prototypes}/DoubleWidth.swift.gyb | 0 3 files changed, 2 deletions(-) rename {stdlib/public/core => test/Prototypes}/DoubleWidth.swift.gyb (100%) diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 5414725e37560..c4f2eeb37eaf3 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -48,7 +48,6 @@ set(SWIFTLIB_ESSENTIAL CTypes.swift DebuggerSupport.swift Dictionary.swift - DoubleWidth.swift.gyb DropWhile.swift Dump.swift EmptyCollection.swift diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index 735a3ae12a1d6..041f5b3b91e7a 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -134,7 +134,6 @@ "BuiltinMath.swift", { "Integers": [ - "DoubleWidth.swift", "Integers.swift", "IntegerParsing.swift"], "Floating": [ diff --git a/stdlib/public/core/DoubleWidth.swift.gyb b/test/Prototypes/DoubleWidth.swift.gyb similarity index 100% rename from stdlib/public/core/DoubleWidth.swift.gyb rename to test/Prototypes/DoubleWidth.swift.gyb From cee7efca65e046bceabe9ba65418cba25365babf Mon Sep 17 00:00:00 2001 From: Max Moiseev Date: Fri, 23 Mar 2018 16:15:11 -0700 Subject: [PATCH 2/4] Un-implement dividingFullWidth for 64bit types on 32bit platforms The implementation uses DoubleWidth that needs to be removed due to library binary size issues. Even extracting the single DoubleWidth method that's used in it would likely result in having to copy a large portion of the rest of DoubleWidth implementation along with it, this defeating the purpose. This change restores the behavior of dividingFullWidth as it was shipped with Swift 4.1, therefore it's not a breaking change. --- stdlib/public/core/Integers.swift.gyb | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb index 683d7ca7c25ce..94489ad8b74e9 100644 --- a/stdlib/public/core/Integers.swift.gyb +++ b/stdlib/public/core/Integers.swift.gyb @@ -3552,23 +3552,11 @@ ${assignmentOperatorComment(x.operator, True)} ) -> (quotient: ${Self}, remainder: ${Self}) { // FIXME(integers): tests % # 128-bit types are not provided by the 32-bit LLVM -% #if word_bits == 32 and bits == 64: +% if word_bits == 32 and bits == 64: % # FIXME(integers): uncomment the above after using the right conditional % # compilation block to exclude 64-bit Windows, which does not support % # 128-bit operations -% if bits == 64: -% HalfWidth = 'Int32' if signed else 'UInt32' - let lhsHigh = - unsafeBitCast(dividend.high, to: DoubleWidth<${HalfWidth}>.self) - let lhsLow = unsafeBitCast(dividend.low, to: DoubleWidth.self) - let rhs_ = unsafeBitCast(self, to: DoubleWidth<${HalfWidth}>.self) - - let (quotient_, remainder_) = rhs_.dividingFullWidth((lhsHigh, lhsLow)) - - let quotient = unsafeBitCast(quotient_, to: ${Self}.self) - let remainder = unsafeBitCast(remainder_, to: ${Self}.self) - - return (quotient: quotient, remainder: remainder) + fatalError("Operation is not supported") % else: // FIXME(integers): handle division by zero and overflows _precondition(self != 0, "Division by zero") From 141fefc06b73627c9ee6958b30a20593cc43554c Mon Sep 17 00:00:00 2001 From: Max Moiseev Date: Fri, 23 Mar 2018 17:14:46 -0700 Subject: [PATCH 3/4] Update tests after removal of DoubleWidth --- test/Constraints/diagnostics_swift4.swift | 3 +- test/Prototypes/DoubleWidth.swift.gyb | 488 +++++++++++++++++++--- test/stdlib/DoubleWidth.swift | 379 ----------------- test/stdlib/FloatingPoint.swift.gyb | 3 + test/stdlib/Integers.swift.gyb | 3 + 5 files changed, 446 insertions(+), 430 deletions(-) delete mode 100644 test/stdlib/DoubleWidth.swift diff --git a/test/Constraints/diagnostics_swift4.swift b/test/Constraints/diagnostics_swift4.swift index 9571efc34ab83..735ff9d4c210d 100644 --- a/test/Constraints/diagnostics_swift4.swift +++ b/test/Constraints/diagnostics_swift4.swift @@ -54,4 +54,5 @@ class R { infix operator +=+ : AdditionPrecedence func +=+(_ lhs: Int, _ rhs: Int) -> Bool { return lhs == rhs } func +=+(_ lhs: T, _ rhs: Int) -> Bool { return lhs == rhs } -let _ = DoubleWidth(Int.min) - 1 +=+ Int.min // Ok +// FIXME: DoubleWidth is no longer part of the standard library +// let _ = DoubleWidth(Int.min) - 1 +=+ Int.min // Ok diff --git a/test/Prototypes/DoubleWidth.swift.gyb b/test/Prototypes/DoubleWidth.swift.gyb index 61ca8a913ef15..5ae83556ab30c 100644 --- a/test/Prototypes/DoubleWidth.swift.gyb +++ b/test/Prototypes/DoubleWidth.swift.gyb @@ -1,14 +1,7 @@ -//===--- DoubleWidth.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 -// -//===----------------------------------------------------------------------===// +// RUN: %target-run-simple-swiftgyb +// REQUIRES: executable_test + +import StdlibUnittest /// A fixed-width integer that has twice the bit width of its base type. /// @@ -45,8 +38,7 @@ /// integer type. Nesting `DoubleWidth` instances, in particular, may result in /// undesirable performance. @_fixed_layout // FIXME(sil-serialize-all) -public struct DoubleWidth : - _ExpressibleByBuiltinIntegerLiteral +public struct DoubleWidth where Base.Magnitude : UnsignedInteger, Base.Words : Collection, Base.Magnitude.Words : Collection { @@ -209,6 +201,54 @@ extension DoubleWidth : Numeric { } } +#if false + +// This conformance is only possible once the type is in the stdlib, as it uses +// Builtin +extension DoubleWidth: _ExpressibleByBuiltinIntegerLiteral { + @_inlineable // FIXME(sil-serialize-all) + public init(_builtinIntegerLiteral _x: _MaxBuiltinIntegerType) { + var _x = _x + self = DoubleWidth() + + // If we can capture the entire literal in a single Int64, stop there. + // This avoids some potential deep recursion due to literal expressions in + // other DoubleWidth methods. + let (_value, _overflow) = Builtin.s_to_s_checked_trunc_Int2048_Int64(_x) + if !Bool(_overflow) { + self = DoubleWidth(Int64(_value)) + return + } + + // Convert all but the most significant 64 bits as unsigned integers. + let _shift = Builtin.sext_Int64_Int2048((64 as Int64)._value) + let lowWordCount = (bitWidth - 1) / 64 + for i in 0.. +typealias UInt256 = DoubleWidth +typealias UInt512 = DoubleWidth +typealias UInt1024 = DoubleWidth + +typealias Int128 = DoubleWidth +typealias Int256 = DoubleWidth +typealias Int512 = DoubleWidth +typealias Int1024 = DoubleWidth + +func checkSignedIntegerConformance(_ x: T) {} +func checkUnsignedIntegerConformance(_ x: T) {} + +dwTests.test("Literals") { + let w: DoubleWidth = 100 + expectTrue(w == 100 as Int) + + let x: DoubleWidth = 1000 + expectTrue(x == 1000 as Int) + + let y: DoubleWidth = 1000 + expectTrue(y == 1000 as Int) + + let z: DoubleWidth = -1000 + expectTrue(z == -1000 as Int) + + expectCrashLater() + _ = -1 as DoubleWidth +} + +#if false +// Uncomment these tests once _ExpressibleByBuiltinIntegerLiteral +// conformance is available +dwTests.test("Literals/Large/Signed") { + let a: Int256 = + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + let b: Int256 = + -0x8000000000000000000000000000000000000000000000000000000000000000 + expectEqual(a, Int256.max) + expectEqual(b, Int256.min) + expectCrashLater() + _ = -0x8000000000000000000000000000000000000000000000000000000000000001 + as Int256 +} + +dwTests.test("Literals/Large/SignedOverflow") { + expectCrashLater() + _ = 0x8000000000000000000000000000000000000000000000000000000000000000 + as Int256 +} + +dwTests.test("Literals/Large/Unsigned") { + let a: UInt256 = + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + let b: UInt256 = 0 + expectEqual(a, UInt256.max) + expectEqual(b, UInt256.min) + expectCrashLater() + _ = -1 as UInt256 +} + +dwTests.test("Literals/Large/UnsignedOverflow") { + expectCrashLater() + _ = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0 + as UInt256 +} +#endif + +dwTests.test("Arithmetic/unsigned") { + let x: DoubleWidth = 1000 + let y: DoubleWidth = 1111 + expectEqual(x + 1, 1001) + expectEqual(x + x, 2000) + expectEqual(x - (1 as DoubleWidth), 999) + expectEqual(x - x, 0) + expectEqual(y - x, 111) + + expectEqual(x * 7, 7000) + expectEqual(y * 7, 7777) + + expectEqual(x / 3, 333) + expectEqual(x / x, 1) + expectEqual(x / y, 0) + expectEqual(y / x, 1) + + expectEqual(x % 3, 1) + expectEqual(x % y, x) +} + +dwTests.test("Arithmetic/signed") { + let x: DoubleWidth = 1000 + let y: DoubleWidth = -1111 + expectEqual(x + 1, 1001) + expectEqual(x + x, 2000) + expectEqual(x - (1 as DoubleWidth), 999) + expectEqual(x - x, 0) + expectEqual(0 - x, -1000) + expectEqual(x + y, -111) + expectEqual(x - y, 2111) + + expectEqual(x * 7, 7000) + expectEqual(y * 7, -7777) + expectEqual(x * -7, -7000) + expectEqual(y * -7, 7777) + + expectEqual(x / 3, 333) + expectEqual(x / -3, -333) + expectEqual(x / x, 1) + expectEqual(x / y, 0) + expectEqual(y / x, -1) + expectEqual(y / y, 1) + + expectEqual(x % 3, 1) + expectEqual(x % -3, 1) + expectEqual(y % 3, -1) + expectEqual(y % -3, -1) + + expectEqual(-y, 1111) + expectEqual(-x, -1000) +} + +dwTests.test("Nested") { + do { + let x = UInt1024.max + let (y, o) = x.addingReportingOverflow(1) + expectEqual(y, 0) + expectTrue(y == (0 as Int)) + expectTrue(o) + } + + do { + let x = Int1024.max + let (y, o) = x.addingReportingOverflow(1) + expectEqual(y, Int1024.min) + expectLT(y, 0) + expectTrue(y < (0 as Int)) + expectTrue(y < (0 as UInt)) + expectTrue(o) + } + + expectFalse(UInt1024.isSigned) + expectEqual(UInt1024.bitWidth, 1024) + expectTrue(Int1024.isSigned) + expectEqual(Int1024.bitWidth, 1024) + + expectEqualSequence( + UInt1024.max.words, repeatElement(UInt.max, count: 1024 / UInt.bitWidth)) +} + +dwTests.test("inits") { + typealias DWU16 = DoubleWidth + + expectTrue(DWU16(UInt16.max) == UInt16.max) + expectNil(DWU16(exactly: UInt32.max)) + expectEqual(DWU16(truncatingIfNeeded: UInt64.max), DWU16.max) + + expectCrashLater() + _ = DWU16(UInt32.max) +} + +dwTests.test("Magnitude") { + typealias DWU16 = DoubleWidth + typealias DWI16 = DoubleWidth + + expectTrue(DWU16.min.magnitude == UInt16.min.magnitude) + expectTrue((42 as DWU16).magnitude == (42 as UInt16).magnitude) + expectTrue(DWU16.max.magnitude == UInt16.max.magnitude) + + expectTrue(DWI16.min.magnitude == Int16.min.magnitude) + expectTrue((-42 as DWI16).magnitude == (-42 as Int16).magnitude) + expectTrue(DWI16().magnitude == Int16(0).magnitude) // See SR-6602. + expectTrue((42 as DWI16).magnitude == (42 as Int16).magnitude) + expectTrue(DWI16.max.magnitude == Int16.max.magnitude) +} + +dwTests.test("TwoWords") { + typealias DW = DoubleWidth + + expectEqual(-1 as DW, DW(truncatingIfNeeded: -1 as Int8)) + + expectNil(Int(exactly: DW(Int.min) - 1)) + expectNil(Int(exactly: DW(Int.max) + 1)) + + expectTrue(DW(Int.min) - 1 < Int.min) + expectTrue(DW(Int.max) + 1 > Int.max) +} + +dwTests.test("Bitshifts") { + typealias DWU64 = DoubleWidth>> + typealias DWI64 = DoubleWidth>> + + func f(_ x: T, type: U.Type) { + let y = U(x) + expectEqual(T.bitWidth, U.bitWidth) + for i in -(T.bitWidth + 1)...(T.bitWidth + 1) { + expectTrue(x << i == y << i) + expectTrue(x >> i == y >> i) + + expectTrue(x &<< i == y &<< i) + expectTrue(x &>> i == y &>> i) + } + } + + f(1 as UInt64, type: DWU64.self) + f(~(~0 as UInt64 >> 1), type: DWU64.self) + f(UInt64.max, type: DWU64.self) + // 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101 + f(17340530535757639845 as UInt64, type: DWU64.self) + + f(1 as Int64, type: DWI64.self) + f(Int64.min, type: DWI64.self) + f(Int64.max, type: DWI64.self) + // 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101 + f(6171603459878809765 as Int64, type: DWI64.self) +} + +dwTests.test("Remainder/DividingBy0") { + func f(_ x: Int1024, _ y: Int1024) -> Int1024 { + return x % y + } + expectCrashLater() + _ = f(42, 0) +} + +dwTests.test("RemainderReportingOverflow/DividingByMinusOne") { + func f(_ x: Int256, _ y: Int256) -> Int256 { + return x.remainderReportingOverflow(dividingBy: y).partialValue + } + expectEqual(f(.max, -1), 0) + expectEqual(f(.min, -1), 0) +} + +dwTests.test("Division/By0") { + func f(_ x: Int1024, _ y: Int1024) -> Int1024 { + return x / y + } + expectCrashLater() + _ = f(42, 0) +} + +dwTests.test("DivideMinByMinusOne") { + func f(_ x: Int1024) -> Int1024 { + return x / -1 + } + expectCrashLater() + _ = f(Int1024.min) +} + +dwTests.test("MultiplyMinByMinusOne") { + func f(_ x: Int1024) -> Int1024 { + return x * -1 + } + expectCrashLater() + _ = f(Int1024.min) +} + +typealias DWI16 = DoubleWidth +typealias DWU16 = DoubleWidth + +dwTests.test("Conversions") { + expectTrue(DWI16(1 << 15 - 1) == Int(1 << 15 - 1)) + expectTrue(DWI16(-1 << 15) == Int(-1 << 15)) + expectTrue(DWU16(1 << 16 - 1) == Int(1 << 16 - 1)) + expectTrue(DWU16(0) == Int(0)) + + expectTrue(DWI16(Double(1 << 15 - 1)) == Int(1 << 15 - 1)) + expectTrue(DWI16(Double(-1 << 15)) == Int(-1 << 15)) + expectTrue(DWU16(Double(1 << 16 - 1)) == Int(1 << 16 - 1)) + expectTrue(DWU16(Double(0)) == Int(0)) + + expectTrue(DWI16(Double(1 << 15 - 1) + 0.9) == Int(1 << 15 - 1)) + expectTrue(DWI16(Double(-1 << 15) - 0.9) == Int(-1 << 15)) + expectTrue(DWU16(Double(1 << 16 - 1) + 0.9) == Int(1 << 16 - 1)) + expectTrue(DWU16(Double(0) - 0.9) == Int(0)) + + expectEqual(DWI16(0.00001), 0) + expectEqual(DWU16(0.00001), 0) +} + +dwTests.test("Exact Conversions") { + expectEqual(DWI16(Double(1 << 15 - 1)), DWI16(exactly: Double(1 << 15 - 1))!) + expectEqual(DWI16(Double(-1 << 15)), DWI16(exactly: Double(-1 << 15))!) + expectEqual(DWU16(Double(1 << 16 - 1)), DWU16(exactly: Double(1 << 16 - 1))!) + expectEqual(DWU16(Double(0)), DWU16(exactly: Double(0))!) + + expectNil(DWI16(exactly: Double(1 << 15 - 1) + 0.9)) + expectNil(DWI16(exactly: Double(-1 << 15) - 0.9)) + expectNil(DWU16(exactly: Double(1 << 16 - 1) + 0.9)) + expectNil(DWU16(exactly: Double(0) - 0.9)) + + expectNil(DWI16(exactly: Double(1 << 15))) + expectNil(DWI16(exactly: Double(-1 << 15) - 1)) + expectNil(DWU16(exactly: Double(1 << 16))) + expectNil(DWU16(exactly: Double(-1))) + + expectNil(DWI16(exactly: 0.00001)) + expectNil(DWU16(exactly: 0.00001)) + + expectNil(DWU16(exactly: Double.nan)) + expectNil(DWU16(exactly: Float.nan)) + expectNil(DWU16(exactly: Double.infinity)) + expectNil(DWU16(exactly: Float.infinity)) +} + +dwTests.test("Conversions/SignedMax+1") { + expectCrashLater() + _ = DWI16(1 << 15) +} + +dwTests.test("Conversions/SignedMin-1") { + expectCrashLater() + _ = DWI16(-1 << 15 - 1) +} + +dwTests.test("Conversions/UnsignedMax+1") { + expectCrashLater() + _ = DWU16(1 << 16) +} + +dwTests.test("Conversions/Unsigned-1") { + expectCrashLater() + _ = DWU16(-1) +} + +dwTests.test("Conversions/String") { + expectEqual(String(Int256.max, radix: 16), + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + expectEqual(String(Int256.min, radix: 16), + "-8000000000000000000000000000000000000000000000000000000000000000") + + expectEqual(String(Int256.max, radix: 2), """ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 1111111111111111111111111111111111111111111111111111111111111111\ + 111111111111111111111111111111111111111111111111111111111111111 + """) + expectEqual(String(Int256.min, radix: 2), """ + -100000000000000000000000000000000000000000000000000000000000000\ + 0000000000000000000000000000000000000000000000000000000000000000\ + 0000000000000000000000000000000000000000000000000000000000000000\ + 00000000000000000000000000000000000000000000000000000000000000000 + """) + + expectEqual(String(Int128.max, radix: 10), + "170141183460469231731687303715884105727") + expectEqual(String(Int128.min, radix: 10), + "-170141183460469231731687303715884105728") +} + +dwTests.test("Words") { + expectEqualSequence((0 as DoubleWidth).words, [0]) + expectEqualSequence((1 as DoubleWidth).words, [1]) + expectEqualSequence((-1 as DoubleWidth).words, [UInt.max]) + expectEqualSequence((256 as DoubleWidth).words, [256]) + expectEqualSequence((-256 as DoubleWidth).words, [UInt.max - 255]) + expectEqualSequence(DoubleWidth.max.words, [32767]) + expectEqualSequence(DoubleWidth.min.words, [UInt.max - 32767]) + + expectEqualSequence((0 as Int1024).words, + repeatElement(0 as UInt, count: 1024 / UInt.bitWidth)) + expectEqualSequence((-1 as Int1024).words, + repeatElement(UInt.max, count: 1024 / UInt.bitWidth)) + expectEqualSequence((1 as Int1024).words, + [1] + Array(repeating: 0, count: 1024 / UInt.bitWidth - 1)) +} + +dwTests.test("Conditional Conformance") { + checkSignedIntegerConformance(0 as Int128) + checkSignedIntegerConformance(0 as Int1024) + + checkUnsignedIntegerConformance(0 as UInt128) + checkUnsignedIntegerConformance(0 as UInt1024) +} + +runAllTests() diff --git a/test/stdlib/DoubleWidth.swift b/test/stdlib/DoubleWidth.swift deleted file mode 100644 index 86b31fcdae29b..0000000000000 --- a/test/stdlib/DoubleWidth.swift +++ /dev/null @@ -1,379 +0,0 @@ -// RUN: %target-run-simple-swift -// REQUIRES: executable_test - -import StdlibUnittest - -var dwTests = TestSuite("DoubleWidth") - -typealias UInt128 = DoubleWidth -typealias UInt256 = DoubleWidth -typealias UInt512 = DoubleWidth -typealias UInt1024 = DoubleWidth - -typealias Int128 = DoubleWidth -typealias Int256 = DoubleWidth -typealias Int512 = DoubleWidth -typealias Int1024 = DoubleWidth - -func checkSignedIntegerConformance(_ x: T) {} -func checkUnsignedIntegerConformance(_ x: T) {} - -dwTests.test("Literals") { - let w: DoubleWidth = 100 - expectTrue(w == 100 as Int) - - let x: DoubleWidth = 1000 - expectTrue(x == 1000 as Int) - - let y: DoubleWidth = 1000 - expectTrue(y == 1000 as Int) - - let z: DoubleWidth = -1000 - expectTrue(z == -1000 as Int) - - expectCrashLater() - _ = -1 as DoubleWidth -} - -dwTests.test("Literals/Large/Signed") { - let a: Int256 = - 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - let b: Int256 = - -0x8000000000000000000000000000000000000000000000000000000000000000 - expectEqual(a, Int256.max) - expectEqual(b, Int256.min) - expectCrashLater() - _ = -0x8000000000000000000000000000000000000000000000000000000000000001 - as Int256 -} - -dwTests.test("Literals/Large/SignedOverflow") { - expectCrashLater() - _ = 0x8000000000000000000000000000000000000000000000000000000000000000 - as Int256 -} - -dwTests.test("Literals/Large/Unsigned") { - let a: UInt256 = - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - let b: UInt256 = 0 - expectEqual(a, UInt256.max) - expectEqual(b, UInt256.min) - expectCrashLater() - _ = -1 as UInt256 -} - -dwTests.test("Literals/Large/UnsignedOverflow") { - expectCrashLater() - _ = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0 - as UInt256 -} - -dwTests.test("Arithmetic/unsigned") { - let x: DoubleWidth = 1000 - let y: DoubleWidth = 1111 - expectEqual(x + 1, 1001) - expectEqual(x + x, 2000) - expectEqual(x - (1 as DoubleWidth), 999) - expectEqual(x - x, 0) - expectEqual(y - x, 111) - - expectEqual(x * 7, 7000) - expectEqual(y * 7, 7777) - - expectEqual(x / 3, 333) - expectEqual(x / x, 1) - expectEqual(x / y, 0) - expectEqual(y / x, 1) - - expectEqual(x % 3, 1) - expectEqual(x % y, x) -} - -dwTests.test("Arithmetic/signed") { - let x: DoubleWidth = 1000 - let y: DoubleWidth = -1111 - expectEqual(x + 1, 1001) - expectEqual(x + x, 2000) - expectEqual(x - (1 as DoubleWidth), 999) - expectEqual(x - x, 0) - expectEqual(0 - x, -1000) - expectEqual(x + y, -111) - expectEqual(x - y, 2111) - - expectEqual(x * 7, 7000) - expectEqual(y * 7, -7777) - expectEqual(x * -7, -7000) - expectEqual(y * -7, 7777) - - expectEqual(x / 3, 333) - expectEqual(x / -3, -333) - expectEqual(x / x, 1) - expectEqual(x / y, 0) - expectEqual(y / x, -1) - expectEqual(y / y, 1) - - expectEqual(x % 3, 1) - expectEqual(x % -3, 1) - expectEqual(y % 3, -1) - expectEqual(y % -3, -1) - - expectEqual(-y, 1111) - expectEqual(-x, -1000) -} - -dwTests.test("Nested") { - do { - let x = UInt1024.max - let (y, o) = x.addingReportingOverflow(1) - expectEqual(y, 0) - expectTrue(y == (0 as Int)) - expectTrue(o) - } - - do { - let x = Int1024.max - let (y, o) = x.addingReportingOverflow(1) - expectEqual(y, Int1024.min) - expectLT(y, 0) - expectTrue(y < (0 as Int)) - expectTrue(y < (0 as UInt)) - expectTrue(o) - } - - expectFalse(UInt1024.isSigned) - expectEqual(UInt1024.bitWidth, 1024) - expectTrue(Int1024.isSigned) - expectEqual(Int1024.bitWidth, 1024) - - expectEqualSequence( - UInt1024.max.words, repeatElement(UInt.max, count: 1024 / UInt.bitWidth)) -} - -dwTests.test("inits") { - typealias DWU16 = DoubleWidth - - expectTrue(DWU16(UInt16.max) == UInt16.max) - expectNil(DWU16(exactly: UInt32.max)) - expectEqual(DWU16(truncatingIfNeeded: UInt64.max), DWU16.max) - - expectCrashLater() - _ = DWU16(UInt32.max) -} - -dwTests.test("Magnitude") { - typealias DWU16 = DoubleWidth - typealias DWI16 = DoubleWidth - - expectTrue(DWU16.min.magnitude == UInt16.min.magnitude) - expectTrue((42 as DWU16).magnitude == (42 as UInt16).magnitude) - expectTrue(DWU16.max.magnitude == UInt16.max.magnitude) - - expectTrue(DWI16.min.magnitude == Int16.min.magnitude) - expectTrue((-42 as DWI16).magnitude == (-42 as Int16).magnitude) - expectTrue(DWI16().magnitude == Int16(0).magnitude) // See SR-6602. - expectTrue((42 as DWI16).magnitude == (42 as Int16).magnitude) - expectTrue(DWI16.max.magnitude == Int16.max.magnitude) -} - -dwTests.test("TwoWords") { - typealias DW = DoubleWidth - - expectEqual(-1 as DW, DW(truncatingIfNeeded: -1 as Int8)) - - expectNil(Int(exactly: DW(Int.min) - 1)) - expectNil(Int(exactly: DW(Int.max) + 1)) - - expectTrue(DW(Int.min) - 1 < Int.min) - expectTrue(DW(Int.max) + 1 > Int.max) -} - -dwTests.test("Bitshifts") { - typealias DWU64 = DoubleWidth>> - typealias DWI64 = DoubleWidth>> - - func f(_ x: T, type: U.Type) { - let y = U(x) - expectEqual(T.bitWidth, U.bitWidth) - for i in -(T.bitWidth + 1)...(T.bitWidth + 1) { - expectTrue(x << i == y << i) - expectTrue(x >> i == y >> i) - - expectTrue(x &<< i == y &<< i) - expectTrue(x &>> i == y &>> i) - } - } - - f(1 as UInt64, type: DWU64.self) - f(~(~0 as UInt64 >> 1), type: DWU64.self) - f(UInt64.max, type: DWU64.self) - // 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101 - f(17340530535757639845 as UInt64, type: DWU64.self) - - f(1 as Int64, type: DWI64.self) - f(Int64.min, type: DWI64.self) - f(Int64.max, type: DWI64.self) - // 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101 - f(6171603459878809765 as Int64, type: DWI64.self) -} - -dwTests.test("Remainder/DividingBy0") { - func f(_ x: Int1024, _ y: Int1024) -> Int1024 { - return x % y - } - expectCrashLater() - _ = f(42, 0) -} - -dwTests.test("RemainderReportingOverflow/DividingByMinusOne") { - func f(_ x: Int256, _ y: Int256) -> Int256 { - return x.remainderReportingOverflow(dividingBy: y).partialValue - } - expectEqual(f(.max, -1), 0) - expectEqual(f(.min, -1), 0) -} - -dwTests.test("Division/By0") { - func f(_ x: Int1024, _ y: Int1024) -> Int1024 { - return x / y - } - expectCrashLater() - _ = f(42, 0) -} - -dwTests.test("DivideMinByMinusOne") { - func f(_ x: Int1024) -> Int1024 { - return x / -1 - } - expectCrashLater() - _ = f(Int1024.min) -} - -dwTests.test("MultiplyMinByMinusOne") { - func f(_ x: Int1024) -> Int1024 { - return x * -1 - } - expectCrashLater() - _ = f(Int1024.min) -} - -typealias DWI16 = DoubleWidth -typealias DWU16 = DoubleWidth - -dwTests.test("Conversions") { - expectTrue(DWI16(1 << 15 - 1) == Int(1 << 15 - 1)) - expectTrue(DWI16(-1 << 15) == Int(-1 << 15)) - expectTrue(DWU16(1 << 16 - 1) == Int(1 << 16 - 1)) - expectTrue(DWU16(0) == Int(0)) - - expectTrue(DWI16(Double(1 << 15 - 1)) == Int(1 << 15 - 1)) - expectTrue(DWI16(Double(-1 << 15)) == Int(-1 << 15)) - expectTrue(DWU16(Double(1 << 16 - 1)) == Int(1 << 16 - 1)) - expectTrue(DWU16(Double(0)) == Int(0)) - - expectTrue(DWI16(Double(1 << 15 - 1) + 0.9) == Int(1 << 15 - 1)) - expectTrue(DWI16(Double(-1 << 15) - 0.9) == Int(-1 << 15)) - expectTrue(DWU16(Double(1 << 16 - 1) + 0.9) == Int(1 << 16 - 1)) - expectTrue(DWU16(Double(0) - 0.9) == Int(0)) - - expectEqual(DWI16(0.00001), 0) - expectEqual(DWU16(0.00001), 0) -} - -dwTests.test("Exact Conversions") { - expectEqual(DWI16(Double(1 << 15 - 1)), DWI16(exactly: Double(1 << 15 - 1))!) - expectEqual(DWI16(Double(-1 << 15)), DWI16(exactly: Double(-1 << 15))!) - expectEqual(DWU16(Double(1 << 16 - 1)), DWU16(exactly: Double(1 << 16 - 1))!) - expectEqual(DWU16(Double(0)), DWU16(exactly: Double(0))!) - - expectNil(DWI16(exactly: Double(1 << 15 - 1) + 0.9)) - expectNil(DWI16(exactly: Double(-1 << 15) - 0.9)) - expectNil(DWU16(exactly: Double(1 << 16 - 1) + 0.9)) - expectNil(DWU16(exactly: Double(0) - 0.9)) - - expectNil(DWI16(exactly: Double(1 << 15))) - expectNil(DWI16(exactly: Double(-1 << 15) - 1)) - expectNil(DWU16(exactly: Double(1 << 16))) - expectNil(DWU16(exactly: Double(-1))) - - expectNil(DWI16(exactly: 0.00001)) - expectNil(DWU16(exactly: 0.00001)) - - expectNil(DWU16(exactly: Double.nan)) - expectNil(DWU16(exactly: Float.nan)) - expectNil(DWU16(exactly: Double.infinity)) - expectNil(DWU16(exactly: Float.infinity)) -} - -dwTests.test("Conversions/SignedMax+1") { - expectCrashLater() - _ = DWI16(1 << 15) -} - -dwTests.test("Conversions/SignedMin-1") { - expectCrashLater() - _ = DWI16(-1 << 15 - 1) -} - -dwTests.test("Conversions/UnsignedMax+1") { - expectCrashLater() - _ = DWU16(1 << 16) -} - -dwTests.test("Conversions/Unsigned-1") { - expectCrashLater() - _ = DWU16(-1) -} - -dwTests.test("Conversions/String") { - expectEqual(String(Int256.max, radix: 16), - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") - expectEqual(String(Int256.min, radix: 16), - "-8000000000000000000000000000000000000000000000000000000000000000") - - expectEqual(String(Int256.max, radix: 2), """ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 1111111111111111111111111111111111111111111111111111111111111111\ - 111111111111111111111111111111111111111111111111111111111111111 - """) - expectEqual(String(Int256.min, radix: 2), """ - -100000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000\ - 00000000000000000000000000000000000000000000000000000000000000000 - """) - - expectEqual(String(Int128.max, radix: 10), - "170141183460469231731687303715884105727") - expectEqual(String(Int128.min, radix: 10), - "-170141183460469231731687303715884105728") -} - -dwTests.test("Words") { - expectEqualSequence((0 as DoubleWidth).words, [0]) - expectEqualSequence((1 as DoubleWidth).words, [1]) - expectEqualSequence((-1 as DoubleWidth).words, [UInt.max]) - expectEqualSequence((256 as DoubleWidth).words, [256]) - expectEqualSequence((-256 as DoubleWidth).words, [UInt.max - 255]) - expectEqualSequence(DoubleWidth.max.words, [32767]) - expectEqualSequence(DoubleWidth.min.words, [UInt.max - 32767]) - - expectEqualSequence((0 as Int1024).words, - repeatElement(0 as UInt, count: 1024 / UInt.bitWidth)) - expectEqualSequence((-1 as Int1024).words, - repeatElement(UInt.max, count: 1024 / UInt.bitWidth)) - expectEqualSequence((1 as Int1024).words, - [1] + Array(repeating: 0, count: 1024 / UInt.bitWidth - 1)) -} - -dwTests.test("Conditional Conformance") { - checkSignedIntegerConformance(0 as Int128) - checkSignedIntegerConformance(0 as Int1024) - - checkUnsignedIntegerConformance(0 as UInt128) - checkUnsignedIntegerConformance(0 as UInt1024) -} - -runAllTests() - diff --git a/test/stdlib/FloatingPoint.swift.gyb b/test/stdlib/FloatingPoint.swift.gyb index d702e5eff36e9..fa98f1b037e23 100644 --- a/test/stdlib/FloatingPoint.swift.gyb +++ b/test/stdlib/FloatingPoint.swift.gyb @@ -105,11 +105,14 @@ FloatingPoint.test("BinaryFloatingPoint/genericIntegerConversion") { expectEqual(Float._convert(from: Int64.max).value, Float(Int64.max)) expectEqual(Float._convert(from: Int64.min).value, Float(Int64.min)) +// FIXME: DoubleWidth is no longer part of the standard library +#if false expectEqual(Float._convert(from: DoubleWidth.max).value, .infinity) expectEqual( Float._convert(from: DoubleWidth>.max).value, .infinity) expectEqual( Float._convert(from: DoubleWidth>.min).value, -.infinity) +#endif } FloatingPoint.test("BinaryFloatingPoint/genericFloatingPointConversion") { diff --git a/test/stdlib/Integers.swift.gyb b/test/stdlib/Integers.swift.gyb index 4238511a43696..f16ac27589cff 100644 --- a/test/stdlib/Integers.swift.gyb +++ b/test/stdlib/Integers.swift.gyb @@ -890,6 +890,8 @@ tests.test("binaryLogarithm/generic") { expectEqual( Int((42 as MockBinaryInteger)._binaryLogarithm()), Int((42 as UInt)._binaryLogarithm())) +// FIXME: DoubleWidth is no longer part of the standard library +#if false expectEqual( Int((42 as MockBinaryInteger>)._binaryLogarithm()), Int((42 as DoubleWidth)._binaryLogarithm())) @@ -900,6 +902,7 @@ tests.test("binaryLogarithm/generic") { Int((42 as MockBinaryInteger>>) ._binaryLogarithm()), Int((42 as DoubleWidth>)._binaryLogarithm())) +#endif } runAllTests() From 8f635083bd5cddbbd19dd5030f17852d6b0ab97e Mon Sep 17 00:00:00 2001 From: Maxim Moiseev Date: Sun, 25 Mar 2018 22:40:58 -0700 Subject: [PATCH 4/4] Don't test DoubleWidth on 32 bit platforms --- test/Prototypes/DoubleWidth.swift.gyb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Prototypes/DoubleWidth.swift.gyb b/test/Prototypes/DoubleWidth.swift.gyb index 5ae83556ab30c..1eeaeada39b11 100644 --- a/test/Prototypes/DoubleWidth.swift.gyb +++ b/test/Prototypes/DoubleWidth.swift.gyb @@ -1,5 +1,6 @@ // RUN: %target-run-simple-swiftgyb // REQUIRES: executable_test +// REQUIRES: CPU=x86_64 import StdlibUnittest