xref: /aosp_15_r20/external/llvm/test/CodeGen/Mips/llvm-ir/call.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; Test the 'call' instruction and the tailcall variant.
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; FIXME: We should remove the need for -enable-mips-tail-calls
4*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32   -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
5*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32r2 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
6*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32r3 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
7*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32r5 -relocation-model=pic -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
8*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
9*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips   -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
10*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips4    -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
11*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64   -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
12*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
13*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
14*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
15*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerdeclare void @extern_void_void()
18*9880d681SAndroid Build Coastguard Workerdeclare i32 @extern_i32_void()
19*9880d681SAndroid Build Coastguard Workerdeclare float @extern_float_void()
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Workerdefine i32 @call_void_void() {
22*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_void_void:
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $[[TGT]]
29*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $[[TGT]]
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker  call void @extern_void_void()
32*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
33*9880d681SAndroid Build Coastguard Worker  ret i32 0
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Workerdefine i32 @call_i32_void() {
37*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_i32_void:
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $[[TGT]]
44*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $[[TGT]]
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker  %1 = call i32 @extern_i32_void()
47*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 1
48*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
49*9880d681SAndroid Build Coastguard Worker  ret i32 %2
50*9880d681SAndroid Build Coastguard Worker}
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerdefine float @call_float_void() {
53*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: call_float_void:
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; FIXME: Not sure why we don't use $gp directly on such a simple test. We should
56*9880d681SAndroid Build Coastguard Worker;        look into it at some point.
57*9880d681SAndroid Build Coastguard Worker; O32:           addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25
58*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]])
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $[[TGT]]
63*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $[[TGT]]
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker  %1 = call float @extern_float_void()
67*9880d681SAndroid Build Coastguard Worker  %2 = fadd float %1, 1.0
68*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
69*9880d681SAndroid Build Coastguard Worker  ret float %2
70*9880d681SAndroid Build Coastguard Worker}
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Workerdefine void @musttail_call_void_void() {
73*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_void_void:
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; ALL:           jr $[[TGT]]
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker  musttail call void @extern_void_void()
82*9880d681SAndroid Build Coastguard Worker  ret void
83*9880d681SAndroid Build Coastguard Worker}
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Workerdefine i32 @musttail_call_i32_void() {
86*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_i32_void:
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker; ALL:           jr $[[TGT]]
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker  %1 = musttail call i32 @extern_i32_void()
95*9880d681SAndroid Build Coastguard Worker  ret i32 %1
96*9880d681SAndroid Build Coastguard Worker}
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Workerdefine float @musttail_call_float_void() {
99*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: musttail_call_float_void:
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker; O32:           lw $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker; N64:           ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker; ALL:           jr $[[TGT]]
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker  %1 = musttail call float @extern_float_void()
108*9880d681SAndroid Build Coastguard Worker  ret float %1
109*9880d681SAndroid Build Coastguard Worker}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Workerdefine i32 @indirect_call_void_void(void ()* %addr) {
112*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_void_void:
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
115*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $25
116*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $25
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker  call void %addr()
119*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
120*9880d681SAndroid Build Coastguard Worker  ret i32 0
121*9880d681SAndroid Build Coastguard Worker}
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Workerdefine i32 @indirect_call_i32_void(i32 ()* %addr) {
124*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_i32_void:
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
127*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $25
128*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $25
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker  %1 = call i32 %addr()
132*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 1
133*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
134*9880d681SAndroid Build Coastguard Worker  ret i32 %2
135*9880d681SAndroid Build Coastguard Worker}
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerdefine float @indirect_call_float_void(float ()* %addr) {
138*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: indirect_call_float_void:
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
141*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $25
142*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $25
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker  %1 = call float %addr()
146*9880d681SAndroid Build Coastguard Worker  %2 = fadd float %1, 1.0
147*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
148*9880d681SAndroid Build Coastguard Worker  ret float %2
149*9880d681SAndroid Build Coastguard Worker}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker; We can't use 'musttail' here because the verifier is too conservative and
152*9880d681SAndroid Build Coastguard Worker; prohibits any prototype difference.
153*9880d681SAndroid Build Coastguard Workerdefine void @tail_indirect_call_void_void(void ()* %addr) {
154*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_void_void:
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
157*9880d681SAndroid Build Coastguard Worker; ALL:           jr $25
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker  tail call void %addr()
160*9880d681SAndroid Build Coastguard Worker  ret void
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Workerdefine i32 @tail_indirect_call_i32_void(i32 ()* %addr) {
164*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_i32_void:
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
167*9880d681SAndroid Build Coastguard Worker; ALL:           jr $25
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker  %1 = tail call i32 %addr()
170*9880d681SAndroid Build Coastguard Worker  ret i32 %1
171*9880d681SAndroid Build Coastguard Worker}
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Workerdefine float @tail_indirect_call_float_void(float ()* %addr) {
174*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: tail_indirect_call_float_void:
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker; ALL:           move $25, $4
177*9880d681SAndroid Build Coastguard Worker; ALL:           jr $25
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker  %1 = tail call float %addr()
180*9880d681SAndroid Build Coastguard Worker  ret float %1
181*9880d681SAndroid Build Coastguard Worker}
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker; Check that passing undef as a double value doesn't cause machine code errors
184*9880d681SAndroid Build Coastguard Worker; for FP64.
185*9880d681SAndroid Build Coastguard Workerdeclare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Workerdefine hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 {
188*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: thunk_undef_double:
189*9880d681SAndroid Build Coastguard Worker; O32: # implicit-def: %A2
190*9880d681SAndroid Build Coastguard Worker; O32: # implicit-def: %A3
191*9880d681SAndroid Build Coastguard Worker; ALL:        jr $25
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker  tail call void @undef_double(i32 undef, double undef) #8
194*9880d681SAndroid Build Coastguard Worker  ret void
195*9880d681SAndroid Build Coastguard Worker}
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker; Check that immediate addresses do not use jal.
198*9880d681SAndroid Build Coastguard Workerdefine i32 @jal_only_allows_symbols() {
199*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: jal_only_allows_symbols:
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker; ALL-NOT:       {{jal }}
202*9880d681SAndroid Build Coastguard Worker; ALL:           addiu $[[TGT:[0-9]+]], $zero, 1234
203*9880d681SAndroid Build Coastguard Worker; ALL-NOT:       {{jal }}
204*9880d681SAndroid Build Coastguard Worker; NOT-R6C:       jalr $[[TGT]]
205*9880d681SAndroid Build Coastguard Worker; R6C:           jalrc $[[TGT]]
206*9880d681SAndroid Build Coastguard Worker; ALL-NOT:       {{jal }}
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker  call void () inttoptr (i32 1234 to void ()*)()
209*9880d681SAndroid Build Coastguard Worker; R6C:           jrc $ra
210*9880d681SAndroid Build Coastguard Worker  ret i32 0
211*9880d681SAndroid Build Coastguard Worker}
212*9880d681SAndroid Build Coastguard Worker
213