xref: /llvm-project/llvm/test/CodeGen/SystemZ/swiftself.ll (revision a1710eb3cd5823c5d14899112ca3086acbdbe9cb)
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 ptr@swiftself_param(ptr swiftself %addr0) {
7  ret ptr %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 ptr@call_swiftself(ptr %arg) {
15  %res = call ptr@swiftself_param(ptr swiftself %arg)
16  ret ptr %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 ptr@swiftself_clobber(ptr swiftself %addr0) {
26  call void asm sideeffect "", "~{r10}"()
27  ret ptr %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(ptr swiftself %addr0) {
38  call ptr@swiftself_param(ptr swiftself %addr0)
39  call ptr@swiftself_param(ptr 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 ptr @swiftself_tail(ptr swiftself %addr0) {
51  call void asm sideeffect "", "~{r10}"()
52  %res = tail call ptr @swiftself_param(ptr swiftself %addr0)
53  ret ptr %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 ptr @swiftself_notail(ptr swiftself %addr0, ptr %addr1) nounwind {
64  %res = tail call ptr @swiftself_param(ptr swiftself %addr1)
65  ret ptr %res
66}
67