[BitwiseCopyable] Drop req from SIMD/Storage.

There are conformers to SIMDStorage (like that in the added test case)
which involve an Array (a type that can't conform to BitwiseCopyable).
So lift the constraint on SIMDStorage.  This in turn requires lifting
the constraint on SIMD (otherwise, e.g. `SIMD8<Scalar>` would fail to
conform since it has as a member some SIMD8Storage which is only
constrained to conform to `SIMDStorage`; the `SIMD8Storage`
associatedtype also cannot be constrained to `BitwiseCopyable` because
that storage may again not conform as in the test example).

rdar://128661878
This commit is contained in:
Nate Chandler
2024-05-24 08:37:07 -07:00
parent 478d8a68d7
commit 746cf2ff5b
5 changed files with 223 additions and 14 deletions

View File

@@ -31,7 +31,7 @@ prefix operator .!
/// elementwise accesses. Computational operations are defined on the `SIMD`
/// protocol, which refines this protocol, and on the concrete types that
/// conform to `SIMD`.
public protocol SIMDStorage : BitwiseCopyable {
public protocol SIMDStorage {
/// The type of scalars in the vector space.
#if $Embedded
associatedtype Scalar: Hashable
@@ -80,8 +80,7 @@ public protocol SIMDScalar : BitwiseCopyable {
public protocol SIMD<Scalar>:
SIMDStorage,
Hashable,
ExpressibleByArrayLiteral,
BitwiseCopyable
ExpressibleByArrayLiteral
{
/// The mask type resulting from pointwise comparisons of this vector type.
associatedtype MaskStorage: SIMD
@@ -96,8 +95,7 @@ public protocol SIMD<Scalar>:
Codable,
Hashable,
CustomStringConvertible,
ExpressibleByArrayLiteral,
BitwiseCopyable
ExpressibleByArrayLiteral
{
/// The mask type resulting from pointwise comparisons of this vector type.
associatedtype MaskStorage: SIMD

View File

@@ -190,6 +190,10 @@ extension SIMD${n}: Sendable
where Scalar: Sendable,
Scalar.SIMD${storageN}Storage: Sendable { }
extension SIMD${n}: BitwiseCopyable
where Scalar: BitwiseCopyable,
Scalar.SIMD${storageN}Storage: BitwiseCopyable { }
%end
extension SIMD3 {
@@ -221,7 +225,7 @@ extension ${Self}: SIMDScalar {
/// Storage for a vector of ${spelledNumbers[n]} integers.
@frozen
@_alignment(${bytes if bytes <= 16 else 16})
public struct SIMD${n}Storage: SIMDStorage, Sendable {
public struct SIMD${n}Storage: SIMDStorage, Sendable, BitwiseCopyable {
public var _value: Builtin.Vec${n}x${BuiltinName}
@@ -275,7 +279,7 @@ extension ${Self} : SIMDScalar {
/// Storage for a vector of ${spelledNumbers[n]} floating-point values.
@frozen
@_alignment(${bytes if bytes <= 16 else 16})
public struct SIMD${n}Storage: SIMDStorage, Sendable {
public struct SIMD${n}Storage: SIMDStorage, Sendable, BitwiseCopyable {
public var _value: Builtin.Vec${n}xFPIEEE${bits}

View File

@@ -48,8 +48,6 @@ Func withoutActuallyEscaping(_:do:) has generic signature change from <ClosureTy
Func withoutActuallyEscaping(_:do:) is now without @rethrows
Protocol SIMDScalar has generic signature change from <Self == Self.SIMD16Storage.Scalar, Self.SIMD16Storage : Swift.SIMDStorage, Self.SIMD2Storage : Swift.SIMDStorage, Self.SIMD32Storage : Swift.SIMDStorage, Self.SIMD4Storage : Swift.SIMDStorage, Self.SIMD64Storage : Swift.SIMDStorage, Self.SIMD8Storage : Swift.SIMDStorage, Self.SIMDMaskScalar : Swift.FixedWidthInteger, Self.SIMDMaskScalar : Swift.SIMDScalar, Self.SIMDMaskScalar : Swift.SignedInteger, Self.SIMD16Storage.Scalar == Self.SIMD2Storage.Scalar, Self.SIMD2Storage.Scalar == Self.SIMD32Storage.Scalar, Self.SIMD32Storage.Scalar == Self.SIMD4Storage.Scalar, Self.SIMD4Storage.Scalar == Self.SIMD64Storage.Scalar, Self.SIMD64Storage.Scalar == Self.SIMD8Storage.Scalar> to <Self : Swift.BitwiseCopyable, Self == Self.SIMD16Storage.Scalar, Self.SIMD16Storage : Swift.SIMDStorage, Self.SIMD2Storage : Swift.SIMDStorage, Self.SIMD32Storage : Swift.SIMDStorage, Self.SIMD4Storage : Swift.SIMDStorage, Self.SIMD64Storage : Swift.SIMDStorage, Self.SIMD8Storage : Swift.SIMDStorage, Self.SIMDMaskScalar : Swift.FixedWidthInteger, Self.SIMDMaskScalar : Swift.SIMDScalar, Self.SIMDMaskScalar : Swift.SignedInteger, Self.SIMDMaskScalar == Self.SIMDMaskScalar.SIMDMaskScalar, Self.SIMD16Storage.Scalar == Self.SIMD2Storage.Scalar, Self.SIMD2Storage.Scalar == Self.SIMD32Storage.Scalar, Self.SIMD32Storage.Scalar == Self.SIMD4Storage.Scalar, Self.SIMD4Storage.Scalar == Self.SIMD64Storage.Scalar, Self.SIMD64Storage.Scalar == Self.SIMD8Storage.Scalar>
Protocol SIMDStorage has generic signature change from <Self.Scalar : Swift.Decodable, Self.Scalar : Swift.Encodable, Self.Scalar : Swift.Hashable> to <Self : Swift.BitwiseCopyable, Self.Scalar : Swift.Decodable, Self.Scalar : Swift.Encodable, Self.Scalar : Swift.Hashable>
Protocol AdditiveArithmetic has added inherited protocol Copyable
Protocol AdditiveArithmetic has added inherited protocol Escapable
@@ -148,13 +146,11 @@ Protocol RangeReplaceableCollection has added inherited protocol Copyable
Protocol RangeReplaceableCollection has added inherited protocol Escapable
Protocol RawRepresentable has added inherited protocol Copyable
Protocol RawRepresentable has added inherited protocol Escapable
Protocol SIMD has added inherited protocol BitwiseCopyable
Protocol SIMD has added inherited protocol Copyable
Protocol SIMD has added inherited protocol Escapable
Protocol SIMDScalar has added inherited protocol BitwiseCopyable
Protocol SIMDScalar has added inherited protocol Copyable
Protocol SIMDScalar has added inherited protocol Escapable
Protocol SIMDStorage has added inherited protocol BitwiseCopyable
Protocol SIMDStorage has added inherited protocol Copyable
Protocol SIMDStorage has added inherited protocol Escapable
Protocol Sequence has added inherited protocol Copyable

View File

@@ -179,11 +179,8 @@ Func ContiguousArray._reserveCapacityImpl(minimumCapacity:growForAppend:) has ma
// it as a removal with the addition of the RangeSet subscripts
Subscript MutableCollection.subscript(_:) has been removed
Protocol SIMD has added inherited protocol BitwiseCopyable
Protocol SIMDScalar has added inherited protocol BitwiseCopyable
Protocol SIMDScalar has generic signature change from <Self == Self.SIMD16Storage.Scalar, Self.SIMD16Storage : Swift.SIMDStorage, Self.SIMD2Storage : Swift.SIMDStorage, Self.SIMD32Storage : Swift.SIMDStorage, Self.SIMD4Storage : Swift.SIMDStorage, Self.SIMD64Storage : Swift.SIMDStorage, Self.SIMD8Storage : Swift.SIMDStorage, Self.SIMDMaskScalar : Swift.FixedWidthInteger, Self.SIMDMaskScalar : Swift.SIMDScalar, Self.SIMDMaskScalar : Swift.SignedInteger, Self.SIMD16Storage.Scalar == Self.SIMD2Storage.Scalar, Self.SIMD2Storage.Scalar == Self.SIMD32Storage.Scalar, Self.SIMD32Storage.Scalar == Self.SIMD4Storage.Scalar, Self.SIMD4Storage.Scalar == Self.SIMD64Storage.Scalar, Self.SIMD64Storage.Scalar == Self.SIMD8Storage.Scalar> to <Self : Swift.BitwiseCopyable, Self == Self.SIMD16Storage.Scalar, Self.SIMD16Storage : Swift.SIMDStorage, Self.SIMD2Storage : Swift.SIMDStorage, Self.SIMD32Storage : Swift.SIMDStorage, Self.SIMD4Storage : Swift.SIMDStorage, Self.SIMD64Storage : Swift.SIMDStorage, Self.SIMD8Storage : Swift.SIMDStorage, Self.SIMDMaskScalar : Swift.FixedWidthInteger, Self.SIMDMaskScalar : Swift.SIMDScalar, Self.SIMDMaskScalar : Swift.SignedInteger, Self.SIMDMaskScalar == Self.SIMDMaskScalar.SIMDMaskScalar, Self.SIMD16Storage.Scalar == Self.SIMD2Storage.Scalar, Self.SIMD2Storage.Scalar == Self.SIMD32Storage.Scalar, Self.SIMD32Storage.Scalar == Self.SIMD4Storage.Scalar, Self.SIMD4Storage.Scalar == Self.SIMD64Storage.Scalar, Self.SIMD64Storage.Scalar == Self.SIMD8Storage.Scalar>
Protocol SIMDStorage has added inherited protocol BitwiseCopyable
Protocol SIMDStorage has generic signature change from <Self.Scalar : Swift.Decodable, Self.Scalar : Swift.Encodable, Self.Scalar : Swift.Hashable> to <Self : Swift.BitwiseCopyable, Self.Scalar : Swift.Decodable, Self.Scalar : Swift.Encodable, Self.Scalar : Swift.Hashable>
Protocol _Pointer has added inherited protocol BitwiseCopyable
Protocol AdditiveArithmetic has added inherited protocol Copyable

View File

@@ -0,0 +1,214 @@
// RUN: %target-typecheck-verify-swift
struct SIMDArrayScalar: BinaryFloatingPoint, SIMDScalar, Codable {
typealias Impl = Float32
typealias RawExponent = Impl.RawExponent
typealias FloatLiteralType = Impl.FloatLiteralType
typealias Exponent = Impl.Exponent
typealias Stride = Impl.Stride
typealias IntegerLiteralType = Impl.IntegerLiteralType
typealias RawSignificand = Impl.RawSignificand
typealias SIMDMaskScalar = Impl.SIMDMaskScalar
typealias SIMD2Storage = SIMDArray<SIMDArrayCount2>
typealias SIMD4Storage = SIMDArray<SIMDArrayCount4>
typealias SIMD8Storage = SIMDArray<SIMDArrayCount8>
typealias SIMD16Storage = SIMDArray<SIMDArrayCount16>
typealias SIMD32Storage = SIMDArray<SIMDArrayCount32>
typealias SIMD64Storage = SIMDArray<SIMDArrayCount64>
var impl: Impl
static var exponentBitCount: Int { Impl.exponentBitCount }
static var significandBitCount: Int { Impl.significandBitCount }
var exponentBitPattern: RawExponent { impl.exponentBitPattern }
var significandBitPattern: RawSignificand { impl.significandBitPattern }
var binade: SIMDArrayScalar { SIMDArrayScalar(impl.binade) }
var significandWidth: Int { impl.significandWidth }
static var nan: SIMDArrayScalar { SIMDArrayScalar(Impl.nan) }
static var signalingNaN: SIMDArrayScalar { SIMDArrayScalar(Impl.signalingNaN) }
static var infinity: SIMDArrayScalar { SIMDArrayScalar(Impl.infinity) }
static var greatestFiniteMagnitude: SIMDArrayScalar { SIMDArrayScalar(Impl.greatestFiniteMagnitude) }
static var pi: SIMDArrayScalar { SIMDArrayScalar(Impl.pi) }
var ulp: SIMDArrayScalar { SIMDArrayScalar(impl.ulp) }
static var leastNormalMagnitude: SIMDArrayScalar { SIMDArrayScalar(Impl.leastNormalMagnitude) }
static var leastNonzeroMagnitude: SIMDArrayScalar { SIMDArrayScalar(Impl.leastNonzeroMagnitude) }
var sign: FloatingPointSign { impl.sign }
var exponent: Exponent { impl.exponent }
var significand: SIMDArrayScalar { SIMDArrayScalar(impl.significand) }
var nextUp: SIMDArrayScalar { SIMDArrayScalar(impl.nextUp) }
var isNormal: Bool { impl.isNormal }
var isFinite: Bool { impl.isFinite }
var isZero: Bool { impl.isZero }
var isSubnormal: Bool { impl.isSubnormal }
var isInfinite: Bool { impl.isInfinite }
var isNaN: Bool { impl.isNaN }
var isSignalingNaN: Bool { impl.isSignalingNaN }
var isCanonical: Bool { impl.isCanonical }
init() {
impl = Impl()
}
init(_ impl: Impl) {
self.impl = impl
}
init(floatLiteral: FloatLiteralType) {
impl = Impl(floatLiteral: floatLiteral)
}
init?<T>(exactly source: T) where T: BinaryInteger {
impl = Impl(source)
}
init(sign: FloatingPointSign, exponent: Float32.Exponent, significand: SIMDArrayScalar) {
impl = Impl(sign: sign, exponent: exponent, significand: significand.impl)
}
init(integerLiteral value: Float32.IntegerLiteralType) {
impl = Impl(integerLiteral: value)
}
init(sign: FloatingPointSign, exponentBitPattern: RawExponent, significandBitPattern: RawSignificand) {
impl = Impl(sign: sign, exponentBitPattern: exponentBitPattern, significandBitPattern: significandBitPattern)
}
var magnitude: SIMDArrayScalar { SIMDArrayScalar(impl.magnitude) }
static func * (lhs: SIMDArrayScalar, rhs: SIMDArrayScalar) -> SIMDArrayScalar {
SIMDArrayScalar(lhs.impl * rhs.impl)
}
static func *= (lhs: inout SIMDArrayScalar, rhs: SIMDArrayScalar) {
lhs.impl *= rhs.impl
}
static func + (lhs: SIMDArrayScalar, rhs: SIMDArrayScalar) -> SIMDArrayScalar {
SIMDArrayScalar(lhs.impl + rhs.impl)
}
static func - (lhs: SIMDArrayScalar, rhs: SIMDArrayScalar) -> SIMDArrayScalar {
SIMDArrayScalar(lhs.impl - rhs.impl)
}
static func / (lhs: SIMDArrayScalar, rhs: SIMDArrayScalar) -> SIMDArrayScalar {
SIMDArrayScalar(lhs.impl / rhs.impl)
}
static func /= (lhs: inout SIMDArrayScalar, rhs: SIMDArrayScalar) {
lhs.impl /= rhs.impl
}
func distance(to other: SIMDArrayScalar) -> Float32.Stride {
impl.distance(to: other.impl)
}
func advanced(by n: Float32.Stride) -> SIMDArrayScalar {
SIMDArrayScalar(impl.advanced(by: n))
}
func isEqual(to other: SIMDArrayScalar) -> Bool {
impl.isEqual(to: other.impl)
}
func isLess(than other: SIMDArrayScalar) -> Bool {
impl.isLess(than: other.impl)
}
func isLessThanOrEqualTo(_ other: SIMDArrayScalar) -> Bool {
impl.isLessThanOrEqualTo(other.impl)
}
mutating func formRemainder(dividingBy other: SIMDArrayScalar) {
impl.formRemainder(dividingBy: other.impl)
}
mutating func formTruncatingRemainder(dividingBy other: SIMDArrayScalar) {
impl.formTruncatingRemainder(dividingBy: other.impl)
}
mutating func formSquareRoot() {
impl.formSquareRoot()
}
mutating func addProduct(_ lhs: SIMDArrayScalar, _ rhs: SIMDArrayScalar) {
impl.addProduct(lhs.impl, rhs.impl)
}
mutating func round(_ rule: FloatingPointRoundingRule) {
impl.round(rule)
}
}
protocol SIMDArrayCount {
static var value: Int { get }
}
struct SIMDArrayCount2: SIMDArrayCount {
static var value: Int { 2 }
}
struct SIMDArrayCount4: SIMDArrayCount {
static var value: Int { 4 }
}
struct SIMDArrayCount8: SIMDArrayCount {
static var value: Int { 8 }
}
struct SIMDArrayCount16: SIMDArrayCount {
static var value: Int { 16 }
}
struct SIMDArrayCount32: SIMDArrayCount {
static var value: Int { 32 }
}
struct SIMDArrayCount64: SIMDArrayCount {
static var value: Int { 64 }
}
struct SIMDArray<Count: SIMDArrayCount>: SIMDStorage {
typealias Scalar = SIMDArrayScalar
var scalarCount: Int { Count.value }
var storage: [Scalar]
init() {
storage = [SIMDArrayScalar](repeating: 0, count: Count.value)
}
subscript(index: Int) -> Scalar {
get { storage[index] }
set(newValue) { storage[index] = newValue }
}
}