Skip to content

Commit 351300e

Browse files
committed
[Distributed] Runtime/NFC: Split accessor thunk tests into 32/64 bit versions
1 parent 8d14443 commit 351300e

File tree

2 files changed

+336
-0
lines changed

2 files changed

+336
-0
lines changed
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift
3+
// RUN: %target-swift-frontend -module-name distributed_actor_accessors -emit-irgen -enable-experimental-distributed -disable-availability-checking -I %t 2>&1 %s | %IRGenFileCheck %s
4+
5+
// UNSUPPORTED: back_deploy_concurrency
6+
// REQUIRES: concurrency
7+
// REQUIRES: distributed
8+
9+
// REQUIRES: CPU=i386
10+
11+
import _Distributed
12+
import FakeDistributedActorSystems
13+
14+
@available(SwiftStdlib 5.5, *)
15+
typealias DefaultDistributedActorSystem = FakeActorSystem
16+
17+
enum SimpleE : Codable {
18+
case a
19+
}
20+
21+
enum E : Codable {
22+
case a, b, c
23+
}
24+
25+
enum IndirectE : Codable {
26+
case empty
27+
indirect case test(_: Int)
28+
}
29+
30+
final class Obj : Codable, Sendable {
31+
let x: Int
32+
33+
init(x: Int) {
34+
self.x = x
35+
}
36+
}
37+
38+
struct LargeStruct : Codable {
39+
var a: Int
40+
var b: Int
41+
var c: String
42+
var d: Double
43+
}
44+
45+
@available(SwiftStdlib 5.6, *)
46+
public distributed actor MyActor {
47+
distributed func simple1(_: Int) {
48+
}
49+
50+
// `String` would be a direct result as a struct type
51+
distributed func simple2(_: Int) -> String {
52+
return ""
53+
}
54+
55+
// `String` is an object that gets exploded into two parameters
56+
distributed func simple3(_: String) -> Int {
57+
return 42
58+
}
59+
60+
// Enum with a single case are special because they have an empty
61+
// native schema so they are dropped from parameters/result.
62+
distributed func single_case_enum(_ e: SimpleE) -> SimpleE {
63+
return e
64+
}
65+
66+
distributed func with_indirect_enums(_: IndirectE, _: Int) -> IndirectE {
67+
return .empty
68+
}
69+
70+
// Combination of multiple arguments, reference type and indirect result
71+
//
72+
// Note: Tuple types cannot be used here is either position because they
73+
// cannot conform to protocols.
74+
distributed func complex(_: [Int], _: Obj, _: String?, _: LargeStruct) -> LargeStruct {
75+
fatalError()
76+
}
77+
}
78+
79+
@available(SwiftStdlib 5.6, *)
80+
public distributed actor MyOtherActor {
81+
distributed func empty() {
82+
}
83+
}
84+
85+
/// ---> Thunk and distributed method accessor for `simple1`
86+
87+
/// Let's make sure that accessor loads the data from the buffer and calls expected accessor
88+
89+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE"
90+
91+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETF"(%swift.context* swiftasync %0, i8* %1, i8* %2, %swift.refcounted* swiftself %3)
92+
93+
/// Read the current offset and cast an element to `Int`
94+
95+
// CHECK: store i8* %1, i8** %offset
96+
// CHECK-NEXT: %elt_offset = load i8*, i8** %offset
97+
// CHECK-NEXT: [[ELT_PTR:%.*]] = bitcast i8* %elt_offset to %TSi*
98+
// CHECK-NEXT: [[NATIVE_VAL_LOC:%.*]] = getelementptr inbounds %TSi, %TSi* [[ELT_PTR]], i32 0, i32 0
99+
// CHECK-NEXT: [[ARG_VAL:%.*]] = load i32, i32* [[NATIVE_VAL_LOC]]
100+
101+
/// Retrieve an async pointer to the distributed thunk for `simple1`
102+
103+
// CHECK: [[THUNK_LOC:%.*]] = add i32 ptrtoint (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE" to i32), {{.*}}
104+
// CHECK-NEXT: [[OPAQUE_THUNK_PTR:%.*]] = inttoptr i32 [[THUNK_LOC]] to i8*
105+
// CHECK-NEXT: [[THUNK_PTR:%.*]] = bitcast i8* [[OPAQUE_THUNK_PTR]] to void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)*
106+
107+
/// Call distributed thunk for `simple1` and `end` async context without results
108+
109+
// CHECK: [[THUNK_PTR_REF:%.*]] = bitcast void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* [[THUNK_PTR]] to i8*
110+
// CHECK-NEXT: [[THUNK_RESULT:%.*]] = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.errorss({{.*}}, i8* [[THUNK_PTR_REF]], %swift.context* {{.*}}, i32 [[ARG_VAL]], %T27distributed_actor_accessors7MyActorC* {{.*}})
111+
// CHECK-NEXT: [[TASK_REF:%.*]] = extractvalue { i8*, %swift.error* } [[THUNK_RESULT]], 0
112+
// CHECK-NEXT: {{.*}} = call i8* @__swift_async_resume_project_context(i8* [[TASK_REF]])
113+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
114+
115+
/// ---> Thunk and distributed method accessor for `simple2`
116+
117+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE"
118+
119+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETF"
120+
121+
// CHECK: [[COERCED_RESULT_SLOT:%.*]] = bitcast i8* {{.*}} to %TSS*
122+
123+
/// !!! - We are not going to double-check argument extraction here since it's the same as `simple1`.
124+
// CHECK: [[NATIVE_ARG_VAL:%.*]] = load i32, i32* {{.*}}
125+
126+
/// Load async pointer to distributed thunk for `simple2`
127+
128+
// CHECK: [[THUNK_LOC:%.*]] = add i32 ptrtoint (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE" to i32), {{.*}}
129+
// CHECK-NEXT: [[OPAQUE_THUNK_PTR:%.*]] = inttoptr i32 [[THUNK_LOC]] to i8*
130+
// CHECK-NEXT: [[THUNK_PTR:%.*]] = bitcast i8* [[OPAQUE_THUNK_PTR]] to void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)*
131+
132+
/// Call the thunk with extracted argument value
133+
134+
// CHECK: [[THUNK_PTR_REF:%.*]] = bitcast void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* [[THUNK_PTR]] to i8*
135+
// CHECK-NEXT: [[THUNK_RESULT:%.*]] = call { i8*, i32, i32, i32, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i32i32i32p0s_swift.errorss({{.*}}, i8* [[THUNK_PTR_REF]], %swift.context* {{.*}}, i32 [[NATIVE_ARG_VAL]], %T27distributed_actor_accessors7MyActorC* {{.*}})
136+
// CHECK-NEXT: [[TASK_REF:%.*]] = extractvalue { i8*, i32, i32, i32, %swift.error* } [[THUNK_RESULT]], 0
137+
// CHECK-NEXT: {{.*}} = call i8* @__swift_async_resume_project_context(i8* [[TASK_REF]])
138+
139+
/// Initialize the result buffer with values produced by the thunk
140+
141+
// CHECK: %._guts1 = getelementptr inbounds %TSS, %TSS* [[COERCED_RESULT_SLOT]], i32 0, i32 0
142+
// CHECK: store i32 {{.*}}, i32* %._guts1._object._count._value
143+
// CHECK: store i8 {{.*}}, i8* %._guts1._object._discriminator._value
144+
// CHECK: store i16 {{.*}}, i16* %._guts1._object._flags._value, align 2
145+
146+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
147+
148+
/// ---> Thunk and distributed method accessor for `simple3`
149+
150+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE"
151+
152+
/// !!! in `simple3` interesting bits are: argument value extraction (because string is exploded into N arguments) and call to distributed thunk
153+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETF"(%swift.context* swiftasync {{.*}}, i8* [[ARG_BUFF:%.*]], i8* [[RESULT_BUFF:%.*]], %swift.refcounted* swiftself {{.*}})
154+
155+
// CHECK: [[TYPED_RESULT_BUFF:%.*]] = bitcast i8* [[RESULT_BUFF]] to %TSi*
156+
157+
// CHECK: [[ELT_PTR:%.*]] = bitcast i8* %elt_offset to %TSS*
158+
// CHECK-NEXT: %._guts = getelementptr inbounds %TSS, %TSS* [[ELT_PTR]], i32 0, i32 0
159+
160+
// CHECK: [[STR_SIZE:%.*]] = load i32, i32* %._guts._object._count._value
161+
// CHECK-NEXT: %._guts._object._variant = getelementptr inbounds %Ts13_StringObjectV, %Ts13_StringObjectV* %._guts._object, i32 0, i32 1
162+
// CHECK-NEXT: [[NATIVE_STR_VAL_PTR:%.*]] = bitcast %Ts13_StringObjectV7VariantO* %._guts._object._variant to i32*
163+
// CHECK-NEXT: [[STR_VAL:%.*]] = load i32, i32* [[NATIVE_STR_VAL_PTR]]
164+
165+
/// Load pointer to a distributed thunk for `simple3`
166+
167+
// CHECK: [[THUNK_LOC:%.*]] = add i32 ptrtoint (void (%swift.context*, i32, i32, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE" to i32)
168+
// CHECK-NEXT: [[OPAQUE_THUNK_PTR:%.*]] = inttoptr i32 [[THUNK_LOC]] to i8*
169+
// CHECK-NEXT: [[THUNK_PTR:%.*]] = bitcast i8* [[OPAQUE_THUNK_PTR]] to void (%swift.context*, i32, i32, i32, %T27distributed_actor_accessors7MyActorC*)*
170+
171+
// CHECK: [[TMP_STR_ARG:%.*]] = bitcast { i32, i32, i32 }* %temp-coercion.coerced to %TSS*
172+
// CHECK-NEXT: %._guts1 = getelementptr inbounds %TSS, %TSS* [[TMP_STR_ARG]], i32 0, i32 0
173+
174+
// CHECK: store i32 %10, i32* %._guts1._object._count._value, align 4
175+
// CHECK: store i32 %12, i32* %28, align 4
176+
177+
// CHECK: [[STR_ARG_SIZE_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* %temp-coercion.coerced, i32 0, i32 0
178+
// CHECK: [[STR_ARG_SIZE:%.*]] = load i32, i32* [[STR_ARG_SIZE_PTR]]
179+
180+
// CHECK: [[STR_ARG_VAL_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* %temp-coercion.coerced, i32 0, i32 1
181+
// CHECK: [[STR_ARG_VAL:%.*]] = load i32, i32* [[STR_ARG_VAL_PTR]]
182+
183+
// CHECK: [[STR_ARG_FLAGS_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* %temp-coercion.coerced, i32 0, i32 2
184+
// CHECK: [[STR_ARG_FLAGS:%.*]] = load i32, i32* [[STR_ARG_FLAGS_PTR]]
185+
186+
/// Call distributed thunk with exploaded string value
187+
188+
// CHECK: [[OPAQUE_THUNK_PTR:%.*]] = bitcast void (%swift.context*, i32, i32, i32, %T27distributed_actor_accessors7MyActorC*)* [[THUNK_PTR]] to i8*
189+
// CHECK-NEXT: [[THUNK_RESULT:%.*]] = call { i8*, i32, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i32p0s_swift.errorss({{.*}}, i8* [[OPAQUE_THUNK_PTR]], %swift.context* {{.*}}, i32 [[STR_ARG_SIZE]], i32 [[STR_ARG_VAL]], i32 [[STR_ARG_FLAGS]], %T27distributed_actor_accessors7MyActorC* {{.*}})
190+
// CHECK-NEXT: [[TASK_REF:%.*]] = extractvalue { i8*, i32, %swift.error* } [[THUNK_RESULT]], 0
191+
// CHECK-NEXT: {{.*}} = call i8* @__swift_async_resume_project_context(i8* [[TASK_REF]])
192+
// CHECK: [[INT_RES:%.*]] = extractvalue { i8*, i32, %swift.error* } [[THUNK_RESULT]], 1
193+
// CHECK: %._value = getelementptr inbounds %TSi, %TSi* [[TYPED_RESULT_BUFF]], i32 0, i32 0
194+
// CHECK: store i32 [[INT_RES]], i32* %._value
195+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
196+
197+
/// --> Thunk and distributed method accessor for `single_case_enum`
198+
199+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTE"
200+
201+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETF"(%swift.context* swiftasync %0, i8* [[BUFFER:%.*]], i8* [[RESULT_BUFF:%.*]], %swift.refcounted* swiftself {{.*}})
202+
203+
/// First, let's check that there were no loads from the argument buffer and no stores to "current offset".
204+
205+
// CHECK: [[OFFSET:%.*]] = bitcast i8** %offset to i8*
206+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[OFFSET]])
207+
// CHECK-NEXT: store i8* [[BUFFER]], i8** %offset
208+
// CHECK-NEXT: %elt_offset = load i8*, i8** %offset
209+
// CHECK-NEXT: [[ELT_PTR:.*]] = bitcast i8* %elt_offset to %T27distributed_actor_accessors7SimpleEO*
210+
// CHECK-NEXT: [[OFFSET:%.*]] = bitcast i8** %offset to i8*
211+
// CHECK-NEXT call void @llvm.lifetime.end.p0i8(i32 8, i8* [[OFFSET]])
212+
213+
/// Now, let's check that the call doesn't have any arguments and returns nothing.
214+
215+
// CHECK: [[THUNK_REF:%.*]] = bitcast void (%swift.context*, %T27distributed_actor_accessors7MyActorC*)* {{.*}} to i8*
216+
// CHECK: {{.*}} = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.errorss({{.*}}, i8* [[THUNK_REF]], %swift.context* {{.*}}, %T27distributed_actor_accessors7MyActorC* {{.*}})
217+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, i8* {{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
218+
219+
/// --> Thunk and distributed method accessor for `with_indirect_enums`
220+
221+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTE"
222+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETF"
223+
224+
/// First, Load both arguments from the buffer.
225+
226+
// CHECK: [[TYPED_RESULT_BUFF:%.*]] = bitcast i8* %2 to %T27distributed_actor_accessors9IndirectEO*
227+
// CHECK: store i8* %1, i8** %offset
228+
// CHECK-NEXT: %elt_offset = load i8*, i8** %offset
229+
230+
// CHECK-NEXT: [[ENUM_PTR:%.*]] = bitcast i8* %elt_offset to %T27distributed_actor_accessors9IndirectEO*
231+
// CHECK-NEXT: [[NATIVE_ENUM_PTR:%.*]] = bitcast %T27distributed_actor_accessors9IndirectEO* [[ENUM_PTR]] to i32*
232+
// CHECK-NEXT: [[NATIVE_ENUM_VAL:%.*]] = load i32, i32* [[NATIVE_ENUM_PTR]]
233+
// CHECK: [[ENUM_PTR_INT:%.*]] = ptrtoint %T27distributed_actor_accessors9IndirectEO* [[ENUM_PTR]] to i32
234+
// CHECK-NEXT: [[NEXT_ELT_LOC:%.*]] = add i32 [[ENUM_PTR_INT]], 4
235+
// CHECK-NEXT: [[NEXT_ELT_PTR:%.*]] = inttoptr i32 [[NEXT_ELT_LOC]] to i8*
236+
// CHECK-NEXT: store i8* [[NEXT_ELT_PTR]], i8** %offset
237+
// CHECK-NEXT: %elt_offset1 = load i8*, i8** %offset
238+
// CHECK-NEXT: [[INT_PTR:%.*]] = bitcast i8* %elt_offset1 to %TSi*
239+
// CHECK-NEXT: %._value = getelementptr inbounds %TSi, %TSi* [[INT_PTR]], i32 0, i32 0
240+
// CHECK-NEXT: [[NATIVE_INT_VAL:%.*]] = load i32, i32* %._value
241+
242+
/// Call distributed thunk with extracted arguments.
243+
244+
// CHECK: [[THUNK_RESULT:%.*]] = call { i8*, i32, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i32p0s_swift.errorss({{.*}}, %swift.context* {{.*}}, i32 [[NATIVE_ENUM_VAL]], i32 [[NATIVE_INT_VAL]], %T27distributed_actor_accessors7MyActorC* {{.*}})
245+
// CHECK-NEXT: [[TASK_REF:%.*]] = extractvalue { i8*, i32, %swift.error* } [[THUNK_RESULT]], 0
246+
// CHECK-NEXT: {{.*}} = call i8* @__swift_async_resume_project_context(i8* [[TASK_REF]])
247+
// CHECK: [[ENUM_RESULT:%.*]] = extractvalue { i8*, i32, %swift.error* } [[THUNK_RESULT]], 1
248+
// CHECK: [[NATIVE_RESULT_PTR:%.*]] = bitcast %T27distributed_actor_accessors9IndirectEO* [[TYPED_RESULT_BUFF]] to i32*
249+
// CHECK-NEXT: store i32 [[ENUM_RESULT]], i32* [[NATIVE_RESULT_PTR]]
250+
251+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
252+
253+
/// ---> Thunk and distributed method for `complex`
254+
255+
// CHECK: define hidden swifttailcc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTE"
256+
257+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETF"(%swift.context* swiftasync {{.*}}, i8* [[ARG_BUFF:%.*]], i8* [[RESULT_BUFF:%.*]], %swift.refcounted* swiftself {{.*}})
258+
259+
/// First, let's check that all of the different argument types here are loaded correctly.
260+
261+
/// Cast result buffer to the expected result type (in this case its indirect opaque pointer)
262+
// CHECK: [[TYPED_RESULT_BUFF:%.*]] = bitcast i8* [[RESULT_BUFF]] to %swift.opaque*
263+
264+
/// -> [Int]
265+
266+
// CHECK: %elt_offset = load i8*, i8** %offset
267+
// CHECK-NEXT: [[ARR_PTR:%.*]] = bitcast i8* %elt_offset to %TSa*
268+
// CHECK-NEXT: %._buffer = getelementptr inbounds %TSa, %TSa* [[ARR_PTR]], i32 0, i32 0
269+
// CHECK: [[NATIVE_ARR_VAL:%.*]] = load [[ARR_STORAGE_TYPE:%.*]], [[ARR_STORAGE_TYPE]]* %._buffer._storage
270+
// CHECK: [[ARR_PTR_INT:%.*]] = ptrtoint %TSa* [[ARR_PTR]] to i32
271+
// CHECK-NEXT: [[NEXT_ELT:%.*]] = add i32 [[ARR_PTR_INT]], 4
272+
// CHECK-NEXT: [[OPAQUE_NEXT_ELT:%.*]] = inttoptr i32 [[NEXT_ELT]] to i8*
273+
// CHECK-NEXT: store i8* [[OPAQUE_NEXT_ELT]], i8** %offset
274+
275+
/// -> Obj
276+
277+
// CHECK-NEXT: %elt_offset1 = load i8*, i8** %offset
278+
// CHECK-NEXT: [[OBJ_PTR:%.*]] = bitcast i8* %elt_offset1 to %T27distributed_actor_accessors3ObjC**
279+
// CHECK-NEXT: [[NATIVE_OBJ_VAL:%.*]] = load %T27distributed_actor_accessors3ObjC*, %T27distributed_actor_accessors3ObjC** [[OBJ_PTR]]
280+
// CHECK: [[OBJ_PTR_INT:%.*]] = ptrtoint %T27distributed_actor_accessors3ObjC** [[OBJ_PTR]] to i32
281+
// CHECK-NEXT: [[NEXT_ELT:%.*]] = add i32 [[OBJ_PTR_INT]], 4
282+
// CHECK-NEXT: [[NEXT_ELT_PTR:%.*]] = inttoptr i32 [[NEXT_ELT]] to i8*
283+
// CHECK-NEXT: store i8* [[NEXT_ELT_PTR]], i8** %offset
284+
285+
/// -> String?
286+
287+
// CHECK-NEXT: %elt_offset2 = load i8*, i8** %offset
288+
// CHECK-NEXT: [[OPT_PTR:%.*]] = bitcast i8* %elt_offset2 to %TSSSg*
289+
// CHECK-NEXT: [[NATIVE_OPT_PTR:%.*]] = bitcast %TSSSg* [[OPT_PTR]] to { i32, i32, i32 }*
290+
// CHECK-NEXT: [[NATIVE_OPT_VAL_0_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* [[NATIVE_OPT_PTR]], i32 0, i32 0
291+
// CHECK-NEXT: [[NATIVE_OPT_VAL_0:%.*]] = load i32, i32* [[NATIVE_OPT_VAL_0_PTR]]
292+
// CHECK-NEXT: [[NATIVE_OPT_VAL_1_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* [[NATIVE_OPT_PTR]], i32 0, i32 1
293+
// CHECK-NEXT: [[NATIVE_OPT_VAL_1:%.*]] = load i32, i32* [[NATIVE_OPT_VAL_1_PTR]]
294+
// CHECK-NEXT: [[NATIVE_OPT_VAL_2_PTR:%.*]] = getelementptr inbounds { i32, i32, i32 }, { i32, i32, i32 }* [[NATIVE_OPT_PTR]], i32 0, i32 2
295+
// CHECK-NEXT: [[NATIVE_OPT_VAL_2:%.*]] = load i32, i32* [[NATIVE_OPT_VAL_2_PTR]]
296+
// CHECK-NEXT: [[OPT_PTR_INT:%.*]] = ptrtoint %TSSSg* [[OPT_PTR]] to i32
297+
// CHECK-NEXT: [[NEXT_ELT:%.*]] = add i32 [[OPT_PTR_INT]], 12
298+
// CHECK-NEXT: [[NEXT_ELT_PTR:%.*]] = inttoptr i32 [[NEXT_ELT]] to i8*
299+
// CHECK-NEXT: store i8* [[NEXT_ELT_PTR]], i8** %offset
300+
301+
/// -> LargeStruct (passed indirectly)
302+
303+
// CHECK-NEXT: %elt_offset3 = load i8*, i8** %offset
304+
// CHECK-NEXT: [[STRUCT_PTR:%.*]] = bitcast i8* %elt_offset3 to %T27distributed_actor_accessors11LargeStructV*
305+
// CHECK-NEXT: [[STRUCT_PTR_VAL:%.*]] = ptrtoint %T27distributed_actor_accessors11LargeStructV* [[STRUCT_PTR]] to i32
306+
// CHECK-NEXT: [[STRUCT_PTR_VAL_ADJ_1:%.*]] = add nuw i32 [[STRUCT_PTR_VAL]], 7
307+
// CHECK-NEXT: [[STRUCT_PTR_VAL_ADJ_2:%.*]] = and i32 [[STRUCT_PTR_VAL_ADJ_1]], -8
308+
// CHECK-NEXT: [[STRUCT_PTR:%.*]] = inttoptr i32 [[STRUCT_PTR_VAL_ADJ_2]] to %T27distributed_actor_accessors11LargeStructV*
309+
310+
311+
// CHECK: [[INDIRECT_RESULT_BUFF:%.*]] = bitcast %swift.opaque* [[TYPED_RESULT_BUFF]] to %T27distributed_actor_accessors11LargeStructV*
312+
313+
/// Now let's make sure that distributed thunk call uses the arguments correctly
314+
315+
// CHECK: [[THUNK_RESULT:%.*]] = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.errorss({{.*}}, %T27distributed_actor_accessors11LargeStructV* [[INDIRECT_RESULT_BUFF]], %swift.context* {{.*}}, {{.*}} [[NATIVE_ARR_VAL]], %T27distributed_actor_accessors3ObjC* [[NATIVE_OBJ_VAL]], i32 [[NATIVE_OPT_VAL_0]], i32 [[NATIVE_OPT_VAL_1]], i32 [[NATIVE_OPT_VAL_2]], %T27distributed_actor_accessors11LargeStructV* [[STRUCT_PTR]], %T27distributed_actor_accessors7MyActorC* {{.*}})
316+
317+
/// RESULT is returned indirectly so there is nothing to pass to `end`
318+
319+
// CHECK: {{.*}} = call i1 (i8*, i1, ...) @llvm.coro.end.async({{.*}}, %swift.context* {{.*}}, %swift.error* {{.*}})
320+
321+
/// ---> Thunk and distributed method for `MyOtherActor.empty`
322+
323+
/// Let's check that there is no offset allocation here since parameter list is empty
324+
325+
// CHECK: define internal swifttailcc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETF"(%swift.context* swiftasync {{.*}}, i8* [[ARG_BUFF:%.*]], i8* [[RESULT_BUFF:%.*]], %swift.refcounted* swiftself {{.*}})
326+
// CHECK-NEXT: entry:
327+
// CHECK-NEXT: {{.*}} = alloca %swift.context*
328+
// CHECK-NEXT: %swifterror = alloca %swift.error*
329+
// CHECK-NEXT: {{.*}} = call token @llvm.coro.id.async(i32 12, i32 16, i32 0, i8* bitcast (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i8*))
330+
// CHECK-NEXT: {{.*}} = call i8* @llvm.coro.begin(token {{%.*}}, i8* null)
331+
// CHECK-NEXT: store %swift.context* {{.*}}, %swift.context** {{.*}}
332+
// CHECK-NEXT: store %swift.error* null, %swift.error** %swifterror
333+
// CHECK-NEXT: {{.*}} = bitcast i8* [[RESULT_BUFF]] to %swift.opaque*
334+
// CHECK-NEXT: {{.*}} = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* bitcast (void (%swift.context*, %T27distributed_actor_accessors12MyOtherActorC*)* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTE" to %swift.async_func_pointer*), i32 0, i32 0)

test/Distributed/distributed_actor_accessor_thunks.swift renamed to test/Distributed/distributed_actor_accessor_thunks_64bit.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// REQUIRES: concurrency
77
// REQUIRES: distributed
88

9+
// REQUIRES: CPU=x86_64
10+
911
import _Distributed
1012
import FakeDistributedActorSystems
1113

0 commit comments

Comments
 (0)