1; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
2
3; Parameter with swiftself should be allocated to r10.
4; CHECK-LABEL: swiftself_param:
5; CHECK: lgr %r2, %r10
6define i8 *@swiftself_param(i8* swiftself %addr0) {
7  ret i8 *%addr0
8}
9
10; Check that r10 is used to pass a swiftself argument.
11; CHECK-LABEL: call_swiftself:
12; CHECK: lgr %r10, %r2
13; CHECK: brasl %r14, swiftself_param
14define i8 *@call_swiftself(i8* %arg) {
15  %res = call i8 *@swiftself_param(i8* swiftself %arg)
16  ret i8 *%res
17}
18
19; r10 should be saved by the callee even if used for swiftself
20; CHECK-LABEL: swiftself_clobber:
21; CHECK: stmg %r10,
22; ...
23; CHECK: lmg %r10,
24; CHECK: br %r14
25define i8 *@swiftself_clobber(i8* swiftself %addr0) {
26  call void asm sideeffect "", "~{r10}"()
27  ret i8 *%addr0
28}
29
30; Demonstrate that we do not need any loads when calling multiple functions
31; with swiftself argument.
32; CHECK-LABEL: swiftself_passthrough:
33; CHECK-NOT: lg{{.*}}r10,
34; CHECK: brasl %r14, swiftself_param
35; CHECK-NOT: lg{{.*}}r10,
36; CHECK-NEXT: brasl %r14, swiftself_param
37define void @swiftself_passthrough(i8* swiftself %addr0) {
38  call i8 *@swiftself_param(i8* swiftself %addr0)
39  call i8 *@swiftself_param(i8* swiftself %addr0)
40  ret void
41}
42
43; Normally, we can use a tail call if the callee swiftself is the same as the
44; caller one. Not yet supported on SystemZ.
45; CHECK-LABEL: swiftself_tail:
46; CHECK: lgr %r[[REG1:[0-9]+]], %r10
47; CHECK: lgr %r10, %r[[REG1]]
48; CHECK: brasl %r14, swiftself_param
49; CHECK: br %r14
50define i8* @swiftself_tail(i8* swiftself %addr0) {
51  call void asm sideeffect "", "~{r10}"()
52  %res = tail call i8* @swiftself_param(i8* swiftself %addr0)
53  ret i8* %res
54}
55
56; We can not use a tail call if the callee swiftself is not the same as the
57; caller one.
58; CHECK-LABEL: swiftself_notail:
59; CHECK: lgr %r10, %r2
60; CHECK: brasl %r14, swiftself_param
61; CHECK: lmg %r10,
62; CHECK: br %r14
63define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind {
64  %res = tail call i8* @swiftself_param(i8* swiftself %addr1)
65  ret i8* %res
66}
67