[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / ARM / GlobalISel / arm-param-lowering.ll
blobe4f6c1ebe19dd5514876d2fd027f33f24142fd73
1 ; RUN: llc -O0 -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ARM -check-prefix=LITTLE
2 ; RUN: llc -O0 -mtriple armeb-unknown -mattr=+vfp2,+v4t -global-isel -global-isel-abort=0 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ARM -check-prefix=BIG
3 ; RUN: llc -O0 -mtriple thumb-unknown -mattr=+vfp2,+v6t2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE -check-prefix=THUMB
5 declare arm_aapcscc i32* @simple_reg_params_target(i32, i32*)
7 define arm_aapcscc i32* @test_call_simple_reg_params(i32 *%a, i32 %b) {
8 ; CHECK-LABEL: name: test_call_simple_reg_params
9 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r0
10 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r1
11 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
12 ; CHECK-DAG: $r0 = COPY [[BVREG]]
13 ; CHECK-DAG: $r1 = COPY [[AVREG]]
14 ; ARM: BL @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0
15 ; THUMB: tBL 14, $noreg, @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0
16 ; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0
17 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
18 ; CHECK: $r0 = COPY [[RVREG]]
19 ; ARM: BX_RET 14, $noreg, implicit $r0
20 ; THUMB: tBX_RET 14, $noreg, implicit $r0
21 entry:
22   %r = notail call arm_aapcscc i32 *@simple_reg_params_target(i32 %b, i32 *%a)
23   ret i32 *%r
26 declare arm_aapcscc i32* @simple_stack_params_target(i32, i32*, i32, i32*, i32, i32*)
28 define arm_aapcscc i32* @test_call_simple_stack_params(i32 *%a, i32 %b) {
29 ; CHECK-LABEL: name: test_call_simple_stack_params
30 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r0
31 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r1
32 ; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
33 ; CHECK-DAG: $r0 = COPY [[BVREG]]
34 ; CHECK-DAG: $r1 = COPY [[AVREG]]
35 ; CHECK-DAG: $r2 = COPY [[BVREG]]
36 ; CHECK-DAG: $r3 = COPY [[AVREG]]
37 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
38 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
39 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
40 ; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4
41 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
42 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
43 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
44 ; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0){{.*}}store 4
45 ; ARM: BL @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
46 ; THUMB: tBL 14, $noreg, @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
47 ; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0
48 ; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
49 ; CHECK: $r0 = COPY [[RVREG]]
50 ; ARM: BX_RET 14, $noreg, implicit $r0
51 ; THUMB: tBX_RET 14, $noreg, implicit $r0
52 entry:
53   %r = notail call arm_aapcscc i32 *@simple_stack_params_target(i32 %b, i32 *%a, i32 %b, i32 *%a, i32 %b, i32 *%a)
54   ret i32 *%r
57 declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext, i8 signext, i8 zeroext, i16 signext, i16 zeroext, i1 zeroext)
59 define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) {
60 ; CHECK-LABEL: name: test_call_ext_params
61 ; CHECK-DAG: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0
62 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s8) = G_TRUNC [[R0VREG]]
63 ; CHECK-DAG: [[R1VREG:%[0-9]+]]:_(s32) = COPY $r1
64 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R1VREG]]
65 ; CHECK-DAG: [[R2VREG:%[0-9]+]]:_(s32) = COPY $r2
66 ; CHECK-DAG: [[CVREG:%[0-9]+]]:_(s1) = G_TRUNC [[R2VREG]]
67 ; CHECK: ADJCALLSTACKDOWN 20, 0, 14, $noreg, implicit-def $sp, implicit $sp
68 ; CHECK: [[SEXTA:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]](s8)
69 ; CHECK: $r0 = COPY [[SEXTA]]
70 ; CHECK: [[ZEXTA:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]](s8)
71 ; CHECK: $r1 = COPY [[ZEXTA]]
72 ; CHECK: [[SEXTB:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]](s16)
73 ; CHECK: $r2 = COPY [[SEXTB]]
74 ; CHECK: [[ZEXTB:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]](s16)
75 ; CHECK: $r3 = COPY [[ZEXTB]]
76 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
77 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
78 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
79 ; CHECK: [[SEXTA2:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]]
80 ; CHECK: G_STORE [[SEXTA2]](s32), [[FI1]](p0){{.*}}store 4
81 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
82 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
83 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
84 ; CHECK: [[ZEXTA2:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]]
85 ; CHECK: G_STORE [[ZEXTA2]](s32), [[FI2]](p0){{.*}}store 4
86 ; CHECK: [[SP3:%[0-9]+]]:_(p0) = COPY $sp
87 ; CHECK: [[OFF3:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
88 ; CHECK: [[FI3:%[0-9]+]]:_(p0) = G_GEP [[SP3]], [[OFF3]](s32)
89 ; CHECK: [[SEXTB2:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]]
90 ; CHECK: G_STORE [[SEXTB2]](s32), [[FI3]](p0){{.*}}store 4
91 ; CHECK: [[SP4:%[0-9]+]]:_(p0) = COPY $sp
92 ; CHECK: [[OFF4:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
93 ; CHECK: [[FI4:%[0-9]+]]:_(p0) = G_GEP [[SP4]], [[OFF4]](s32)
94 ; CHECK: [[ZEXTB2:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]]
95 ; CHECK: G_STORE [[ZEXTB2]](s32), [[FI4]](p0){{.*}}store 4
96 ; CHECK: [[SP5:%[0-9]+]]:_(p0) = COPY $sp
97 ; CHECK: [[OFF5:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
98 ; CHECK: [[FI5:%[0-9]+]]:_(p0) = G_GEP [[SP5]], [[OFF5]](s32)
99 ; CHECK: [[ZEXTC:%[0-9]+]]:_(s32) = G_ZEXT [[CVREG]]
100 ; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store 4
101 ; ARM: BL @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
102 ; THUMB: tBL 14, $noreg, @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
103 ; CHECK: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0
104 ; CHECK: [[RVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R0VREG]]
105 ; CHECK: ADJCALLSTACKUP 20, 0, 14, $noreg, implicit-def $sp, implicit $sp
106 ; CHECK: [[RExtVREG:%[0-9]+]]:_(s32) = G_SEXT [[RVREG]]
107 ; CHECK: $r0 = COPY [[RExtVREG]]
108 ; ARM: BX_RET 14, $noreg, implicit $r0
109 ; THUMB: tBX_RET 14, $noreg, implicit $r0
110 entry:
111   %r = notail call arm_aapcscc signext i16 @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i1 zeroext %c)
112   ret i16 %r
115 declare arm_aapcs_vfpcc double @vfpcc_fp_target(float, double)
117 define arm_aapcs_vfpcc double @test_call_vfpcc_fp_params(double %a, float %b) {
118 ; CHECK-LABEL: name: test_call_vfpcc_fp_params
119 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s64) = COPY $d0
120 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $s2
121 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
122 ; CHECK-DAG: $s0 = COPY [[BVREG]]
123 ; CHECK-DAG: $d1 = COPY [[AVREG]]
124 ; ARM: BL @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0
125 ; THUMB: tBL 14, $noreg, @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0
126 ; CHECK: [[RVREG:%[0-9]+]]:_(s64) = COPY $d0
127 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
128 ; CHECK: $d0 = COPY [[RVREG]]
129 ; ARM: BX_RET 14, $noreg, implicit $d0
130 ; THUMB: tBX_RET 14, $noreg, implicit $d0
131 entry:
132   %r = notail call arm_aapcs_vfpcc double @vfpcc_fp_target(float %b, double %a)
133   ret double %r
136 declare arm_aapcscc double @aapcscc_fp_target(float, double, float, double)
138 define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) {
139 ; CHECK-LABEL: name: test_call_aapcs_fp_params
140 ; CHECK-DAG: [[A1:%[0-9]+]]:_(s32) = COPY $r0
141 ; CHECK-DAG: [[A2:%[0-9]+]]:_(s32) = COPY $r1
142 ; LITTLE-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A1]](s32), [[A2]](s32)
143 ; BIG-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A2]](s32), [[A1]](s32)
144 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r2
145 ; CHECK: ADJCALLSTACKDOWN 16, 0, 14, $noreg, implicit-def $sp, implicit $sp
146 ; CHECK-DAG: $r0 = COPY [[BVREG]]
147 ; CHECK-DAG: [[A1:%[0-9]+]]:_(s32), [[A2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AVREG]](s64)
148 ; LITTLE-DAG: $r2 = COPY [[A1]]
149 ; LITTLE-DAG: $r3 = COPY [[A2]]
150 ; BIG-DAG: $r2 = COPY [[A2]]
151 ; BIG-DAG: $r3 = COPY [[A1]]
152 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
153 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
154 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
155 ; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4
156 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
157 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
158 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
159 ; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0){{.*}}store 8
160 ; ARM: BL @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
161 ; THUMB: tBL 14, $noreg, @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
162 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r0
163 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r1
164 ; LITTLE: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R1]](s32), [[R2]](s32)
165 ; BIG: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R1]](s32)
166 ; CHECK: ADJCALLSTACKUP 16, 0, 14, $noreg, implicit-def $sp, implicit $sp
167 ; CHECK: [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[RVREG]](s64)
168 ; LITTLE-DAG: $r0 = COPY [[R1]]
169 ; LITTLE-DAG: $r1 = COPY [[R2]]
170 ; BIG-DAG: $r0 = COPY [[R2]]
171 ; BIG-DAG: $r1 = COPY [[R1]]
172 ; ARM: BX_RET 14, $noreg, implicit $r0, implicit $r1
173 ; THUMB: tBX_RET 14, $noreg, implicit $r0, implicit $r1
174 entry:
175   %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a, float %b, double %a)
176   ret double %r
179 declare arm_aapcscc float @different_call_conv_target(float)
181 define arm_aapcs_vfpcc float @test_call_different_call_conv(float %x) {
182 ; CHECK-LABEL: name: test_call_different_call_conv
183 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
184 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
185 ; CHECK: $r0 = COPY [[X]]
186 ; ARM: BL @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0
187 ; THUMB: tBL 14, $noreg, @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0
188 ; CHECK: [[R:%[0-9]+]]:_(s32) = COPY $r0
189 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
190 ; CHECK: $s0 = COPY [[R]]
191 ; ARM: BX_RET 14, $noreg, implicit $s0
192 ; THUMB: tBX_RET 14, $noreg, implicit $s0
193 entry:
194   %r = notail call arm_aapcscc float @different_call_conv_target(float %x)
195   ret float %r
198 declare arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32])
200 define arm_aapcscc [3 x i32] @test_tiny_int_arrays([2 x i32] %arr) {
201 ; CHECK-LABEL: name: test_tiny_int_arrays
202 ; CHECK: liveins: $r0, $r1
203 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
204 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
205 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
206 ; CHECK: $r0 = COPY [[R0]]
207 ; CHECK: $r1 = COPY [[R1]]
208 ; ARM: BL @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
209 ; THUMB: tBL 14, $noreg, @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
210 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
211 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
212 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2
213 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
214 ; FIXME: This doesn't seem correct with regard to the AAPCS docs (which say
215 ; that composite types larger than 4 bytes should be passed through memory),
216 ; but it's what DAGISel does. We should fix it in the common code for both.
217 ; CHECK: $r0 = COPY [[R0]]
218 ; CHECK: $r1 = COPY [[R1]]
219 ; CHECK: $r2 = COPY [[R2]]
220 ; ARM: BX_RET 14, $noreg, implicit $r0, implicit $r1, implicit $r2
221 ; THUMB: tBX_RET 14, $noreg, implicit $r0, implicit $r1, implicit $r2
222 entry:
223   %r = notail call arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32] %arr)
224   ret [3 x i32] %r
227 declare arm_aapcscc void @multiple_int_arrays_target([2 x i32], [2 x i32])
229 define arm_aapcscc void @test_multiple_int_arrays([2 x i32] %arr0, [2 x i32] %arr1) {
230 ; CHECK-LABEL: name: test_multiple_int_arrays
231 ; CHECK: liveins: $r0, $r1
232 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
233 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
234 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2
235 ; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $r3
236 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
237 ; CHECK: $r0 = COPY [[R0]]
238 ; CHECK: $r1 = COPY [[R1]]
239 ; CHECK: $r2 = COPY [[R2]]
240 ; CHECK: $r3 = COPY [[R3]]
241 ; ARM: BL @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
242 ; THUMB: tBL 14, $noreg, @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
243 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
244 ; ARM: BX_RET 14, $noreg
245 ; THUMB: tBX_RET 14, $noreg
246 entry:
247   notail call arm_aapcscc void @multiple_int_arrays_target([2 x i32] %arr0, [2 x i32] %arr1)
248   ret void
251 declare arm_aapcscc void @large_int_arrays_target([20 x i32])
253 define arm_aapcscc void @test_large_int_arrays([20 x i32] %arr) {
254 ; CHECK-LABEL: name: test_large_int_arrays
255 ; CHECK: fixedStack:
256 ; The parameters live in separate stack locations, one for each element that
257 ; doesn't fit in the registers.
258 ; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,
259 ; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 60, size: 4
260 ; CHECK: liveins: $r0, $r1, $r2, $r3
261 ; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0
262 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1
263 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2
264 ; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3
265 ; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]
266 ; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]]
267 ; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]
268 ; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]]
269 ; CHECK: ADJCALLSTACKDOWN 64, 0, 14, $noreg, implicit-def $sp, implicit $sp
270 ; CHECK: $r0 = COPY [[R0]]
271 ; CHECK: $r1 = COPY [[R1]]
272 ; CHECK: $r2 = COPY [[R2]]
273 ; CHECK: $r3 = COPY [[R3]]
274 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
275 ; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
276 ; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32)
277 ; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4
278 ; Match the second-to-last offset, so we can get the correct SP for the last element
279 ; CHECK: G_CONSTANT i32 56
280 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
281 ; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
282 ; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32)
283 ; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4
284 ; ARM: BL @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
285 ; THUMB: tBL 14, $noreg, @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
286 ; CHECK: ADJCALLSTACKUP 64, 0, 14, $noreg, implicit-def $sp, implicit $sp
287 ; ARM: BX_RET 14, $noreg
288 ; THUMB: tBX_RET 14, $noreg
289 entry:
290   notail call arm_aapcscc void @large_int_arrays_target([20 x i32] %arr)
291   ret void
294 declare arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double])
296 define arm_aapcscc [2 x float] @test_fp_arrays_aapcs([3 x double] %arr) {
297 ; CHECK-LABEL: name: test_fp_arrays_aapcs
298 ; CHECK: fixedStack:
299 ; CHECK: id: [[ARR2_ID:[0-9]+]], type: default, offset: 0, size: 8,
300 ; CHECK: liveins: $r0, $r1, $r2, $r3
301 ; CHECK: [[ARR0_0:%[0-9]+]]:_(s32) = COPY $r0
302 ; CHECK: [[ARR0_1:%[0-9]+]]:_(s32) = COPY $r1
303 ; LITTLE: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_0]](s32), [[ARR0_1]](s32)
304 ; BIG: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_1]](s32), [[ARR0_0]](s32)
305 ; CHECK: [[ARR1_0:%[0-9]+]]:_(s32) = COPY $r2
306 ; CHECK: [[ARR1_1:%[0-9]+]]:_(s32) = COPY $r3
307 ; LITTLE: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_0]](s32), [[ARR1_1]](s32)
308 ; BIG: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_1]](s32), [[ARR1_0]](s32)
309 ; CHECK: [[ARR2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[ARR2_ID]]
310 ; CHECK: [[ARR2:%[0-9]+]]:_(s64) = G_LOAD [[ARR2_FI]]{{.*}}load 8 from %fixed-stack.[[ARR2_ID]]
311 ; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
312 ; CHECK: [[ARR0_0:%[0-9]+]]:_(s32), [[ARR0_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR0]](s64)
313 ; LITTLE: $r0 = COPY [[ARR0_0]](s32)
314 ; LITTLE: $r1 = COPY [[ARR0_1]](s32)
315 ; BIG: $r0 = COPY [[ARR0_1]](s32)
316 ; BIG: $r1 = COPY [[ARR0_0]](s32)
317 ; CHECK: [[ARR1_0:%[0-9]+]]:_(s32), [[ARR1_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR1]](s64)
318 ; LITTLE: $r2 = COPY [[ARR1_0]](s32)
319 ; LITTLE: $r3 = COPY [[ARR1_1]](s32)
320 ; BIG: $r2 = COPY [[ARR1_1]](s32)
321 ; BIG: $r3 = COPY [[ARR1_0]](s32)
322 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
323 ; CHECK: [[ARR2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
324 ; CHECK: [[ARR2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[ARR2_OFFSET]](s32)
325 ; CHECK: G_STORE [[ARR2]](s64), [[ARR2_ADDR]](p0){{.*}}store 8
326 ; ARM: BL @fp_arrays_aapcs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
327 ; THUMB: tBL 14, $noreg, @fp_arrays_aapcs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
328 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
329 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
330 ; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
331 ; CHECK: $r0 = COPY [[R0]]
332 ; CHECK: $r1 = COPY [[R1]]
333 ; ARM: BX_RET 14, $noreg, implicit $r0, implicit $r1
334 ; THUMB: tBX_RET 14, $noreg, implicit $r0, implicit $r1
335 entry:
336   %r = notail call arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double] %arr)
337   ret [2 x float] %r
340 declare arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double], [3 x float], [4 x double])
342 define arm_aapcs_vfpcc [4 x float] @test_fp_arrays_aapcs_vfp([3 x double] %x, [3 x float] %y, [4 x double] %z) {
343 ; CHECK-LABEL: name: test_fp_arrays_aapcs_vfp
344 ; CHECK: fixedStack:
345 ; CHECK-DAG: id: [[Z0_ID:[0-9]+]], type: default, offset: 0, size: 8,
346 ; CHECK-DAG: id: [[Z1_ID:[0-9]+]], type: default, offset: 8, size: 8,
347 ; CHECK-DAG: id: [[Z2_ID:[0-9]+]], type: default, offset: 16, size: 8,
348 ; CHECK-DAG: id: [[Z3_ID:[0-9]+]], type: default, offset: 24, size: 8,
349 ; CHECK: liveins: $d0, $d1, $d2, $s6, $s7, $s8
350 ; CHECK: [[X0:%[0-9]+]]:_(s64) = COPY $d0
351 ; CHECK: [[X1:%[0-9]+]]:_(s64) = COPY $d1
352 ; CHECK: [[X2:%[0-9]+]]:_(s64) = COPY $d2
353 ; CHECK: [[Y0:%[0-9]+]]:_(s32) = COPY $s6
354 ; CHECK: [[Y1:%[0-9]+]]:_(s32) = COPY $s7
355 ; CHECK: [[Y2:%[0-9]+]]:_(s32) = COPY $s8
356 ; CHECK: [[Z0_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z0_ID]]
357 ; CHECK: [[Z0:%[0-9]+]]:_(s64) = G_LOAD [[Z0_FI]]{{.*}}load 8
358 ; CHECK: [[Z1_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z1_ID]]
359 ; CHECK: [[Z1:%[0-9]+]]:_(s64) = G_LOAD [[Z1_FI]]{{.*}}load 8
360 ; CHECK: [[Z2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z2_ID]]
361 ; CHECK: [[Z2:%[0-9]+]]:_(s64) = G_LOAD [[Z2_FI]]{{.*}}load 8
362 ; CHECK: [[Z3_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z3_ID]]
363 ; CHECK: [[Z3:%[0-9]+]]:_(s64) = G_LOAD [[Z3_FI]]{{.*}}load 8
364 ; CHECK: ADJCALLSTACKDOWN 32, 0, 14, $noreg, implicit-def $sp, implicit $sp
365 ; CHECK: $d0 = COPY [[X0]](s64)
366 ; CHECK: $d1 = COPY [[X1]](s64)
367 ; CHECK: $d2 = COPY [[X2]](s64)
368 ; CHECK: $s6 = COPY [[Y0]](s32)
369 ; CHECK: $s7 = COPY [[Y1]](s32)
370 ; CHECK: $s8 = COPY [[Y2]](s32)
371 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
372 ; CHECK: [[Z0_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
373 ; CHECK: [[Z0_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z0_OFFSET]](s32)
374 ; CHECK: G_STORE [[Z0]](s64), [[Z0_ADDR]](p0){{.*}}store 8
375 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
376 ; CHECK: [[Z1_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
377 ; CHECK: [[Z1_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z1_OFFSET]](s32)
378 ; CHECK: G_STORE [[Z1]](s64), [[Z1_ADDR]](p0){{.*}}store 8
379 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
380 ; CHECK: [[Z2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
381 ; CHECK: [[Z2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z2_OFFSET]](s32)
382 ; CHECK: G_STORE [[Z2]](s64), [[Z2_ADDR]](p0){{.*}}store 8
383 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
384 ; CHECK: [[Z3_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
385 ; CHECK: [[Z3_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z3_OFFSET]](s32)
386 ; CHECK: G_STORE [[Z3]](s64), [[Z3_ADDR]](p0){{.*}}store 8
387 ; ARM: BL @fp_arrays_aapcs_vfp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $d1, implicit $d2, implicit $s6, implicit $s7, implicit $s8, implicit-def $s0, implicit-def $s1, implicit-def $s2, implicit-def $s3
388 ; THUMB: tBL 14, $noreg, @fp_arrays_aapcs_vfp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $d1, implicit $d2, implicit $s6, implicit $s7, implicit $s8, implicit-def $s0, implicit-def $s1, implicit-def $s2, implicit-def $s3
389 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $s0
390 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $s1
391 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $s2
392 ; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $s3
393 ; CHECK: ADJCALLSTACKUP 32, 0, 14, $noreg, implicit-def $sp, implicit $sp
394 ; CHECK: $s0 = COPY [[R0]]
395 ; CHECK: $s1 = COPY [[R1]]
396 ; CHECK: $s2 = COPY [[R2]]
397 ; CHECK: $s3 = COPY [[R3]]
398 ; ARM: BX_RET 14, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3
399 ; THUMB: tBX_RET 14, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3
400 entry:
401   %r = notail call arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double] %x, [3 x float] %y, [4 x double] %z)
402   ret [4 x float] %r
405 declare arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr)
407 define arm_aapcscc [2 x i32*] @test_tough_arrays([6 x [4 x i32]] %arr) {
408 ; CHECK-LABEL: name: test_tough_arrays
409 ; CHECK: fixedStack:
410 ; The parameters live in separate stack locations, one for each element that
411 ; doesn't fit in the registers.
412 ; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,
413 ; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 76, size: 4
414 ; CHECK: liveins: $r0, $r1, $r2, $r3
415 ; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0
416 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1
417 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2
418 ; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3
419 ; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]
420 ; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]]
421 ; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]
422 ; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]]
423 ; CHECK: ADJCALLSTACKDOWN 80, 0, 14, $noreg, implicit-def $sp, implicit $sp
424 ; CHECK: $r0 = COPY [[R0]]
425 ; CHECK: $r1 = COPY [[R1]]
426 ; CHECK: $r2 = COPY [[R2]]
427 ; CHECK: $r3 = COPY [[R3]]
428 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
429 ; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
430 ; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32)
431 ; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4
432 ; Match the second-to-last offset, so we can get the correct SP for the last element
433 ; CHECK: G_CONSTANT i32 72
434 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
435 ; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 76
436 ; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32)
437 ; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4
438 ; ARM: BL @tough_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
439 ; THUMB: tBL 14, $noreg, @tough_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
440 ; CHECK: [[R0:%[0-9]+]]:_(p0) = COPY $r0
441 ; CHECK: [[R1:%[0-9]+]]:_(p0) = COPY $r1
442 ; CHECK: ADJCALLSTACKUP 80, 0, 14, $noreg, implicit-def $sp, implicit $sp
443 ; CHECK: $r0 = COPY [[R0]]
444 ; CHECK: $r1 = COPY [[R1]]
445 ; ARM: BX_RET 14, $noreg, implicit $r0, implicit $r1
446 ; THUMB: tBX_RET 14, $noreg, implicit $r0, implicit $r1
447 entry:
448   %r = notail call arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr)
449   ret [2 x i32*] %r
452 declare arm_aapcscc {i32, i32} @structs_target({i32, i32})
454 define arm_aapcscc {i32, i32} @test_structs({i32, i32} %x) {
455 ; CHECK-LABEL: test_structs
456 ; CHECK: liveins: $r0, $r1
457 ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY $r0
458 ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY $r1
459 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
460 ; CHECK-DAG: $r0 = COPY [[X0]](s32)
461 ; CHECK-DAG: $r1 = COPY [[X1]](s32)
462 ; ARM: BL @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
463 ; THUMB: tBL 14, $noreg, @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
464 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
465 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
466 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
467 ; CHECK: $r0 = COPY [[R0]](s32)
468 ; CHECK: $r1 = COPY [[R1]](s32)
469 ; ARM: BX_RET 14, $noreg, implicit $r0, implicit $r1
470 ; THUMB: tBX_RET 14, $noreg, implicit $r0, implicit $r1
471   %r = notail call arm_aapcscc {i32, i32} @structs_target({i32, i32} %x)
472   ret {i32, i32} %r