1 ; Test the 'call' instruction and the tailcall variant.
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=mips -mcpu=mips32r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
7 ; RUN: llc -march=mips -mcpu=mips32r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
8 ; RUN: llc -march=mips -mcpu=mips32r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
9 ; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+fp64,+nooddspreg -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
10 ; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
11 ; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
12 ; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
13 ; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
14 ; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
15 ; RUN: llc -march=mips64 -mcpu=mips64r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
17 declare void @extern_void_void()
18 declare i32 @extern_i32_void()
19 declare float @extern_float_void()
21 define i32 @call_void_void() {
22 ; ALL-LABEL: call_void_void:
24 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
26 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
30 call void @extern_void_void()
34 define i32 @call_i32_void() {
35 ; ALL-LABEL: call_i32_void:
37 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
39 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
43 %1 = call i32 @extern_i32_void()
48 define float @call_float_void() {
49 ; ALL-LABEL: call_float_void:
51 ; FIXME: Not sure why we don't use $gp directly on such a simple test. We should
52 ; look into it at some point.
53 ; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25
54 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]])
56 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
60 ; O32: move $gp, $[[GP]]
62 %1 = call float @extern_float_void()
63 %2 = fadd float %1, 1.0
67 define void @musttail_call_void_void() {
68 ; ALL-LABEL: musttail_call_void_void:
70 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
72 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
77 musttail call void @extern_void_void()
81 define i32 @musttail_call_i32_void() {
82 ; ALL-LABEL: musttail_call_i32_void:
84 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
86 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
91 %1 = musttail call i32 @extern_i32_void()
95 define float @musttail_call_float_void() {
96 ; ALL-LABEL: musttail_call_float_void:
98 ; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
100 ; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
102 ; NOT-R6: jr $[[TGT]]
105 %1 = musttail call float @extern_float_void()
109 define i32 @indirect_call_void_void(void ()* %addr) {
110 ; ALL-LABEL: indirect_call_void_void:
119 define i32 @indirect_call_i32_void(i32 ()* %addr) {
120 ; ALL-LABEL: indirect_call_i32_void:
125 %1 = call i32 %addr()
130 define float @indirect_call_float_void(float ()* %addr) {
131 ; ALL-LABEL: indirect_call_float_void:
136 %1 = call float %addr()
137 %2 = fadd float %1, 1.0
141 ; We can't use 'musttail' here because the verifier is too conservative and
142 ; prohibits any prototype difference.
143 define void @tail_indirect_call_void_void(void ()* %addr) {
144 ; ALL-LABEL: tail_indirect_call_void_void:
149 tail call void %addr()
153 define i32 @tail_indirect_call_i32_void(i32 ()* %addr) {
154 ; ALL-LABEL: tail_indirect_call_i32_void:
159 %1 = tail call i32 %addr()
163 define float @tail_indirect_call_float_void(float ()* %addr) {
164 ; ALL-LABEL: tail_indirect_call_float_void:
169 %1 = tail call float %addr()
173 ; Check that passing undef as a double value doesn't cause machine code errors
175 declare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2
177 define hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 {
178 ; ALL-LABEL: thunk_undef_double:
179 ; O32: # implicit-def: %A2
180 ; O32: # implicit-def: %A3
182 tail call void @undef_double(i32 undef, double undef) #8
186 ; Check that immediate addresses do not use jal.
187 define i32 @jal_only_allows_symbols() {
188 ; ALL-LABEL: jal_only_allows_symbols:
191 ; ALL: addiu $[[TGT:[0-9]+]], $zero, 1234
196 call void () inttoptr (i32 1234 to void ()*)()