mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
113 lines
3.9 KiB
Swift
113 lines
3.9 KiB
Swift
// This is an end-to-end test case of a speculative design for SIMD types using
|
|
// polymorphic builtins. It is just intended to exercise the functional intended
|
|
// behavior of _isConcrete + polymorphic builtins and that this functionality
|
|
// keeps on working. It is not intended to push any future simd designs in any
|
|
// direction, just validate that this speculative design keeps working as
|
|
// expected.
|
|
|
|
// RUN: %empty-directory(%t)
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(mysimd)) -enable-builtin-module -enable-library-evolution %S/../Inputs/polymorphic_builtins.swift -emit-module -emit-module-path %t/mysimd.swiftmodule -module-name mysimd -D DEBUG -Onone
|
|
// RUN: %target-codesign %t/%target-library-name(mysimd)
|
|
|
|
// RUN: %target-build-swift -enable-builtin-module %s -L %t -I %t -lmysimd -Xfrontend -disable-access-control -Xfrontend -sil-verify-all %target-rpath(%t) -o %t/a.out -D DEBUG -Onone
|
|
// RUN: %target-codesign %t/a.out
|
|
|
|
// RUN: %target-run %t/a.out %t/%target-library-name(mysimd)
|
|
|
|
// RUN: %empty-directory(%t)
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(mysimd)) -enable-builtin-module -enable-library-evolution %S/../Inputs/polymorphic_builtins.swift -emit-module -emit-module-path %t/mysimd.swiftmodule -module-name mysimd -O
|
|
// RUN: %target-codesign %t/%target-library-name(mysimd)
|
|
|
|
// RUN: %target-build-swift -enable-builtin-module %s -L %t -I %t -lmysimd -Xfrontend -disable-access-control -Xfrontend -sil-verify-all %target-rpath(%t) -o %t/a.out -O
|
|
// RUN: %target-codesign %t/a.out
|
|
|
|
// RUN: %target-run %t/a.out %t/%target-library-name(mysimd)
|
|
|
|
// REQUIRES: executable_test
|
|
|
|
import Builtin
|
|
import StdlibUnittest
|
|
import mysimd
|
|
|
|
// Defer running all of the tests to end of file.
|
|
defer { runAllTests() }
|
|
|
|
// Implement the full specialization scheme, checking where we crash.
|
|
var Tests = TestSuite("Polymorphic Builtins")
|
|
|
|
Tests.test("Direct Dispatch + Transparent => Get right result") {
|
|
let inputs: [Int32] = [5,6,7,8]
|
|
let expectedOutputs: [Int32] = inputs.map { $0 &+ $0 }
|
|
|
|
let x = mysimd.SIMD4<Int32>(inputs)
|
|
let y = x &+ x
|
|
|
|
expectEqual(expectedOutputs, y.asArray)
|
|
}
|
|
|
|
public protocol Bar {
|
|
associatedtype SIMDTy : SIMD
|
|
func callAddGuarded(_ t: SIMDTy) -> SIMDTy
|
|
func callMulUnguarded(_ t: SIMDTy) -> SIMDTy
|
|
}
|
|
|
|
public struct Foo<T : SIMD> where T.Scalar : FixedWidthInteger {
|
|
}
|
|
|
|
extension Foo : Bar {
|
|
typealias SIMDTy = T
|
|
|
|
@_transparent
|
|
func callAddGuarded(_ t: T) -> T {
|
|
return t &+ t
|
|
}
|
|
|
|
@_transparent
|
|
func callMulUnguarded(_ t: T) -> T {
|
|
return t &* t
|
|
}
|
|
}
|
|
|
|
func callBarAdd<T: Bar, U : SIMD>(_ t: T, _ u: U) -> U where T.SIMDTy == U {
|
|
return t.callAddGuarded(u)
|
|
}
|
|
|
|
func callBarMul<T: Bar, U : SIMD>(_ t: T, _ u: U) -> U where T.SIMDTy == U {
|
|
return t.callMulUnguarded(u)
|
|
}
|
|
|
|
// In this case, we have guarded inside the add function using _isConcrete. So
|
|
// we should go down the slow path even though we are calling through a vtable
|
|
// (and thus are going along the generic code path).
|
|
Tests.test("Indirect Dispatch + Transparent + _isConcrete Guard == OK") {
|
|
let inputs: [Int32] = [5,6,7,8]
|
|
let expectedOutputs: [Int32] = inputs.map { $0 &+ $0 }
|
|
|
|
let x = mysimd.SIMD4<Int32>(inputs)
|
|
let f = Foo<mysimd.SIMD4<Int32>>()
|
|
let y = callBarAdd(f, x)
|
|
expectEqual(expectedOutputs, y.asArray)
|
|
}
|
|
|
|
// In this case, we call mul which is unguarded with _isConcrete and thus
|
|
// crashes in Debug, but in Release we (after inlining/specialization) /do/
|
|
// succeed. This is one reason why _isConcrete is needed.
|
|
//
|
|
// The stdlib maintainer should have guarded this usage to ensure that we did
|
|
// not go down this code path.
|
|
|
|
Tests.test("Indirect Dispatch + Transparent + No _isConcrete Guard == Crash when Debug") {
|
|
#if DEBUG
|
|
expectCrashLater()
|
|
#endif
|
|
let inputs: [Int32] = [5,6,7,8]
|
|
let expectedOutputs: [Int32] = inputs.map { $0 &* $0 }
|
|
|
|
let x = mysimd.SIMD4<Int32>(inputs)
|
|
let f = Foo<mysimd.SIMD4<Int32>>()
|
|
let y = callBarMul(f, x)
|
|
expectEqual(expectedOutputs, y.asArray)
|
|
}
|