[ARM] Cortex-M4 schedule additions
[llvm-complete.git] / test / CodeGen / Mips / return-vector.ll
blobc59695d18734e41a55a48e22676fee5921093ef7
1 ; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s
4 ; Check that function accesses vector return value from stack in cases when
5 ; vector can't be returned in registers. Also check that caller passes in
6 ; register $4 stack address where the vector should be placed.
9 declare <8 x i32>    @i8(...)
10 declare <4 x float>  @f4(...)
11 declare <4 x double> @d4(...)
13 define i32 @call_i8() {
14 entry:
15   %call = call <8 x i32> (...) @i8()
16   %v0 = extractelement <8 x i32> %call, i32 0
17   %v1 = extractelement <8 x i32> %call, i32 1
18   %v2 = extractelement <8 x i32> %call, i32 2
19   %v3 = extractelement <8 x i32> %call, i32 3
20   %v4 = extractelement <8 x i32> %call, i32 4
21   %v5 = extractelement <8 x i32> %call, i32 5
22   %v6 = extractelement <8 x i32> %call, i32 6
23   %v7 = extractelement <8 x i32> %call, i32 7
24   %add1 = add i32 %v0, %v1
25   %add2 = add i32 %v2, %v3
26   %add3 = add i32 %v4, %v5
27   %add4 = add i32 %v6, %v7
28   %add5 = add i32 %add1, %add2
29   %add6 = add i32 %add3, %add4
30   %add7 = add i32 %add5, %add6
31   ret i32 %add7
33 ; CHECK-LABEL:        call_i8:
34 ; CHECK:        call16(i8)
35 ; CHECK:        addiu   $4, $sp, 32
36 ; CHECK:        lw      $[[R0:[a-z0-9]+]], 60($sp)
37 ; CHECK:        lw      $[[R1:[a-z0-9]+]], 56($sp)
38 ; CHECK:        lw      $[[R2:[a-z0-9]+]], 52($sp)
39 ; CHECK:        lw      $[[R3:[a-z0-9]+]], 48($sp)
40 ; CHECK:        lw      $[[R4:[a-z0-9]+]], 44($sp)
41 ; CHECK:        lw      $[[R5:[a-z0-9]+]], 40($sp)
42 ; CHECK:        lw      $[[R6:[a-z0-9]+]], 36($sp)
43 ; CHECK:        lw      $[[R7:[a-z0-9]+]], 32($sp)
47 define float @call_f4() {
48 entry:
49   %call = call <4 x float> (...) @f4()
50   %v0 = extractelement <4 x float> %call, i32 0
51   %v1 = extractelement <4 x float> %call, i32 1
52   %v2 = extractelement <4 x float> %call, i32 2
53   %v3 = extractelement <4 x float> %call, i32 3
54   %add1 = fadd float %v0, %v1
55   %add2 = fadd float %v2, %v3
56   %add3 = fadd float %add1, %add2
57   ret float %add3
59 ; CHECK-LABEL:        call_f4:
60 ; CHECK:        call16(f4)
61 ; CHECK:        addiu   $4, $sp, 16
62 ; CHECK:        lwc1    $[[R0:[a-z0-9]+]], 28($sp)
63 ; CHECK:        lwc1    $[[R1:[a-z0-9]+]], 24($sp)
64 ; CHECK:        lwc1    $[[R3:[a-z0-9]+]], 20($sp)
65 ; CHECK:        lwc1    $[[R4:[a-z0-9]+]], 16($sp)
69 define double @call_d4() {
70 entry:
71   %call = call <4 x double> (...) @d4()
72   %v0 = extractelement <4 x double> %call, i32 0
73   %v1 = extractelement <4 x double> %call, i32 1
74   %v2 = extractelement <4 x double> %call, i32 2
75   %v3 = extractelement <4 x double> %call, i32 3
76   %add1 = fadd double %v0, %v1
77   %add2 = fadd double %v2, %v3
78   %add3 = fadd double %add1, %add2
79   ret double %add3
81 ; CHECK-LABEL:        call_d4:
82 ; CHECK:        call16(d4)
83 ; CHECK:        addiu   $4, $sp, 32
84 ; CHECK:        ldc1    $[[R0:[a-z0-9]+]], 56($sp)
85 ; CHECK:        ldc1    $[[R1:[a-z0-9]+]], 48($sp)
86 ; CHECK:        ldc1    $[[R3:[a-z0-9]+]], 40($sp)
87 ; CHECK:        ldc1    $[[R4:[a-z0-9]+]], 32($sp)
92 ; Check that function accesses vector return value from registers in cases when
93 ; vector can be returned in registers
96 declare <4 x i32>    @i4(...)
97 declare <2 x float>  @f2(...)
98 declare <2 x double> @d2(...)
100 define i32 @call_i4() {
101 entry:
102   %call = call <4 x i32> (...) @i4()
103   %v0 = extractelement <4 x i32> %call, i32 0
104   %v1 = extractelement <4 x i32> %call, i32 1
105   %v2 = extractelement <4 x i32> %call, i32 2
106   %v3 = extractelement <4 x i32> %call, i32 3
107   %add1 = add i32 %v0, %v1
108   %add2 = add i32 %v2, %v3
109   %add3 = add i32 %add1, %add2
110   ret i32 %add3
112 ; CHECK-LABEL:        call_i4:
113 ; CHECK:        call16(i4)
114 ; CHECK-NOT:    lw
115 ; CHECK:        addu    $[[R2:[a-z0-9]+]], $[[R0:[a-z0-9]+]], $[[R1:[a-z0-9]+]]
116 ; CHECK:        addu    $[[R5:[a-z0-9]+]], $[[R3:[a-z0-9]+]], $[[R4:[a-z0-9]+]]
117 ; CHECK:        addu    $[[R6:[a-z0-9]+]], $[[R5]], $[[R2]]
121 define float @call_f2() {
122 entry:
123   %call = call <2 x float> (...) @f2()
124   %v0 = extractelement <2 x float> %call, i32 0
125   %v1 = extractelement <2 x float> %call, i32 1
126   %add1 = fadd float %v0, %v1
127   ret float %add1
129 ; CHECK-LABEL:        call_f2:
130 ; CHECK:        call16(f2)
131 ; CHECK:        addiu $4, $sp, [[O0:[0-9]+]]
132 ; CHECK-DAG:    lwc1 $f[[F0:[0-9]]], [[O0]]($sp)
133 ; CHECK-DAG:    lwc1 $f[[F1:[0-9]]], 20($sp)
134 ; CHECK:        add.s    $f0, $f[[F0]], $f[[F1]]
139 define double @call_d2() {
140 entry:
141   %call = call <2 x double> (...) @d2()
142   %v0 = extractelement <2 x double> %call, i32 0
143   %v1 = extractelement <2 x double> %call, i32 1
144   %add1 = fadd double %v0, %v1
145   ret double %add1
147 ; CHECK-LABEL:        call_d2:
148 ; CHECK:        call16(d2)
149 ; CHECK:        addiu $4, $sp, [[O0:[0-9]+]]
150 ; CHECK-DAG:    ldc1 $f[[F0:[0-9]+]], 24($sp)
151 ; CHECK-DAG:    ldc1 $f[[F1:[0-9]+]], [[O0]]($sp)
152 ; CHECK:        add.d    $f0, $f[[F1]], $f[[F0]]
156 ; Check that function returns vector on stack in cases when vector can't be
157 ; returned in registers. Also check that vector is placed on stack starting
158 ; from the address in register $4.
161 define <8 x i32> @return_i8() {
162 entry:
163   ret <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
165 ; CHECK-LABEL:        return_i8:
166 ; CHECK:        sw      $[[R0:[a-z0-9]+]], 28($4)
167 ; CHECK:        sw      $[[R1:[a-z0-9]+]], 24($4)
168 ; CHECK:        sw      $[[R2:[a-z0-9]+]], 20($4)
169 ; CHECK:        sw      $[[R3:[a-z0-9]+]], 16($4)
170 ; CHECK:        sw      $[[R4:[a-z0-9]+]], 12($4)
171 ; CHECK:        sw      $[[R5:[a-z0-9]+]], 8($4)
172 ; CHECK:        sw      $[[R6:[a-z0-9]+]], 4($4)
173 ; CHECK:        sw      $[[R7:[a-z0-9]+]], 0($4)
177 define <4 x float> @return_f4(float %a, float %b, float %c, float %d) {
178 entry:
179   %vecins1 = insertelement <4 x float> undef,    float %a, i32 0
180   %vecins2 = insertelement <4 x float> %vecins1, float %b, i32 1
181   %vecins3 = insertelement <4 x float> %vecins2, float %c, i32 2
182   %vecins4 = insertelement <4 x float> %vecins3, float %d, i32 3
183   ret <4 x float> %vecins4
185 ; CHECK-LABEL:        return_f4:
186 ; CHECK-DAG:    lwc1    $f[[R0:[0-9]+]], 16($sp)
187 ; CHECK-DAG:    swc1    $f[[R0]], 12($4)
188 ; CHECK-DAG:    sw      $7, 8($4)
189 ; CHECK-DAG:    sw      $6, 4($4)
190 ; CHECK-DAG:    sw      $5, 0($4)
195 define <4 x double> @return_d4(double %a, double %b, double %c, double %d) {
196 entry:
197   %vecins1 = insertelement <4 x double> undef,    double %a, i32 0
198   %vecins2 = insertelement <4 x double> %vecins1, double %b, i32 1
199   %vecins3 = insertelement <4 x double> %vecins2, double %c, i32 2
200   %vecins4 = insertelement <4 x double> %vecins3, double %d, i32 3
201   ret <4 x double> %vecins4
203 ; CHECK-LABEL:            return_d4:
204 ; CHECK-DAG:        sdc1    $[[R0:[a-z0-9]+]], 24($4)
205 ; CHECK-DAG:        sdc1    $[[R1:[a-z0-9]+]], 16($4)
206 ; CHECK-DAG:        sdc1    $[[R2:[a-z0-9]+]], 8($4)
207 ; CHECK-DAG:        sdc1    $[[R3:[a-z0-9]+]], 0($4)
212 ; Check that function returns vector in registers in cases when vector can be
213 ; returned in registers.
216 define <4 x i32> @return_i4() {
217 entry:
218   ret <4 x i32> <i32 0, i32 1, i32 2, i32 3>
220 ; CHECK-LABEL:        return_i4:
221 ; CHECK:        addiu   $2, $zero, 0
222 ; CHECK:        addiu   $3, $zero, 1
223 ; CHECK:        addiu   $4, $zero, 2
224 ; CHECK:        addiu   $5, $zero, 3
228 define <2 x float> @return_f2(float %a, float %b) {
229 entry:
230   %vecins1 = insertelement <2 x float> undef,    float %a, i32 0
231   %vecins2 = insertelement <2 x float> %vecins1, float %b, i32 1
232   ret <2 x float> %vecins2
234 ; CHECK-LABEL:        return_f2:
235 ; CHECK-DAG:    sw   $5, 0($4)
236 ; CHECK-DAG:    sw   $6, 4($4)
240 define <2 x double> @return_d2(double %a, double %b) {
241 entry:
242   %vecins1 = insertelement <2 x double> undef,    double %a, i32 0
243   %vecins2 = insertelement <2 x double> %vecins1, double %b, i32 1
244   ret <2 x double> %vecins2
246 ; CHECK-LABEL:        return_d2:
247 ; CHECK-DAG:    ldc1 $f[[F0:[0-9]]], 16($sp)
248 ; CHECK-DAG:    sdc1 $f[[F0]], 8($4)
249 ; CHECK-DAG:    mtc1 $6, $f[[F1:[0-9]+]]
250 ; CHECK-DAG:    mtc1 $7, $f
251 ; CHECK-DAG:    sdc1 $f[[F0]], 0($4)