• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE
2; RUN: llc -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=BIG
3; XFAIL: armeb
4
5declare arm_aapcscc i32* @simple_reg_params_target(i32, i32*)
6
7define 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; CHECK: BL @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0
15; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0
16; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
17; CHECK: $r0 = COPY [[RVREG]]
18; CHECK: BX_RET 14, $noreg, implicit $r0
19entry:
20  %r = notail call arm_aapcscc i32 *@simple_reg_params_target(i32 %b, i32 *%a)
21  ret i32 *%r
22}
23
24declare arm_aapcscc i32* @simple_stack_params_target(i32, i32*, i32, i32*, i32, i32*)
25
26define arm_aapcscc i32* @test_call_simple_stack_params(i32 *%a, i32 %b) {
27; CHECK-LABEL: name: test_call_simple_stack_params
28; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r0
29; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r1
30; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
31; CHECK-DAG: $r0 = COPY [[BVREG]]
32; CHECK-DAG: $r1 = COPY [[AVREG]]
33; CHECK-DAG: $r2 = COPY [[BVREG]]
34; CHECK-DAG: $r3 = COPY [[AVREG]]
35; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
36; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
37; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
38; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4
39; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
40; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
41; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
42; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0){{.*}}store 4
43; CHECK: BL @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
44; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0
45; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
46; CHECK: $r0 = COPY [[RVREG]]
47; CHECK: BX_RET 14, $noreg, implicit $r0
48entry:
49  %r = notail call arm_aapcscc i32 *@simple_stack_params_target(i32 %b, i32 *%a, i32 %b, i32 *%a, i32 %b, i32 *%a)
50  ret i32 *%r
51}
52
53declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext, i8 signext, i8 zeroext, i16 signext, i16 zeroext, i1 zeroext)
54
55define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) {
56; CHECK-LABEL: name: test_call_ext_params
57; CHECK-DAG: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0
58; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s8) = G_TRUNC [[R0VREG]]
59; CHECK-DAG: [[R1VREG:%[0-9]+]]:_(s32) = COPY $r1
60; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R1VREG]]
61; CHECK-DAG: [[R2VREG:%[0-9]+]]:_(s32) = COPY $r2
62; CHECK-DAG: [[CVREG:%[0-9]+]]:_(s1) = G_TRUNC [[R2VREG]]
63; CHECK: ADJCALLSTACKDOWN 20, 0, 14, $noreg, implicit-def $sp, implicit $sp
64; CHECK: [[SEXTA:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]](s8)
65; CHECK: $r0 = COPY [[SEXTA]]
66; CHECK: [[ZEXTA:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]](s8)
67; CHECK: $r1 = COPY [[ZEXTA]]
68; CHECK: [[SEXTB:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]](s16)
69; CHECK: $r2 = COPY [[SEXTB]]
70; CHECK: [[ZEXTB:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]](s16)
71; CHECK: $r3 = COPY [[ZEXTB]]
72; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
73; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
74; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
75; CHECK: [[SEXTA2:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]]
76; CHECK: G_STORE [[SEXTA2]](s32), [[FI1]](p0){{.*}}store 4
77; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
78; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
79; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
80; CHECK: [[ZEXTA2:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]]
81; CHECK: G_STORE [[ZEXTA2]](s32), [[FI2]](p0){{.*}}store 4
82; CHECK: [[SP3:%[0-9]+]]:_(p0) = COPY $sp
83; CHECK: [[OFF3:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
84; CHECK: [[FI3:%[0-9]+]]:_(p0) = G_GEP [[SP3]], [[OFF3]](s32)
85; CHECK: [[SEXTB2:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]]
86; CHECK: G_STORE [[SEXTB2]](s32), [[FI3]](p0){{.*}}store 4
87; CHECK: [[SP4:%[0-9]+]]:_(p0) = COPY $sp
88; CHECK: [[OFF4:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
89; CHECK: [[FI4:%[0-9]+]]:_(p0) = G_GEP [[SP4]], [[OFF4]](s32)
90; CHECK: [[ZEXTB2:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]]
91; CHECK: G_STORE [[ZEXTB2]](s32), [[FI4]](p0){{.*}}store 4
92; CHECK: [[SP5:%[0-9]+]]:_(p0) = COPY $sp
93; CHECK: [[OFF5:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
94; CHECK: [[FI5:%[0-9]+]]:_(p0) = G_GEP [[SP5]], [[OFF5]](s32)
95; CHECK: [[ZEXTC:%[0-9]+]]:_(s32) = G_ZEXT [[CVREG]]
96; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store 4
97; CHECK: BL @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0
98; CHECK: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0
99; CHECK: [[RVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R0VREG]]
100; CHECK: ADJCALLSTACKUP 20, 0, 14, $noreg, implicit-def $sp, implicit $sp
101; CHECK: [[RExtVREG:%[0-9]+]]:_(s32) = G_SEXT [[RVREG]]
102; CHECK: $r0 = COPY [[RExtVREG]]
103; CHECK: BX_RET 14, $noreg, implicit $r0
104entry:
105  %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)
106  ret i16 %r
107}
108
109declare arm_aapcs_vfpcc double @vfpcc_fp_target(float, double)
110
111define arm_aapcs_vfpcc double @test_call_vfpcc_fp_params(double %a, float %b) {
112; CHECK-LABEL: name: test_call_vfpcc_fp_params
113; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s64) = COPY $d0
114; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $s2
115; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
116; CHECK-DAG: $s0 = COPY [[BVREG]]
117; CHECK-DAG: $d1 = COPY [[AVREG]]
118; CHECK: BL @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0
119; CHECK: [[RVREG:%[0-9]+]]:_(s64) = COPY $d0
120; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
121; CHECK: $d0 = COPY [[RVREG]]
122; CHECK: BX_RET 14, $noreg, implicit $d0
123entry:
124  %r = notail call arm_aapcs_vfpcc double @vfpcc_fp_target(float %b, double %a)
125  ret double %r
126}
127
128declare arm_aapcscc double @aapcscc_fp_target(float, double, float, double)
129
130define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) {
131; CHECK-LABEL: name: test_call_aapcs_fp_params
132; CHECK-DAG: [[A1:%[0-9]+]]:_(s32) = COPY $r0
133; CHECK-DAG: [[A2:%[0-9]+]]:_(s32) = COPY $r1
134; LITTLE-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A1]](s32), [[A2]](s32)
135; BIG-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A2]](s32), [[A1]](s32)
136; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r2
137; CHECK: ADJCALLSTACKDOWN 16, 0, 14, $noreg, implicit-def $sp, implicit $sp
138; CHECK-DAG: $r0 = COPY [[BVREG]]
139; CHECK-DAG: [[A1:%[0-9]+]]:_(s32), [[A2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AVREG]](s64)
140; LITTLE-DAG: $r2 = COPY [[A1]]
141; LITTLE-DAG: $r3 = COPY [[A2]]
142; BIG-DAG: $r2 = COPY [[A2]]
143; BIG-DAG: $r3 = COPY [[A1]]
144; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp
145; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
146; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32)
147; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4
148; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp
149; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
150; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32)
151; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0){{.*}}store 8
152; CHECK: BL @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1
153; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r0
154; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r1
155; LITTLE: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R1]](s32), [[R2]](s32)
156; BIG: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R1]](s32)
157; CHECK: ADJCALLSTACKUP 16, 0, 14, $noreg, implicit-def $sp, implicit $sp
158; CHECK: [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[RVREG]](s64)
159; LITTLE-DAG: $r0 = COPY [[R1]]
160; LITTLE-DAG: $r1 = COPY [[R2]]
161; BIG-DAG: $r0 = COPY [[R2]]
162; BIG-DAG: $r1 = COPY [[R1]]
163; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1
164entry:
165  %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a, float %b, double %a)
166  ret double %r
167}
168
169declare arm_aapcscc float @different_call_conv_target(float)
170
171define arm_aapcs_vfpcc float @test_call_different_call_conv(float %x) {
172; CHECK-LABEL: name: test_call_different_call_conv
173; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
174; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
175; CHECK: $r0 = COPY [[X]]
176; CHECK: BL @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0
177; CHECK: [[R:%[0-9]+]]:_(s32) = COPY $r0
178; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
179; CHECK: $s0 = COPY [[R]]
180; CHECK: BX_RET 14, $noreg, implicit $s0
181entry:
182  %r = notail call arm_aapcscc float @different_call_conv_target(float %x)
183  ret float %r
184}
185
186declare arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32])
187
188define arm_aapcscc [3 x i32] @test_tiny_int_arrays([2 x i32] %arr) {
189; CHECK-LABEL: name: test_tiny_int_arrays
190; CHECK: liveins: $r0, $r1
191; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
192; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
193; CHECK: [[ARG_ARR:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32)
194; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR]](s64), 0
195; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR]](s64), 32
196; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
197; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0
198; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32
199; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
200; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64)
201; CHECK: $r0 = COPY [[R0]]
202; CHECK: $r1 = COPY [[R1]]
203; CHECK: BL @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
204; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
205; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
206; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2
207; CHECK: [[RES_ARR:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32)
208; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
209; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 0
210; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 32
211; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 64
212; CHECK: [[IMPDEF2:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
213; CHECK: [[INS3:%[0-9]+]]:_(s96) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0
214; CHECK: [[INS4:%[0-9]+]]:_(s96) = G_INSERT [[INS3]], [[EXT4]](s32), 32
215; CHECK: [[INS5:%[0-9]+]]:_(s96) = G_INSERT [[INS4]], [[EXT5]](s32), 64
216; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS5]](s96)
217; FIXME: This doesn't seem correct with regard to the AAPCS docs (which say
218; that composite types larger than 4 bytes should be passed through memory),
219; but it's what DAGISel does. We should fix it in the common code for both.
220; CHECK: $r0 = COPY [[R0]]
221; CHECK: $r1 = COPY [[R1]]
222; CHECK: $r2 = COPY [[R2]]
223; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1, implicit $r2
224entry:
225  %r = notail call arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32] %arr)
226  ret [3 x i32] %r
227}
228
229declare arm_aapcscc void @multiple_int_arrays_target([2 x i32], [2 x i32])
230
231define arm_aapcscc void @test_multiple_int_arrays([2 x i32] %arr0, [2 x i32] %arr1) {
232; CHECK-LABEL: name: test_multiple_int_arrays
233; CHECK: liveins: $r0, $r1
234; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
235; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
236; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2
237; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $r3
238; CHECK: [[ARG_ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32)
239; CHECK: [[ARG_ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R3]](s32)
240; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR0]](s64), 0
241; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR0]](s64), 32
242; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR1]](s64), 0
243; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR1]](s64), 32
244; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
245; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0
246; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32
247; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
248; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0
249; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[INS3]], [[EXT4]](s32), 32
250; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
251; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64)
252; CHECK: [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS4]](s64)
253; CHECK: $r0 = COPY [[R0]]
254; CHECK: $r1 = COPY [[R1]]
255; CHECK: $r2 = COPY [[R2]]
256; CHECK: $r3 = COPY [[R3]]
257; CHECK: BL @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
258; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
259; CHECK: BX_RET 14, $noreg
260entry:
261  notail call arm_aapcscc void @multiple_int_arrays_target([2 x i32] %arr0, [2 x i32] %arr1)
262  ret void
263}
264
265declare arm_aapcscc void @large_int_arrays_target([20 x i32])
266
267define arm_aapcscc void @test_large_int_arrays([20 x i32] %arr) {
268; CHECK-LABEL: name: test_large_int_arrays
269; CHECK: fixedStack:
270; The parameters live in separate stack locations, one for each element that
271; doesn't fit in the registers.
272; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,
273; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 60, size: 4
274; CHECK: liveins: $r0, $r1, $r2, $r3
275; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0
276; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1
277; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2
278; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3
279; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]
280; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]]
281; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]
282; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]]
283; CHECK: [[ARG_ARR:%[0-9]+]]:_(s640) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32), [[FIRST_STACK_ELEMENT]](s32), {{.*}}, [[LAST_STACK_ELEMENT]](s32)
284; CHECK: [[INS:%[0-9]+]]:_(s640) = G_INSERT {{.*}}, {{.*}}(s32), 608
285; CHECK: ADJCALLSTACKDOWN 64, 0, 14, $noreg, implicit-def $sp, implicit $sp
286; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32), [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32), {{.*}}, [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS]](s640)
287; CHECK: $r0 = COPY [[R0]]
288; CHECK: $r1 = COPY [[R1]]
289; CHECK: $r2 = COPY [[R2]]
290; CHECK: $r3 = COPY [[R3]]
291; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
292; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
293; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32)
294; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4
295; Match the second-to-last offset, so we can get the correct SP for the last element
296; CHECK: G_CONSTANT i32 56
297; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
298; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
299; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32)
300; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4
301; CHECK: BL @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3
302; CHECK: ADJCALLSTACKUP 64, 0, 14, $noreg, implicit-def $sp, implicit $sp
303; CHECK: BX_RET 14, $noreg
304entry:
305  notail call arm_aapcscc void @large_int_arrays_target([20 x i32] %arr)
306  ret void
307}
308
309declare arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double])
310
311define arm_aapcscc [2 x float] @test_fp_arrays_aapcs([3 x double] %arr) {
312; CHECK-LABEL: name: test_fp_arrays_aapcs
313; CHECK: fixedStack:
314; CHECK: id: [[ARR2_ID:[0-9]+]], type: default, offset: 0, size: 8,
315; CHECK: liveins: $r0, $r1, $r2, $r3
316; CHECK: [[ARR0_0:%[0-9]+]]:_(s32) = COPY $r0
317; CHECK: [[ARR0_1:%[0-9]+]]:_(s32) = COPY $r1
318; LITTLE: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_0]](s32), [[ARR0_1]](s32)
319; BIG: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_1]](s32), [[ARR0_0]](s32)
320; CHECK: [[ARR1_0:%[0-9]+]]:_(s32) = COPY $r2
321; CHECK: [[ARR1_1:%[0-9]+]]:_(s32) = COPY $r3
322; LITTLE: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_0]](s32), [[ARR1_1]](s32)
323; BIG: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_1]](s32), [[ARR1_0]](s32)
324; CHECK: [[ARR2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[ARR2_ID]]
325; CHECK: [[ARR2:%[0-9]+]]:_(s64) = G_LOAD [[ARR2_FI]]{{.*}}load 8 from %fixed-stack.[[ARR2_ID]]
326; CHECK: [[ARR_MERGED:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[ARR0]](s64), [[ARR1]](s64), [[ARR2]](s64)
327; CHECK: [[EXT1:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 0
328; CHECK: [[EXT2:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 64
329; CHECK: [[EXT3:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 128
330; CHECK: [[IMPDEF:%[0-9]+]]:_(s192) = G_IMPLICIT_DEF
331; CHECK: [[INS1:%[0-9]+]]:_(s192) = G_INSERT [[IMPDEF]], [[EXT1]](s64), 0
332; CHECK: [[INS2:%[0-9]+]]:_(s192) = G_INSERT [[INS1]], [[EXT2]](s64), 64
333; CHECK: [[INS3:%[0-9]+]]:_(s192) = G_INSERT [[INS2]], [[EXT3]](s64), 128
334; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
335; CHECK: [[ARR0:%[0-9]+]]:_(s64), [[ARR1:%[0-9]+]]:_(s64), [[ARR2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS3]](s192)
336; CHECK: [[ARR0_0:%[0-9]+]]:_(s32), [[ARR0_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR0]](s64)
337; LITTLE: $r0 = COPY [[ARR0_0]](s32)
338; LITTLE: $r1 = COPY [[ARR0_1]](s32)
339; BIG: $r0 = COPY [[ARR0_1]](s32)
340; BIG: $r1 = COPY [[ARR0_0]](s32)
341; CHECK: [[ARR1_0:%[0-9]+]]:_(s32), [[ARR1_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR1]](s64)
342; LITTLE: $r2 = COPY [[ARR1_0]](s32)
343; LITTLE: $r3 = COPY [[ARR1_1]](s32)
344; BIG: $r2 = COPY [[ARR1_1]](s32)
345; BIG: $r3 = COPY [[ARR1_0]](s32)
346; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
347; CHECK: [[ARR2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
348; CHECK: [[ARR2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[ARR2_OFFSET]](s32)
349; CHECK: G_STORE [[ARR2]](s64), [[ARR2_ADDR]](p0){{.*}}store 8
350; CHECK: 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
351; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
352; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
353; CHECK: [[R_MERGED:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32)
354; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp
355; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s64), 0
356; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s64), 32
357; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
358; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT4]](s32), 0
359; CHECK: [[INS5:%[0-9]+]]:_(s64) = G_INSERT [[INS4]], [[EXT5]](s32), 32
360; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS5]](s64)
361; CHECK: $r0 = COPY [[R0]]
362; CHECK: $r1 = COPY [[R1]]
363; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1
364entry:
365  %r = notail call arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double] %arr)
366  ret [2 x float] %r
367}
368
369declare arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double], [3 x float], [4 x double])
370
371define arm_aapcs_vfpcc [4 x float] @test_fp_arrays_aapcs_vfp([3 x double] %x, [3 x float] %y, [4 x double] %z) {
372; CHECK-LABEL: name: test_fp_arrays_aapcs_vfp
373; CHECK: fixedStack:
374; CHECK-DAG: id: [[Z0_ID:[0-9]+]], type: default, offset: 0, size: 8,
375; CHECK-DAG: id: [[Z1_ID:[0-9]+]], type: default, offset: 8, size: 8,
376; CHECK-DAG: id: [[Z2_ID:[0-9]+]], type: default, offset: 16, size: 8,
377; CHECK-DAG: id: [[Z3_ID:[0-9]+]], type: default, offset: 24, size: 8,
378; CHECK: liveins: $d0, $d1, $d2, $s6, $s7, $s8
379; CHECK: [[X0:%[0-9]+]]:_(s64) = COPY $d0
380; CHECK: [[X1:%[0-9]+]]:_(s64) = COPY $d1
381; CHECK: [[X2:%[0-9]+]]:_(s64) = COPY $d2
382; CHECK: [[Y0:%[0-9]+]]:_(s32) = COPY $s6
383; CHECK: [[Y1:%[0-9]+]]:_(s32) = COPY $s7
384; CHECK: [[Y2:%[0-9]+]]:_(s32) = COPY $s8
385; CHECK: [[Z0_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z0_ID]]
386; CHECK: [[Z0:%[0-9]+]]:_(s64) = G_LOAD [[Z0_FI]]{{.*}}load 8
387; CHECK: [[Z1_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z1_ID]]
388; CHECK: [[Z1:%[0-9]+]]:_(s64) = G_LOAD [[Z1_FI]]{{.*}}load 8
389; CHECK: [[Z2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z2_ID]]
390; CHECK: [[Z2:%[0-9]+]]:_(s64) = G_LOAD [[Z2_FI]]{{.*}}load 8
391; CHECK: [[Z3_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z3_ID]]
392; CHECK: [[Z3:%[0-9]+]]:_(s64) = G_LOAD [[Z3_FI]]{{.*}}load 8
393; CHECK: [[X_ARR:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[X0]](s64), [[X1]](s64), [[X2]](s64)
394; CHECK: [[Y_ARR:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[Y0]](s32), [[Y1]](s32), [[Y2]](s32)
395; CHECK: [[Z_ARR:%[0-9]+]]:_(s256) = G_MERGE_VALUES [[Z0]](s64), [[Z1]](s64), [[Z2]](s64), [[Z3]](s64)
396; CHECK: [[EXT1:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 0
397; CHECK: [[EXT2:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 64
398; CHECK: [[EXT3:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 128
399; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 0
400; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 32
401; CHECK: [[EXT6:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 64
402; CHECK: [[EXT7:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 0
403; CHECK: [[EXT8:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 64
404; CHECK: [[EXT9:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 128
405; CHECK: [[EXT10:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 192
406; CHECK: [[IMPDEF:%[0-9]+]]:_(s192) = G_IMPLICIT_DEF
407; CHECK: [[INS1:%[0-9]+]]:_(s192) = G_INSERT [[IMPDEF]], [[EXT1]](s64), 0
408; CHECK: [[INS2:%[0-9]+]]:_(s192) = G_INSERT [[INS1]], [[EXT2]](s64), 64
409; CHECK: [[INS3:%[0-9]+]]:_(s192) = G_INSERT [[INS2]], [[EXT3]](s64), 128
410; CHECK: [[IMPDEF2:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
411; CHECK: [[INS4:%[0-9]+]]:_(s96) = G_INSERT [[IMPDEF2]], [[EXT4]](s32), 0
412; CHECK: [[INS5:%[0-9]+]]:_(s96) = G_INSERT [[INS4]], [[EXT5]](s32), 32
413; CHECK: [[INS6:%[0-9]+]]:_(s96) = G_INSERT [[INS5]], [[EXT6]](s32), 64
414; CHECK: [[IMPDEF3:%[0-9]+]]:_(s256) = G_IMPLICIT_DEF
415; CHECK: [[INS7:%[0-9]+]]:_(s256) = G_INSERT [[IMPDEF3]], [[EXT7]](s64), 0
416; CHECK: [[INS8:%[0-9]+]]:_(s256) = G_INSERT [[INS7]], [[EXT8]](s64), 64
417; CHECK: [[INS9:%[0-9]+]]:_(s256) = G_INSERT [[INS8]], [[EXT9]](s64), 128
418; CHECK: [[INS10:%[0-9]+]]:_(s256) = G_INSERT [[INS9]], [[EXT10]](s64), 192
419; CHECK: ADJCALLSTACKDOWN 32, 0, 14, $noreg, implicit-def $sp, implicit $sp
420; CHECK: [[X0:%[0-9]+]]:_(s64), [[X1:%[0-9]+]]:_(s64), [[X2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS3]](s192)
421; CHECK: [[Y0:%[0-9]+]]:_(s32), [[Y1:%[0-9]+]]:_(s32), [[Y2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS6]](s96)
422; CHECK: [[Z0:%[0-9]+]]:_(s64), [[Z1:%[0-9]+]]:_(s64), [[Z2:%[0-9]+]]:_(s64), [[Z3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS10]](s256)
423; CHECK: $d0 = COPY [[X0]](s64)
424; CHECK: $d1 = COPY [[X1]](s64)
425; CHECK: $d2 = COPY [[X2]](s64)
426; CHECK: $s6 = COPY [[Y0]](s32)
427; CHECK: $s7 = COPY [[Y1]](s32)
428; CHECK: $s8 = COPY [[Y2]](s32)
429; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
430; CHECK: [[Z0_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
431; CHECK: [[Z0_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z0_OFFSET]](s32)
432; CHECK: G_STORE [[Z0]](s64), [[Z0_ADDR]](p0){{.*}}store 8
433; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
434; CHECK: [[Z1_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
435; CHECK: [[Z1_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z1_OFFSET]](s32)
436; CHECK: G_STORE [[Z1]](s64), [[Z1_ADDR]](p0){{.*}}store 8
437; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
438; CHECK: [[Z2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
439; CHECK: [[Z2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z2_OFFSET]](s32)
440; CHECK: G_STORE [[Z2]](s64), [[Z2_ADDR]](p0){{.*}}store 8
441; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
442; CHECK: [[Z3_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
443; CHECK: [[Z3_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z3_OFFSET]](s32)
444; CHECK: G_STORE [[Z3]](s64), [[Z3_ADDR]](p0){{.*}}store 8
445; CHECK: 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
446; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $s0
447; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $s1
448; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $s2
449; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $s3
450; CHECK: [[R_MERGED:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32)
451; CHECK: ADJCALLSTACKUP 32, 0, 14, $noreg, implicit-def $sp, implicit $sp
452; CHECK: [[EXT11:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 0
453; CHECK: [[EXT12:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 32
454; CHECK: [[EXT13:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 64
455; CHECK: [[EXT14:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 96
456; CHECK: [[IMPDEF4:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF
457; CHECK: [[INS11:%[0-9]+]]:_(s128) = G_INSERT [[IMPDEF4]], [[EXT11]](s32), 0
458; CHECK: [[INS12:%[0-9]+]]:_(s128) = G_INSERT [[INS11]], [[EXT12]](s32), 32
459; CHECK: [[INS13:%[0-9]+]]:_(s128) = G_INSERT [[INS12]], [[EXT13]](s32), 64
460; CHECK: [[INS14:%[0-9]+]]:_(s128) = G_INSERT [[INS13]], [[EXT14]](s32), 96
461; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS14]](s128)
462; CHECK: $s0 = COPY [[R0]]
463; CHECK: $s1 = COPY [[R1]]
464; CHECK: $s2 = COPY [[R2]]
465; CHECK: $s3 = COPY [[R3]]
466; CHECK: BX_RET 14, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3
467entry:
468  %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)
469  ret [4 x float] %r
470}
471
472declare arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr)
473
474define arm_aapcscc [2 x i32*] @test_tough_arrays([6 x [4 x i32]] %arr) {
475; CHECK-LABEL: name: test_tough_arrays
476; CHECK: fixedStack:
477; The parameters live in separate stack locations, one for each element that
478; doesn't fit in the registers.
479; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,
480; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 76, size: 4
481; CHECK: liveins: $r0, $r1, $r2, $r3
482; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0
483; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1
484; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2
485; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3
486; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]
487; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]]
488; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]
489; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]]
490; CHECK: [[ARG_ARR:%[0-9]+]]:_(s768) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32), [[FIRST_STACK_ELEMENT]](s32), {{.*}}, [[LAST_STACK_ELEMENT]](s32)
491; CHECK: [[INS:%[0-9]+]]:_(s768) = G_INSERT {{.*}}, {{.*}}(s32), 736
492; CHECK: ADJCALLSTACKDOWN 80, 0, 14, $noreg, implicit-def $sp, implicit $sp
493; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32), [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32), {{.*}}, [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS]](s768)
494; CHECK: $r0 = COPY [[R0]]
495; CHECK: $r1 = COPY [[R1]]
496; CHECK: $r2 = COPY [[R2]]
497; CHECK: $r3 = COPY [[R3]]
498; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
499; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
500; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32)
501; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4
502; Match the second-to-last offset, so we can get the correct SP for the last element
503; CHECK: G_CONSTANT i32 72
504; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
505; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 76
506; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32)
507; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4
508; CHECK: 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
509; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
510; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
511; CHECK: [[RES_ARR:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32)
512; CHECK: ADJCALLSTACKUP 80, 0, 14, $noreg, implicit-def $sp, implicit $sp
513; CHECK: [[EXT1:%[0-9]+]]:_(p0) = G_EXTRACT [[RES_ARR]](s64), 0
514; CHECK: [[EXT2:%[0-9]+]]:_(p0) = G_EXTRACT [[RES_ARR]](s64), 32
515; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
516; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](p0), 0
517; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[INS2]], [[EXT2]](p0), 32
518; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS3]](s64)
519; CHECK: $r0 = COPY [[R0]]
520; CHECK: $r1 = COPY [[R1]]
521; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1
522entry:
523  %r = notail call arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr)
524  ret [2 x i32*] %r
525}
526
527declare arm_aapcscc {i32, i32} @structs_target({i32, i32})
528
529define arm_aapcscc {i32, i32} @test_structs({i32, i32} %x) {
530; CHECK-LABEL: test_structs
531; CHECK: liveins: $r0, $r1
532; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY $r0
533; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY $r1
534; CHECK: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]](s32), [[X1]](s32)
535; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[X]](s64), 0
536; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[X]](s64), 32
537; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
538; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0
539; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32
540; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
541; CHECK: [[X0:%[0-9]+]]:_(s32), [[X1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64)
542; CHECK-DAG: $r0 = COPY [[X0]](s32)
543; CHECK-DAG: $r1 = COPY [[X1]](s32)
544; CHECK: BL @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1
545; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0
546; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1
547; CHECK: [[R:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32)
548; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
549; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[R]](s64), 0
550; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[R]](s64), 32
551; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
552; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0
553; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[INS3]], [[EXT4]](s32), 32
554; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS4]](s64)
555; CHECK: $r0 = COPY [[R0]](s32)
556; CHECK: $r1 = COPY [[R1]](s32)
557; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1
558  %r = notail call arm_aapcscc {i32, i32} @structs_target({i32, i32} %x)
559  ret {i32, i32} %r
560}
561