|
1 |
| -// RUN: %target-swift-frontend -Xllvm -swiftmergefunc-threshold=0 -parse-as-library -O -target-cpu core2 -emit-ir %s | %FileCheck %s |
| 1 | +// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s |
2 | 2 | // REQUIRES: optimized_stdlib,CPU=x86_64
|
3 | 3 |
|
4 | 4 | // This is an end-to-end test to ensure that the optimizer generates
|
|
12 | 12 | func blackhole<T>(_ value: T) {}
|
13 | 13 |
|
14 | 14 | // UnsafeBufferPointer<UInt8>
|
15 |
| -// ========================== |
16 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}s22utf8_decoding_fastpath15decodeUBPAsUTF8ySSSRys5UInt8VGF{{.*}} |
17 |
| -// CHECK-NOT: _fromCodeUnits |
18 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
19 |
| -// CHECK-NOT: _fromCodeUnits |
20 |
| -// CHECK-LAST: ret |
| 15 | +// |
| 16 | +// CHECK-LABEL: sil {{.*}}decodeUBPAsUTF{{.*}} : $@convention |
| 17 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 18 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 19 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 20 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 21 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 22 | +// CHECK-LABEL: end sil function {{.*}}decodeUBPAsUTF |
21 | 23 | public func decodeUBPAsUTF8(_ ptr: UnsafeBufferPointer<UInt8>) -> String {
|
22 | 24 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
23 | 25 | }
|
24 | 26 |
|
25 | 27 | // UnsafeMutableBufferPointer<UInt8>
|
26 |
| -// ================================= |
27 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}s22utf8_decoding_fastpath16decodeUMBPAsUTF8ySSSrys5UInt8VGF{{.*}} |
28 |
| -// CHECK-NOT: _fromCodeUnits |
29 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
30 |
| -// CHECK-NOT: _fromCodeUnits |
31 |
| -// CHECK-LAST: ret |
| 28 | +// |
| 29 | +// CHECK-LABEL: sil {{.*}}decodeUMBPAsUTF8{{.*}} : $@convention |
| 30 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 31 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 32 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 33 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 34 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 35 | +// CHECK-LABEL: end sil function{{.*}}decodeUMBPAsUTF8 |
32 | 36 | public func decodeUMBPAsUTF8(_ ptr: UnsafeMutableBufferPointer<UInt8>) -> String {
|
33 | 37 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
34 | 38 | }
|
35 | 39 |
|
36 | 40 | // Array<UInt8>
|
37 |
| -// ============ |
38 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeArrayAsUTF8{{.*}} |
39 |
| -// CHECK-NOT: _fromCodeUnits |
40 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
41 |
| -// CHECK-NOT: _fromCodeUnits |
42 |
| -// CHECK-LAST: ret |
| 41 | +// |
| 42 | +// CHECK-LABEL: sil {{.*}}decodeArrayAsUTF8{{.*}} : $@convention |
| 43 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 44 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 45 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 46 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 47 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 48 | +// CHECK-LABEL: end sil function{{.*}}decodeArrayAsUTF8 |
43 | 49 | public func decodeArrayAsUTF8(_ ptr: [UInt8]) -> String {
|
44 | 50 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
45 | 51 | }
|
46 | 52 |
|
47 | 53 | // UnsafeRawBufferPointer
|
48 |
| -// ====================== |
49 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeURBPAsUTF8{{.*}} |
50 |
| -// CHECK-NOT: _fromCodeUnits |
51 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
52 |
| -// CHECK-NOT: _fromCodeUnits |
53 |
| -// CHECK-LAST: ret |
| 54 | +// |
| 55 | +// CHECK-LABEL: sil {{.*}}decodeURBPAsUTF8{{.*}} : $@convention |
| 56 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 57 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 58 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 59 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 60 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 61 | +// CHECK-LABEL: end sil function{{.*}}decodeURBPAsUTF8 |
54 | 62 | public func decodeURBPAsUTF8(_ ptr: UnsafeRawBufferPointer) -> String {
|
55 | 63 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
56 | 64 | }
|
57 | 65 |
|
58 | 66 | // UnsafeMutableRawBufferPointer
|
59 |
| -// ============================= |
60 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeUMRBPAsUTF8{{.*}} |
61 |
| -// CHECK-NOT: _fromCodeUnits |
62 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
63 |
| -// CHECK-NOT: _fromCodeUnits |
64 |
| -// CHECK-LAST: ret |
| 67 | +// |
| 68 | +// CHECK-LABEL: sil {{.*}}decodeUMRBPAsUTF8{{.*}} : $@convention |
| 69 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 70 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 71 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 72 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 73 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 74 | +// CHECK-LABEL: end sil function{{.*}}decodeUMRBPAsUTF8 |
65 | 75 | public func decodeUMRBPAsUTF8(_ ptr: UnsafeMutableRawBufferPointer) -> String {
|
66 | 76 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
67 | 77 | }
|
68 | 78 |
|
69 | 79 | // String.UTF8View
|
70 |
| -// =============== |
71 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeStringUTF8ViewAs{{.*}} |
72 |
| -// CHECK-NOT: _fromCodeUnits |
73 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
74 |
| -// CHECK-NOT: _fromCodeUnits |
75 |
| -// CHECK-LAST: br |
| 80 | +// |
| 81 | +// CHECK-LABEL: sil {{.*}}decodeStringUTF8ViewAs{{.*}} : $@convention |
| 82 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 83 | +// CHECK-DAG: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 84 | +// CHECK-DAG: function_ref {{.*}}_fromUTF8Repairing |
| 85 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 86 | +// CHECK-LABEL: end sil function{{.*}}decodeStringUTF8ViewAs |
76 | 87 | public func decodeStringUTF8ViewAsUTF8(_ ptr: String.UTF8View) -> String {
|
77 | 88 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
78 | 89 | }
|
79 | 90 |
|
80 | 91 | // Substring.UTF8View
|
81 |
| -// ================== |
82 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeSubstringUTF8ViewAs{{.*}} |
83 |
| -// CHECK-NOT: _fromCodeUnits |
84 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
85 |
| -// CHECK-NOT: _fromCodeUnits |
86 |
| -// CHECK-LAST: br |
| 92 | +// |
| 93 | +// NOTE: withContiguousStorageIfAvailable is not currently inlined at the SIL |
| 94 | +// level, so we have to disable the UTF8Repairing check :-( |
| 95 | +// |
| 96 | +// CHECK-LABEL: sil {{.*}}decodeSubstringUTF8ViewAs{{.*}} : $@convention |
| 97 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 98 | +// CHECK-DAG: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 99 | +// xCHECK-DAG: function_ref {{.*}}_fromUTF8Repairing |
| 100 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 101 | +// CHECK-LABEL: end sil function{{.*}}decodeSubstringUTF8ViewAs |
87 | 102 | public func decodeSubstringUTF8ViewAsUTF8(_ ptr: Substring.UTF8View) -> String {
|
88 | 103 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
89 | 104 | }
|
90 | 105 |
|
91 | 106 | // Slice<UBP>
|
92 |
| -// ========== |
93 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeUBPSliceAsUTF8{{.*}} |
94 |
| -// CHECK-NOT: _fromCodeUnits |
95 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
96 |
| -// CHECK-NOT: _fromCodeUnits |
97 |
| -// CHECK-LAST: br |
| 107 | +// |
| 108 | +// CHECK-LABEL: sil {{.*}}decodeUBPSliceAsUTF8{{.*}} : $@convention |
| 109 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 110 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 111 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 112 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 113 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 114 | +// CHECK-LABEL: end sil function{{.*}}decodeUBPSliceAsUTF8 |
98 | 115 | public func decodeUBPSliceAsUTF8(_ ptr: Slice<UnsafeBufferPointer<UInt8>>) -> String {
|
99 | 116 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
100 | 117 | }
|
101 | 118 |
|
102 | 119 | // Slice<URBP>
|
103 |
| -// =========== |
104 |
| -// CHECK-LABEL: define {{.*}}swiftcc {{.*}}decodeURBPSliceAsUTF8{{.*}} |
105 |
| -// CHECK-NOT: _fromCodeUnits |
106 |
| -// CHECK: {{.*}} = call swiftcc {{.*}} @"$sSS18_fromUTF8Repairing{{.*}} |
107 |
| -// CHECK-NOT: _fromCodeUnits |
108 |
| -// CHECK: ret |
| 120 | +// |
| 121 | +// CHECK-LABEL: sil {{.*}}decodeURBPSliceAsUTF8{{.*}} : $@convention |
| 122 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 123 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 124 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 125 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 126 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 127 | +// CHECK-LABEL: end sil function{{.*}}decodeURBPSliceAsUTF8 |
109 | 128 | public func decodeURBPSliceAsUTF8(_ ptr: Slice<UnsafeBufferPointer<UInt8>>) -> String {
|
110 |
| - blackhole("foo") // otherwise it just jumps into the Slice<UBP> version |
111 | 129 | return String(decoding: ptr, as: Unicode.UTF8.self)
|
112 | 130 | }
|
| 131 | + |
| 132 | +public struct CustomContiguousCollection: Collection { |
| 133 | + let storage: [UInt8] |
| 134 | + public typealias Index = Int |
| 135 | + public typealias Element = UInt8 |
| 136 | + |
| 137 | + public init(_ bytes: [UInt8]) { self.storage = bytes } |
| 138 | + public subscript(position: Int) -> Element { self.storage[position] } |
| 139 | + public var startIndex: Index { 0 } |
| 140 | + public var endIndex: Index { storage.count } |
| 141 | + public func index(after i: Index) -> Index { i+1 } |
| 142 | + |
| 143 | + @inline(__always) |
| 144 | + public func withContiguousStorageIfAvailable<R>( |
| 145 | + _ body: (UnsafeBufferPointer<UInt8>) throws -> R |
| 146 | + ) rethrows -> R? { |
| 147 | + try storage.withContiguousStorageIfAvailable(body) |
| 148 | + } |
| 149 | +} |
| 150 | +public struct CustomNonContiguousCollection: Collection { |
| 151 | + let storage: [UInt8] |
| 152 | + public typealias Index = Int |
| 153 | + public typealias Element = UInt8 |
| 154 | + |
| 155 | + public init(_ bytes: [UInt8]) { self.storage = bytes } |
| 156 | + public subscript(position: Int) -> Element { self.storage[position] } |
| 157 | + public var startIndex: Index { 0 } |
| 158 | + public var endIndex: Index { storage.count } |
| 159 | + public func index(after i: Index) -> Index { i+1 } |
| 160 | + |
| 161 | + @inline(__always) |
| 162 | + public func withContiguousStorageIfAvailable<R>( |
| 163 | + _ body: (UnsafeBufferPointer<UInt8>) throws -> R |
| 164 | + ) rethrows -> R? { |
| 165 | + nil |
| 166 | + } |
| 167 | +} |
| 168 | + |
| 169 | +// CustomContiguousCollection |
| 170 | +// |
| 171 | +// CHECK-LABEL: sil {{.*}}decodeCustomContiguousAsUTF8{{.*}} : $@convention |
| 172 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 173 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 174 | +// CHECK: function_ref {{.*}}_fromUTF8Repairing |
| 175 | +// CHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 176 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 177 | +// CHECK-LABEL: end sil function{{.*}}decodeCustomContiguousAsUTF8 |
| 178 | +public func decodeCustomContiguousAsUTF8(_ c: CustomContiguousCollection) -> String { |
| 179 | + return String(decoding: c, as: UTF8.self) |
| 180 | +} |
| 181 | + |
| 182 | +// CustomNonContiguousCollection |
| 183 | +// |
| 184 | +// CHECK-LABEL: sil {{.*}}decodeCustomNonContiguousAsUTF8{{.*}} : $@convention |
| 185 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 186 | +// CHECK-NOT: function_ref {{.*}}_fromUTF8Repairing |
| 187 | +// CHECK: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 188 | +// CHECK-NOT: function_ref {{.*}}_fromCodeUnits |
| 189 | +// CHECK-NOT: function_ref {{.*}}_fromUTF8Repairing |
| 190 | +// CHECK-LABEL: end sil function{{.*}}decodeCustomNonContiguousAsUTF8 |
| 191 | +public func decodeCustomNonContiguousAsUTF8(_ c: CustomNonContiguousCollection) -> String { |
| 192 | + return String(decoding: c, as: UTF8.self) |
| 193 | +} |
| 194 | + |
| 195 | +// UTF-16 |
| 196 | +// |
| 197 | +// NOTE: The SIL optimizer cannot currently fold away a (UTF16.self == |
| 198 | +// UTF8.self) metatype comparison, so we have to disabel the check-not for UTF-8 |
| 199 | +// construction :-( |
| 200 | +// |
| 201 | +// CHECK-LABEL: sil {{.*}}decodeUTF16{{.*}} : $@convention |
| 202 | +// xCHECK-NOT: function_ref {{.*}}_fromUTF8Repairing |
| 203 | +// xCHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 204 | +// CHECK: function_ref {{.*}}_fromCodeUnits |
| 205 | +// xCHECK-NOT: function_ref {{.*}}_fromUTF8Repairing |
| 206 | +// xCHECK-NOT: function_ref {{.*}}_fromNonContiguousUnsafeBitcastUTF8Repairing |
| 207 | +// CHECK-LABEL: end sil function{{.*}}decodeUTF16 |
| 208 | +public func decodeUTF16(_ c: Array<UInt16>) -> String { |
| 209 | + return String(decoding: c, as: UTF16.self) |
| 210 | +} |
0 commit comments