File: polymorphic_builtins.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (112 lines) | stat: -rw-r--r-- 3,951 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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-library-evolution %S/../Inputs/polymorphic_builtins.swift -emit-module -emit-module-path %t/mysimd.swiftmodule -module-name mysimd -parse-stdlib -D DEBUG -Onone
// RUN: %target-codesign %t/%target-library-name(mysimd)

// RUN: %target-build-swift %s -L %t -I %t -lmysimd -parse-stdlib -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-library-evolution %S/../Inputs/polymorphic_builtins.swift -emit-module -emit-module-path %t/mysimd.swiftmodule -module-name mysimd -parse-stdlib -O
// RUN: %target-codesign %t/%target-library-name(mysimd)

// RUN: %target-build-swift %s -L %t -I %t -lmysimd -parse-stdlib -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 Swift
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)
}