0752fc7ac7dbd448f41c0b7f9e81d0c514947908
[oota-llvm.git] / test / CodeGen / Mips / llvm-ir / call.ll
1 ; 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
9 declare void @extern_void_void()
10 declare i32 @extern_i32_void()
11 declare float @extern_float_void()
12
13 define 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
26 define 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
40 define 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
59 define 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
72 define 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
85 define 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
98 define 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
108 define 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
119 define 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.
132 define 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
142 define 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
152 define 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 }