Skip to content

Commit dc8e287

Browse files
committed
Move most of the simd operators into an optional module
Adding simd to the stdlib caused some typechecker regressions. We can resolve them in the near-term by making the types universally available, but moving the arithmetic operators into a separate module that must be explicitly imported.
1 parent 67ec3b7 commit dc8e287

File tree

6 files changed

+350
-334
lines changed

6 files changed

+350
-334
lines changed

stdlib/public/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ if(SWIFT_BUILD_STDLIB)
5555
add_subdirectory(runtime)
5656
add_subdirectory(stubs)
5757
add_subdirectory(core)
58+
add_subdirectory(SIMDOperators)
5859
add_subdirectory(SwiftOnoneSupport)
5960
endif()
6061

stdlib/public/SDK/simd/Quaternion.swift.gyb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import Swift
1616
import Darwin
17+
import SIMDOperators
1718
@_exported import simd
1819

1920
%for scalar in ['Float','Double']:

stdlib/public/SDK/simd/simd.swift.gyb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import Swift
1616
import Darwin
17+
@_exported import SIMDOperators
1718
@_exported import simd
1819

1920
public extension SIMD {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
add_swift_target_library(swiftSIMDOperators ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
2+
Operators.swift
3+
4+
SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
5+
SWIFT_COMPILE_FLAGS
6+
LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
7+
)
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
infix operator .& : LogicalConjunctionPrecedence
2+
infix operator .^ : LogicalDisjunctionPrecedence
3+
infix operator .| : LogicalDisjunctionPrecedence
4+
infix operator .&= : AssignmentPrecedence
5+
infix operator .^= : AssignmentPrecedence
6+
infix operator .|= : AssignmentPrecedence
7+
prefix operator .!
8+
9+
// Implementations of integer operations. These should eventually all
10+
// be replaced with @_semantics to lower directly to vector IR nodes.
11+
public extension SIMD where Scalar : FixedWidthInteger {
12+
@_transparent
13+
var leadingZeroBitCount: Self {
14+
var result = Self()
15+
for i in indices { result[i] = Scalar(self[i].leadingZeroBitCount) }
16+
return result
17+
}
18+
19+
@_transparent
20+
var trailingZeroBitCount: Self {
21+
var result = Self()
22+
for i in indices { result[i] = Scalar(self[i].trailingZeroBitCount) }
23+
return result
24+
}
25+
26+
@_transparent
27+
var nonzeroBitCount: Self {
28+
var result = Self()
29+
for i in indices { result[i] = Scalar(self[i].nonzeroBitCount) }
30+
return result
31+
}
32+
33+
@_transparent
34+
static prefix func ~(rhs: Self) -> Self {
35+
var result = Self()
36+
for i in result.indices { result[i] = ~rhs[i] }
37+
return result
38+
}
39+
40+
@_transparent
41+
static func &(lhs: Self, rhs: Self) -> Self {
42+
var result = Self()
43+
for i in result.indices { result[i] = lhs[i] & rhs[i] }
44+
return result
45+
}
46+
47+
@_transparent
48+
static func ^(lhs: Self, rhs: Self) -> Self {
49+
var result = Self()
50+
for i in result.indices { result[i] = lhs[i] ^ rhs[i] }
51+
return result
52+
}
53+
54+
@_transparent
55+
static func |(lhs: Self, rhs: Self) -> Self {
56+
var result = Self()
57+
for i in result.indices { result[i] = lhs[i] | rhs[i] }
58+
return result
59+
}
60+
61+
@_transparent
62+
static func &<<(lhs: Self, rhs: Self) -> Self {
63+
var result = Self()
64+
for i in result.indices { result[i] = lhs[i] &<< rhs[i] }
65+
return result
66+
}
67+
68+
@_transparent
69+
static func &>>(lhs: Self, rhs: Self) -> Self {
70+
var result = Self()
71+
for i in result.indices { result[i] = lhs[i] &>> rhs[i] }
72+
return result
73+
}
74+
75+
@_transparent
76+
static func &+(lhs: Self, rhs: Self) -> Self {
77+
var result = Self()
78+
for i in result.indices { result[i] = lhs[i] &+ rhs[i] }
79+
return result
80+
}
81+
82+
@_transparent
83+
static func &-(lhs: Self, rhs: Self) -> Self {
84+
var result = Self()
85+
for i in result.indices { result[i] = lhs[i] &- rhs[i] }
86+
return result
87+
}
88+
89+
@_transparent
90+
static func &*(lhs: Self, rhs: Self) -> Self {
91+
var result = Self()
92+
for i in result.indices { result[i] = lhs[i] &* rhs[i] }
93+
return result
94+
}
95+
96+
@_transparent
97+
static func /(lhs: Self, rhs: Self) -> Self {
98+
var result = Self()
99+
for i in result.indices { result[i] = lhs[i] / rhs[i] }
100+
return result
101+
}
102+
103+
@_transparent
104+
static func %(lhs: Self, rhs: Self) -> Self {
105+
var result = Self()
106+
for i in result.indices { result[i] = lhs[i] % rhs[i] }
107+
return result
108+
}
109+
}
110+
111+
// Implementations of floating-point operations. These should eventually all
112+
// be replaced with @_semantics to lower directly to vector IR nodes.
113+
public extension SIMD where Scalar : FloatingPoint {
114+
@_transparent
115+
static func +(lhs: Self, rhs: Self) -> Self {
116+
var result = Self()
117+
for i in result.indices { result[i] = lhs[i] + rhs[i] }
118+
return result
119+
}
120+
121+
@_transparent
122+
static func -(lhs: Self, rhs: Self) -> Self {
123+
var result = Self()
124+
for i in result.indices { result[i] = lhs[i] - rhs[i] }
125+
return result
126+
}
127+
128+
@_transparent
129+
static func *(lhs: Self, rhs: Self) -> Self {
130+
var result = Self()
131+
for i in result.indices { result[i] = lhs[i] * rhs[i] }
132+
return result
133+
}
134+
135+
@_transparent
136+
static func /(lhs: Self, rhs: Self) -> Self {
137+
var result = Self()
138+
for i in result.indices { result[i] = lhs[i] / rhs[i] }
139+
return result
140+
}
141+
142+
@_transparent
143+
func addingProduct(_ lhs: Self, _ rhs: Self) -> Self {
144+
var result = Self()
145+
for i in result.indices { result[i] = self[i].addingProduct(lhs[i], rhs[i]) }
146+
return result
147+
}
148+
149+
@_transparent
150+
func squareRoot( ) -> Self {
151+
var result = Self()
152+
for i in result.indices { result[i] = self[i].squareRoot() }
153+
return result
154+
}
155+
156+
@_transparent
157+
func rounded(_ rule: FloatingPointRoundingRule) -> Self {
158+
var result = Self()
159+
for i in result.indices { result[i] = self[i].rounded(rule) }
160+
return result
161+
}
162+
}
163+
164+
public extension SIMDMask {
165+
@_transparent
166+
static prefix func .!(rhs: SIMDMask) -> SIMDMask {
167+
return SIMDMask(~rhs._storage)
168+
}
169+
170+
@_transparent
171+
static func .&(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
172+
return SIMDMask(lhs._storage & rhs._storage)
173+
}
174+
175+
@_transparent
176+
static func .^(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
177+
return SIMDMask(lhs._storage ^ rhs._storage)
178+
}
179+
180+
@_transparent
181+
static func .|(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
182+
return SIMDMask(lhs._storage | rhs._storage)
183+
}
184+
}
185+
186+
// These operations should never need @_semantics; they should be trivial
187+
// wrappers around the core operations defined above.
188+
public extension SIMD where Scalar : FixedWidthInteger {
189+
@_transparent static func &(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) & rhs }
190+
@_transparent static func ^(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) ^ rhs }
191+
@_transparent static func |(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) | rhs }
192+
@_transparent static func &<<(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &<< rhs }
193+
@_transparent static func &>>(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &>> rhs }
194+
@_transparent static func &+(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &+ rhs }
195+
@_transparent static func &-(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &- rhs }
196+
@_transparent static func &*(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &* rhs }
197+
@_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
198+
@_transparent static func %(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) % rhs }
199+
200+
@_transparent static func &(lhs: Self, rhs: Scalar) -> Self { return lhs & Self(repeating: rhs) }
201+
@_transparent static func ^(lhs: Self, rhs: Scalar) -> Self { return lhs ^ Self(repeating: rhs) }
202+
@_transparent static func |(lhs: Self, rhs: Scalar) -> Self { return lhs | Self(repeating: rhs) }
203+
@_transparent static func &<<(lhs: Self, rhs: Scalar) -> Self { return lhs &<< Self(repeating: rhs) }
204+
@_transparent static func &>>(lhs: Self, rhs: Scalar) -> Self { return lhs &>> Self(repeating: rhs) }
205+
@_transparent static func &+(lhs: Self, rhs: Scalar) -> Self { return lhs &+ Self(repeating: rhs) }
206+
@_transparent static func &-(lhs: Self, rhs: Scalar) -> Self { return lhs &- Self(repeating: rhs) }
207+
@_transparent static func &*(lhs: Self, rhs: Scalar) -> Self { return lhs &* Self(repeating: rhs) }
208+
@_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
209+
@_transparent static func %(lhs: Self, rhs: Scalar) -> Self { return lhs % Self(repeating: rhs) }
210+
211+
@_transparent static func &=(lhs: inout Self, rhs: Self) { lhs = lhs & rhs }
212+
@_transparent static func ^=(lhs: inout Self, rhs: Self) { lhs = lhs ^ rhs }
213+
@_transparent static func |=(lhs: inout Self, rhs: Self) { lhs = lhs | rhs }
214+
@_transparent static func &<<=(lhs: inout Self, rhs: Self) { lhs = lhs &<< rhs }
215+
@_transparent static func &>>=(lhs: inout Self, rhs: Self) { lhs = lhs &>> rhs }
216+
@_transparent static func &+=(lhs: inout Self, rhs: Self) { lhs = lhs &+ rhs }
217+
@_transparent static func &-=(lhs: inout Self, rhs: Self) { lhs = lhs &- rhs }
218+
@_transparent static func &*=(lhs: inout Self, rhs: Self) { lhs = lhs &* rhs }
219+
@_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
220+
@_transparent static func %=(lhs: inout Self, rhs: Self) { lhs = lhs % rhs }
221+
222+
@_transparent static func &=(lhs: inout Self, rhs: Scalar) { lhs = lhs & rhs }
223+
@_transparent static func ^=(lhs: inout Self, rhs: Scalar) { lhs = lhs ^ rhs }
224+
@_transparent static func |=(lhs: inout Self, rhs: Scalar) { lhs = lhs | rhs }
225+
@_transparent static func &<<=(lhs: inout Self, rhs: Scalar) { lhs = lhs &<< rhs }
226+
@_transparent static func &>>=(lhs: inout Self, rhs: Scalar) { lhs = lhs &>> rhs }
227+
@_transparent static func &+=(lhs: inout Self, rhs: Scalar) { lhs = lhs &+ rhs }
228+
@_transparent static func &-=(lhs: inout Self, rhs: Scalar) { lhs = lhs &- rhs }
229+
@_transparent static func &*=(lhs: inout Self, rhs: Scalar) { lhs = lhs &* rhs }
230+
@_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
231+
@_transparent static func %=(lhs: inout Self, rhs: Scalar) { lhs = lhs % rhs }
232+
233+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
234+
static func +(lhs: Self, rhs: Self) -> Self { fatalError() }
235+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
236+
static func -(lhs: Self, rhs: Self) -> Self { fatalError() }
237+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
238+
static func *(lhs: Self, rhs: Self) -> Self { fatalError() }
239+
240+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
241+
static func +(lhs: Self, rhs: Scalar) -> Self { fatalError() }
242+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
243+
static func -(lhs: Self, rhs: Scalar) -> Self { fatalError() }
244+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
245+
static func *(lhs: Self, rhs: Scalar) -> Self { fatalError() }
246+
247+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
248+
static func +(lhs: Scalar, rhs: Self) -> Self { fatalError() }
249+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
250+
static func -(lhs: Scalar, rhs: Self) -> Self { fatalError() }
251+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
252+
static func *(lhs: Scalar, rhs: Self) -> Self { fatalError() }
253+
254+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
255+
static func +=(lhs: inout Self, rhs: Self) { fatalError() }
256+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
257+
static func -=(lhs: inout Self, rhs: Self) { fatalError() }
258+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
259+
static func *=(lhs: inout Self, rhs: Self) { fatalError() }
260+
261+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
262+
static func +=(lhs: inout Self, rhs: Scalar) { fatalError() }
263+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
264+
static func -=(lhs: inout Self, rhs: Scalar) { fatalError() }
265+
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
266+
static func *=(lhs: inout Self, rhs: Scalar) { fatalError() }
267+
}
268+
269+
public extension SIMD where Scalar : FloatingPoint {
270+
@_transparent static prefix func -(rhs: Self) -> Self { return 0 - rhs }
271+
272+
@_transparent static func +(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) + rhs }
273+
@_transparent static func -(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) - rhs }
274+
@_transparent static func *(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) * rhs }
275+
@_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
276+
277+
@_transparent static func +(lhs: Self, rhs: Scalar) -> Self { return lhs + Self(repeating: rhs) }
278+
@_transparent static func -(lhs: Self, rhs: Scalar) -> Self { return lhs - Self(repeating: rhs) }
279+
@_transparent static func *(lhs: Self, rhs: Scalar) -> Self { return lhs * Self(repeating: rhs) }
280+
@_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
281+
282+
@_transparent static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs }
283+
@_transparent static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs }
284+
@_transparent static func *=(lhs: inout Self, rhs: Self) { lhs = lhs * rhs }
285+
@_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
286+
287+
@_transparent static func +=(lhs: inout Self, rhs: Scalar) { lhs = lhs + rhs }
288+
@_transparent static func -=(lhs: inout Self, rhs: Scalar) { lhs = lhs - rhs }
289+
@_transparent static func *=(lhs: inout Self, rhs: Scalar) { lhs = lhs * rhs }
290+
@_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
291+
292+
@_transparent func addingProduct(_ lhs: Scalar, _ rhs: Self) -> Self {
293+
return self.addingProduct(Self(repeating: lhs), rhs)
294+
}
295+
@_transparent func addingProduct(_ lhs: Self, _ rhs: Scalar) -> Self {
296+
return self.addingProduct(lhs, Self(repeating: rhs))
297+
}
298+
@_transparent mutating func addProduct(_ lhs: Self, _ rhs: Self) {
299+
self = self.addingProduct(lhs, rhs)
300+
}
301+
@_transparent mutating func addProduct(_ lhs: Scalar, _ rhs: Self) {
302+
self = self.addingProduct(lhs, rhs)
303+
}
304+
@_transparent mutating func addProduct(_ lhs: Self, _ rhs: Scalar) {
305+
self = self.addingProduct(lhs, rhs)
306+
}
307+
308+
@_transparent mutating func formSquareRoot( ) {
309+
self = self.squareRoot()
310+
}
311+
312+
@_transparent mutating func round(_ rule: FloatingPointRoundingRule) {
313+
self = self.rounded(rule)
314+
}
315+
}
316+
317+
public extension SIMDMask {
318+
@_transparent static func .&(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .& rhs }
319+
@_transparent static func .^(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .^ rhs }
320+
@_transparent static func .|(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .| rhs }
321+
322+
@_transparent static func .&(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .& SIMDMask(repeating: rhs) }
323+
@_transparent static func .^(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .^ SIMDMask(repeating: rhs) }
324+
@_transparent static func .|(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .| SIMDMask(repeating: rhs) }
325+
326+
@_transparent static func .&=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .& rhs }
327+
@_transparent static func .^=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .^ rhs }
328+
@_transparent static func .|=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .| rhs }
329+
330+
@_transparent static func .&=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .& rhs }
331+
@_transparent static func .^=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .^ rhs }
332+
@_transparent static func .|=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .| rhs }
333+
}

0 commit comments

Comments
 (0)