blob: d78f1b5521ddb07532875f622d2c63e11f12b27c [file] [log] [blame]
Daniel Sanders20c82ee42014-07-04 15:16:14 +00001; Test the 'call' instruction and the tailcall variant.
2
Simon Dardisd2ed8ab2016-09-27 13:15:54 +00003; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
4; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
5; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
6; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,NOT-R6C
7; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
8; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,O32,R6C
Simon Dardisca74dd72017-01-27 11:36:52 +00009; RUN: llc -march=mips64 -mcpu=mips4 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
10; RUN: llc -march=mips64 -mcpu=mips64 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
11; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
12; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
13; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,NOT-R6C
14; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefixes=ALL,N64,R6C
Simon Dardisd2ed8ab2016-09-27 13:15:54 +000015; RUN: llc -march=mips -mcpu=mips32 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
16; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
17; RUN: llc -march=mips -mcpu=mips32r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
18; RUN: llc -march=mips -mcpu=mips32r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C
19; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
20; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C
Simon Dardisca74dd72017-01-27 11:36:52 +000021; RUN: llc -march=mips64 -mcpu=mips4 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
22; RUN: llc -march=mips64 -mcpu=mips64 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
23; RUN: llc -march=mips64 -mcpu=mips64r2 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
24; RUN: llc -march=mips64 -mcpu=mips64r3 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
25; RUN: llc -march=mips64 -mcpu=mips64r5 -relocation-model=pic -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C
26; RUN: llc -march=mips64 -mcpu=mips64r6 -relocation-model=pic -disable-mips-delay-filler -mips-tail-calls=1 < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C
Daniel Sanders20c82ee42014-07-04 15:16:14 +000027
28declare void @extern_void_void()
29declare i32 @extern_i32_void()
30declare float @extern_float_void()
31
32define i32 @call_void_void() {
33; ALL-LABEL: call_void_void:
34
35; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
36
37; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
38
Simon Dardisd9d41f52016-04-05 12:50:29 +000039; NOT-R6C: jalr $[[TGT]]
Simon Dardis53a34922016-04-14 13:43:17 +000040; R6C: jalrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +000041
42 call void @extern_void_void()
Simon Dardis53a34922016-04-14 13:43:17 +000043; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +000044 ret i32 0
45}
46
47define i32 @call_i32_void() {
48; ALL-LABEL: call_i32_void:
49
50; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
51
52; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
53
Simon Dardisd9d41f52016-04-05 12:50:29 +000054; NOT-R6C: jalr $[[TGT]]
Simon Dardis53a34922016-04-14 13:43:17 +000055; R6C: jalrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +000056
57 %1 = call i32 @extern_i32_void()
58 %2 = add i32 %1, 1
Simon Dardis53a34922016-04-14 13:43:17 +000059; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +000060 ret i32 %2
61}
62
63define float @call_float_void() {
64; ALL-LABEL: call_float_void:
65
66; FIXME: Not sure why we don't use $gp directly on such a simple test. We should
67; look into it at some point.
68; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25
69; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]])
70
71; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
72
Simon Dardisd9d41f52016-04-05 12:50:29 +000073; NOT-R6C: jalr $[[TGT]]
Simon Dardis53a34922016-04-14 13:43:17 +000074; R6C: jalrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +000075
Daniel Sanders20c82ee42014-07-04 15:16:14 +000076
77 %1 = call float @extern_float_void()
78 %2 = fadd float %1, 1.0
Simon Dardis53a34922016-04-14 13:43:17 +000079; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +000080 ret float %2
81}
82
Daniel Sanders20c82ee42014-07-04 15:16:14 +000083define i32 @indirect_call_void_void(void ()* %addr) {
84; ALL-LABEL: indirect_call_void_void:
85
86; ALL: move $25, $4
Simon Dardisd9d41f52016-04-05 12:50:29 +000087; NOT-R6C: jalr $25
Simon Dardis53a34922016-04-14 13:43:17 +000088; R6C: jalrc $25
Daniel Sanders20c82ee42014-07-04 15:16:14 +000089
90 call void %addr()
Simon Dardis53a34922016-04-14 13:43:17 +000091; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +000092 ret i32 0
93}
94
95define i32 @indirect_call_i32_void(i32 ()* %addr) {
96; ALL-LABEL: indirect_call_i32_void:
97
98; ALL: move $25, $4
Simon Dardisd9d41f52016-04-05 12:50:29 +000099; NOT-R6C: jalr $25
Simon Dardis53a34922016-04-14 13:43:17 +0000100; R6C: jalrc $25
Simon Dardisd9d41f52016-04-05 12:50:29 +0000101
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000102
103 %1 = call i32 %addr()
104 %2 = add i32 %1, 1
Simon Dardis53a34922016-04-14 13:43:17 +0000105; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000106 ret i32 %2
107}
108
109define float @indirect_call_float_void(float ()* %addr) {
110; ALL-LABEL: indirect_call_float_void:
111
112; ALL: move $25, $4
Simon Dardisd9d41f52016-04-05 12:50:29 +0000113; NOT-R6C: jalr $25
Simon Dardis53a34922016-04-14 13:43:17 +0000114; R6C: jalrc $25
Simon Dardisd9d41f52016-04-05 12:50:29 +0000115
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000116
117 %1 = call float %addr()
118 %2 = fadd float %1, 1.0
Simon Dardis53a34922016-04-14 13:43:17 +0000119; R6C: jrc $ra
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000120 ret float %2
121}
122
123; We can't use 'musttail' here because the verifier is too conservative and
124; prohibits any prototype difference.
125define void @tail_indirect_call_void_void(void ()* %addr) {
126; ALL-LABEL: tail_indirect_call_void_void:
127
128; ALL: move $25, $4
Simon Dardis57f4ae42016-08-04 09:17:07 +0000129; NOT-R6C: jr $[[TGT]]
130; R6C: jrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000131
132 tail call void %addr()
133 ret void
134}
135
136define i32 @tail_indirect_call_i32_void(i32 ()* %addr) {
137; ALL-LABEL: tail_indirect_call_i32_void:
138
139; ALL: move $25, $4
Simon Dardis57f4ae42016-08-04 09:17:07 +0000140; NOT-R6C: jr $[[TGT]]
141; R6C: jrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000142
143 %1 = tail call i32 %addr()
144 ret i32 %1
145}
146
147define float @tail_indirect_call_float_void(float ()* %addr) {
148; ALL-LABEL: tail_indirect_call_float_void:
149
150; ALL: move $25, $4
Simon Dardis57f4ae42016-08-04 09:17:07 +0000151; NOT-R6C: jr $[[TGT]]
152; R6C: jrc $[[TGT]]
Daniel Sanders20c82ee42014-07-04 15:16:14 +0000153
154 %1 = tail call float %addr()
155 ret float %1
156}
Daniel Sanders2fb85642015-10-12 13:55:44 +0000157
158; Check that passing undef as a double value doesn't cause machine code errors
159; for FP64.
160declare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2
161
162define hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 {
163; ALL-LABEL: thunk_undef_double:
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000164; O32: # implicit-def: $a2
165; O32: # implicit-def: $a3
Simon Dardis57f4ae42016-08-04 09:17:07 +0000166; NOT-R6C: jr $[[TGT]]
167; R6C: jrc $[[TGT]]
Simon Dardisd9d41f52016-04-05 12:50:29 +0000168
Daniel Sanders2fb85642015-10-12 13:55:44 +0000169 tail call void @undef_double(i32 undef, double undef) #8
170 ret void
171}
Daniel Sanders4d323002016-01-11 15:57:46 +0000172
173; Check that immediate addresses do not use jal.
174define i32 @jal_only_allows_symbols() {
175; ALL-LABEL: jal_only_allows_symbols:
176
177; ALL-NOT: {{jal }}
178; ALL: addiu $[[TGT:[0-9]+]], $zero, 1234
179; ALL-NOT: {{jal }}
Simon Dardisd9d41f52016-04-05 12:50:29 +0000180; NOT-R6C: jalr $[[TGT]]
Simon Dardis53a34922016-04-14 13:43:17 +0000181; R6C: jalrc $[[TGT]]
Daniel Sanders4d323002016-01-11 15:57:46 +0000182; ALL-NOT: {{jal }}
183
184 call void () inttoptr (i32 1234 to void ()*)()
Simon Dardis53a34922016-04-14 13:43:17 +0000185; R6C: jrc $ra
Daniel Sanders4d323002016-01-11 15:57:46 +0000186 ret i32 0
187}
188