blob: 0752fc7ac7dbd448f41c0b7f9e81d0c514947908 [file] [log] [blame]
Daniel Sanders20c82ee42014-07-04 15:16:14 +00001; Test the 'call' instruction and the tailcall variant.
2
3; FIXME: We should remove the need for -enable-mips-tail-calls
4; RUN: llc -march=mips -mcpu=mips32 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
5; RUN: llc -march=mips -mcpu=mips32r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
6; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
7; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
8
9declare void @extern_void_void()
10declare i32 @extern_i32_void()
11declare float @extern_float_void()
12
13define i32 @call_void_void() {
14; ALL-LABEL: call_void_void:
15
16; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
17
18; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
19
20; ALL: jalr $[[TGT]]
21
22 call void @extern_void_void()
23 ret i32 0
24}
25
26define i32 @call_i32_void() {
27; ALL-LABEL: call_i32_void:
28
29; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
30
31; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
32
33; ALL: jalr $[[TGT]]
34
35 %1 = call i32 @extern_i32_void()
36 %2 = add i32 %1, 1
37 ret i32 %2
38}
39
40define float @call_float_void() {
41; ALL-LABEL: call_float_void:
42
43; FIXME: Not sure why we don't use $gp directly on such a simple test. We should
44; look into it at some point.
45; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25
46; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]])
47
48; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
49
50; ALL: jalr $[[TGT]]
51
52; O32: move $gp, $[[GP]]
53
54 %1 = call float @extern_float_void()
55 %2 = fadd float %1, 1.0
56 ret float %2
57}
58
59define void @musttail_call_void_void() {
60; ALL-LABEL: musttail_call_void_void:
61
62; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
63
64; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
65
66; ALL: jr $[[TGT]]
67
68 musttail call void @extern_void_void()
69 ret void
70}
71
72define i32 @musttail_call_i32_void() {
73; ALL-LABEL: musttail_call_i32_void:
74
75; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
76
77; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
78
79; ALL: jr $[[TGT]]
80
81 %1 = musttail call i32 @extern_i32_void()
82 ret i32 %1
83}
84
85define float @musttail_call_float_void() {
86; ALL-LABEL: musttail_call_float_void:
87
88; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
89
90; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
91
92; ALL: jr $[[TGT]]
93
94 %1 = musttail call float @extern_float_void()
95 ret float %1
96}
97
98define i32 @indirect_call_void_void(void ()* %addr) {
99; ALL-LABEL: indirect_call_void_void:
100
101; ALL: move $25, $4
102; ALL: jalr $25
103
104 call void %addr()
105 ret i32 0
106}
107
108define i32 @indirect_call_i32_void(i32 ()* %addr) {
109; ALL-LABEL: indirect_call_i32_void:
110
111; ALL: move $25, $4
112; ALL: jalr $25
113
114 %1 = call i32 %addr()
115 %2 = add i32 %1, 1
116 ret i32 %2
117}
118
119define float @indirect_call_float_void(float ()* %addr) {
120; ALL-LABEL: indirect_call_float_void:
121
122; ALL: move $25, $4
123; ALL: jalr $25
124
125 %1 = call float %addr()
126 %2 = fadd float %1, 1.0
127 ret float %2
128}
129
130; We can't use 'musttail' here because the verifier is too conservative and
131; prohibits any prototype difference.
132define void @tail_indirect_call_void_void(void ()* %addr) {
133; ALL-LABEL: tail_indirect_call_void_void:
134
135; ALL: move $25, $4
136; ALL: jr $25
137
138 tail call void %addr()
139 ret void
140}
141
142define i32 @tail_indirect_call_i32_void(i32 ()* %addr) {
143; ALL-LABEL: tail_indirect_call_i32_void:
144
145; ALL: move $25, $4
146; ALL: jr $25
147
148 %1 = tail call i32 %addr()
149 ret i32 %1
150}
151
152define float @tail_indirect_call_float_void(float ()* %addr) {
153; ALL-LABEL: tail_indirect_call_float_void:
154
155; ALL: move $25, $4
156; ALL: jr $25
157
158 %1 = tail call float %addr()
159 ret float %1
160}