• 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
4define void @test_void_return() {
5; CHECK-LABEL: name: test_void_return
6; CHECK: BX_RET 14 /* CC::al */, $noreg
7entry:
8  ret void
9}
10
11define signext i1 @test_add_i1(i1 %x, i1 %y) {
12; CHECK-LABEL: name: test_add_i1
13; CHECK: liveins: $r0, $r1
14; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
15; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s1) = G_TRUNC [[VREGR0]]
16; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
17; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s1) = G_TRUNC [[VREGR1]]
18; CHECK: [[SUM:%[0-9]+]]:_(s1) = G_ADD [[VREGX]], [[VREGY]]
19; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_SEXT [[SUM]]
20; CHECK: $r0 = COPY [[EXT]](s32)
21; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
22entry:
23  %sum = add i1 %x, %y
24  ret i1 %sum
25}
26
27define i8 @test_add_i8(i8 %x, i8 %y) {
28; CHECK-LABEL: name: test_add_i8
29; CHECK: liveins: $r0, $r1
30; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
31; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
32; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
33; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR1]]
34; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGX]], [[VREGY]]
35; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
36; CHECK: $r0 = COPY [[SUM_EXT]](s32)
37; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
38entry:
39  %sum = add i8 %x, %y
40  ret i8 %sum
41}
42
43define i8 @test_sub_i8(i8 %x, i8 %y) {
44; CHECK-LABEL: name: test_sub_i8
45; CHECK: liveins: $r0, $r1
46; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
47; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
48; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
49; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR1]]
50; CHECK: [[RES:%[0-9]+]]:_(s8) = G_SUB [[VREGX]], [[VREGY]]
51; CHECK: [[RES_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[RES]]
52; CHECK: $r0 = COPY [[RES_EXT]](s32)
53; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
54entry:
55  %res = sub i8 %x, %y
56  ret i8 %res
57}
58
59define signext i8 @test_return_sext_i8(i8 %x) {
60; CHECK-LABEL: name: test_return_sext_i8
61; CHECK: liveins: $r0
62; CHECK: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
63; CHECK: [[VREG:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR0]]
64; CHECK: [[VREGEXT:%[0-9]+]]:_(s32) = G_SEXT [[VREG]]
65; CHECK: $r0 = COPY [[VREGEXT]](s32)
66; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
67entry:
68  ret i8 %x
69}
70
71define i16 @test_add_i16(i16 %x, i16 %y) {
72; CHECK-LABEL: name: test_add_i16
73; CHECK: liveins: $r0, $r1
74; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
75; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
76; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
77; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
78; CHECK: [[SUM:%[0-9]+]]:_(s16) = G_ADD [[VREGX]], [[VREGY]]
79; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
80; CHECK: $r0 = COPY [[SUM_EXT]](s32)
81; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
82entry:
83  %sum = add i16 %x, %y
84  ret i16 %sum
85}
86
87define i16 @test_sub_i16(i16 %x, i16 %y) {
88; CHECK-LABEL: name: test_sub_i16
89; CHECK: liveins: $r0, $r1
90; CHECK-DAG: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
91; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
92; CHECK-DAG: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
93; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
94; CHECK: [[RES:%[0-9]+]]:_(s16) = G_SUB [[VREGX]], [[VREGY]]
95; CHECK: [[RES_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[RES]]
96; CHECK: $r0 = COPY [[RES_EXT]](s32)
97; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
98entry:
99  %res = sub i16 %x, %y
100  ret i16 %res
101}
102
103define zeroext i16 @test_return_zext_i16(i16 %x) {
104; CHECK-LABEL: name: test_return_zext_i16
105; CHECK: liveins: $r0
106; CHECK: [[VREGR0:%[0-9]+]]:_(s32) = COPY $r0
107; CHECK: [[VREG:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR0]]
108; CHECK: [[VREGEXT:%[0-9]+]]:_(s32) = G_ZEXT [[VREG]]
109; CHECK: $r0 = COPY [[VREGEXT]](s32)
110; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
111entry:
112  ret i16 %x
113}
114
115define i32 @test_add_i32(i32 %x, i32 %y) {
116; CHECK-LABEL: name: test_add_i32
117; CHECK: liveins: $r0, $r1
118; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s32) = COPY $r0
119; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s32) = COPY $r1
120; CHECK: [[SUM:%[0-9]+]]:_(s32) = G_ADD [[VREGX]], [[VREGY]]
121; CHECK: $r0 = COPY [[SUM]](s32)
122; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
123entry:
124  %sum = add i32 %x, %y
125  ret i32 %sum
126}
127
128define i32 @test_sub_i32(i32 %x, i32 %y) {
129; CHECK-LABEL: name: test_sub_i32
130; CHECK: liveins: $r0, $r1
131; CHECK-DAG: [[VREGX:%[0-9]+]]:_(s32) = COPY $r0
132; CHECK-DAG: [[VREGY:%[0-9]+]]:_(s32) = COPY $r1
133; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SUB [[VREGX]], [[VREGY]]
134; CHECK: $r0 = COPY [[RES]](s32)
135; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
136entry:
137  %res = sub i32 %x, %y
138  ret i32 %res
139}
140
141define i32 @test_stack_args(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
142; CHECK-LABEL: name: test_stack_args
143; CHECK: fixedStack:
144; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 4
145; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 4
146; CHECK: liveins: $r0, $r1, $r2, $r3
147; CHECK: [[VREGP2:%[0-9]+]]:_(s32) = COPY $r2
148; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
149; CHECK: [[VREGP5:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]]{{.*}}load 4
150; CHECK: [[SUM:%[0-9]+]]:_(s32) = G_ADD [[VREGP2]], [[VREGP5]]
151; CHECK: $r0 = COPY [[SUM]]
152; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
153entry:
154  %sum = add i32 %p2, %p5
155  ret i32 %sum
156}
157
158define i16 @test_stack_args_signext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
159                                    i8 signext %p4, i16 signext %p5) {
160; CHECK-LABEL: name: test_stack_args_signext
161; CHECK: fixedStack:
162; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
163; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
164; CHECK: liveins: $r0, $r1, $r2, $r3
165; CHECK: [[VREGR1:%[0-9]+]]:_(s32) = COPY $r1
166; CHECK: [[VREGP1:%[0-9]+]]:_(s16) = G_TRUNC [[VREGR1]]
167; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
168; CHECK: [[VREGP5EXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
169; CHECK: [[VREGP5:%[0-9]+]]:_(s16) = G_TRUNC [[VREGP5EXT]]
170; CHECK: [[SUM:%[0-9]+]]:_(s16) = G_ADD [[VREGP1]], [[VREGP5]]
171; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
172; CHECK: $r0 = COPY [[SUM_EXT]](s32)
173; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
174entry:
175  %sum = add i16 %p1, %p5
176  ret i16 %sum
177}
178
179define i8 @test_stack_args_zeroext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
180                                    i8 zeroext %p4, i16 zeroext %p5) {
181; CHECK-LABEL: name: test_stack_args_zeroext
182; CHECK: fixedStack:
183; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
184; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
185; CHECK: liveins: $r0, $r1, $r2, $r3
186; CHECK: [[VREGR2:%[0-9]+]]:_(s32) = COPY $r2
187; CHECK: [[VREGP2:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR2]]
188; CHECK: [[FIP4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
189; CHECK: [[VREGP4EXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP4]](p0){{.*}}load 4
190; CHECK: [[VREGP4:%[0-9]+]]:_(s8) = G_TRUNC [[VREGP4EXT]]
191; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGP2]], [[VREGP4]]
192; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
193; CHECK: $r0 = COPY [[SUM_EXT]](s32)
194; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
195entry:
196  %sum = add i8 %p2, %p4
197  ret i8 %sum
198}
199
200define i8 @test_stack_args_noext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
201                                 i8 %p4, i16 %p5) {
202; CHECK-LABEL: name: test_stack_args_noext
203; CHECK: fixedStack:
204; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
205; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
206; CHECK: liveins: $r0, $r1, $r2, $r3
207; CHECK: [[VREGR2:%[0-9]+]]:_(s32) = COPY $r2
208; CHECK: [[VREGP2:%[0-9]+]]:_(s8) = G_TRUNC [[VREGR2]]
209; CHECK: [[FIP4:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
210; CHECK: [[VREGP4:%[0-9]+]]:_(s8) = G_LOAD [[FIP4]](p0){{.*}}load 1
211; CHECK: [[SUM:%[0-9]+]]:_(s8) = G_ADD [[VREGP2]], [[VREGP4]]
212; CHECK: [[SUM_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SUM]]
213; CHECK: $r0 = COPY [[SUM_EXT]](s32)
214; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
215entry:
216  %sum = add i8 %p2, %p4
217  ret i8 %sum
218}
219
220define zeroext i16 @test_stack_args_extend_the_extended(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
221                                                        i8 signext %p4, i16 signext %p5) {
222; CHECK-LABEL: name: test_stack_args_extend_the_extended
223; CHECK: fixedStack:
224; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
225; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
226; CHECK: liveins: $r0, $r1, $r2, $r3
227; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
228; CHECK: [[VREGP5SEXT:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
229; CHECK: [[VREGP5:%[0-9]+]]:_(s16) = G_TRUNC [[VREGP5SEXT]]
230; CHECK: [[VREGP5ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[VREGP5]]
231; CHECK: $r0 = COPY [[VREGP5ZEXT]]
232; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
233entry:
234  ret i16 %p5
235}
236
237define i16 @test_ptr_arg(i16* %p) {
238; CHECK-LABEL: name: test_ptr_arg
239; CHECK: liveins: $r0
240; CHECK: [[VREGP:%[0-9]+]]:_(p0) = COPY $r0
241; CHECK: [[VREGV:%[0-9]+]]:_(s16) = G_LOAD [[VREGP]](p0){{.*}}load 2
242entry:
243  %v = load i16, i16* %p
244  ret i16 %v
245}
246
247define i32* @test_ptr_ret(i32** %p) {
248; Test pointer returns and pointer-to-pointer arguments
249; CHECK-LABEL: name: test_ptr_ret
250; CHECK: liveins: $r0
251; CHECK: [[VREGP:%[0-9]+]]:_(p0) = COPY $r0
252; CHECK: [[VREGV:%[0-9]+]]:_(p0) = G_LOAD [[VREGP]](p0){{.*}}load 4
253; CHECK: $r0 = COPY [[VREGV]]
254; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
255entry:
256  %v = load i32*, i32** %p
257  ret i32* %v
258}
259
260define i32 @test_ptr_arg_on_stack(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32* %p) {
261; CHECK-LABEL: name: test_ptr_arg_on_stack
262; CHECK: fixedStack:
263; CHECK: id: [[P:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
264; CHECK: liveins: $r0, $r1, $r2, $r3
265; CHECK: [[FIP:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P]]
266; CHECK: [[VREGP:%[0-9]+]]:_(p0) = G_LOAD [[FIP]](p0){{.*}}load 4
267; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_LOAD [[VREGP]](p0){{.*}}load 4
268; CHECK: $r0 = COPY [[VREGV]]
269; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
270entry:
271  %v = load i32, i32* %p
272  ret i32 %v
273}
274
275define arm_aapcscc float @test_float_aapcscc(float %p0, float %p1, float %p2,
276                                             float %p3, float %p4, float %p5) {
277; CHECK-LABEL: name: test_float_aapcscc
278; CHECK: fixedStack:
279; CHECK-DAG: id: [[P4:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
280; CHECK-DAG: id: [[P5:[0-9]+]]{{.*}}offset: 4{{.*}}size: 4
281; CHECK: liveins: $r0, $r1, $r2, $r3
282; CHECK: [[VREGP1:%[0-9]+]]:_(s32) = COPY $r1
283; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
284; CHECK: [[VREGP5:%[0-9]+]]:_(s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
285; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_FADD [[VREGP1]], [[VREGP5]]
286; CHECK: $r0 = COPY [[VREGV]]
287; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0
288entry:
289  %v = fadd float %p1, %p5
290  ret float %v
291}
292
293define arm_aapcs_vfpcc float @test_float_vfpcc(float %p0, float %p1, float %p2,
294                                               float %p3, float %p4, float %p5,
295                                               float %ridiculous,
296                                               float %number,
297                                               float %of,
298                                               float %parameters,
299                                               float %that,
300                                               float %should,
301                                               float %never,
302                                               float %exist,
303                                               float %in,
304                                               float %practice,
305                                               float %q0, float %q1) {
306; CHECK-LABEL: name: test_float_vfpcc
307; CHECK: fixedStack:
308; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 4
309; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 4{{.*}}size: 4
310; CHECK: liveins: $s0, $s1, $s2, $s3, $s4, $s5, $s6, $s7, $s8, $s9, $s10, $s11, $s12, $s13, $s14, $s15
311; CHECK: [[VREGP1:%[0-9]+]]:_(s32) = COPY $s1
312; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
313; CHECK: [[VREGQ1:%[0-9]+]]:_(s32) = G_LOAD [[FIQ1]](p0){{.*}}load 4
314; CHECK: [[VREGV:%[0-9]+]]:_(s32) = G_FADD [[VREGP1]], [[VREGQ1]]
315; CHECK: $s0 = COPY [[VREGV]]
316; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $s0
317entry:
318  %v = fadd float %p1, %q1
319  ret float %v
320}
321
322define arm_aapcs_vfpcc double @test_double_vfpcc(double %p0, double %p1, double %p2,
323                                                 double %p3, double %p4, double %p5,
324                                                 double %reasonable,
325                                                 double %parameters,
326                                                 double %q0, double %q1) {
327; CHECK-LABEL: name: test_double_vfpcc
328; CHECK: fixedStack:
329; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
330; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
331; CHECK: liveins: $d0, $d1, $d2, $d3, $d4, $d5, $d6, $d7
332; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = COPY $d1
333; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
334; CHECK: [[VREGQ1:%[0-9]+]]:_(s64) = G_LOAD [[FIQ1]](p0){{.*}}load 8
335; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGQ1]]
336; CHECK: $d0 = COPY [[VREGV]]
337; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $d0
338entry:
339  %v = fadd double %p1, %q1
340  ret double %v
341}
342
343define arm_aapcscc double @test_double_aapcscc(double %p0, double %p1, double %p2,
344                                               double %p3, double %p4, double %p5) {
345; CHECK-LABEL: name: test_double_aapcscc
346; CHECK: fixedStack:
347; CHECK-DAG: id: [[P2:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
348; CHECK-DAG: id: [[P3:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
349; CHECK-DAG: id: [[P4:[0-9]+]]{{.*}}offset: 16{{.*}}size: 8
350; CHECK-DAG: id: [[P5:[0-9]+]]{{.*}}offset: 24{{.*}}size: 8
351; CHECK: liveins: $r0, $r1, $r2, $r3
352; CHECK-DAG: [[VREGP1LO:%[0-9]+]]:_(s32) = COPY $r2
353; CHECK-DAG: [[VREGP1HI:%[0-9]+]]:_(s32) = COPY $r3
354; LITTLE: [[VREGP1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP1LO]](s32), [[VREGP1HI]](s32)
355; BIG: [[VREGP1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP1HI]](s32), [[VREGP1LO]](s32)
356; CHECK: [[FIP5:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
357; CHECK: [[VREGP5:%[0-9]+]]:_(s64) = G_LOAD [[FIP5]](p0){{.*}}load 8
358; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGP5]]
359; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
360; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
361; CHECK-DAG: $r0 = COPY [[VREGVLO]]
362; CHECK-DAG: $r1 = COPY [[VREGVHI]]
363; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
364entry:
365  %v = fadd double %p1, %p5
366  ret double %v
367}
368
369define arm_aapcs_vfpcc double @test_double_gap_vfpcc(double %p0, float %filler,
370                                                     double %p1, double %p2,
371                                                     double %p3, double %p4,
372                                                     double %reasonable,
373                                                     double %parameters,
374                                                     double %q0, double %q1) {
375; CHECK-LABEL: name: test_double_gap_vfpcc
376; CHECK: fixedStack:
377; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
378; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
379; CHECK: liveins: $d0, $d2, $d3, $d4, $d5, $d6, $d7, $s2
380; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = COPY $d2
381; CHECK: [[FIQ1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
382; CHECK: [[VREGQ1:%[0-9]+]]:_(s64) = G_LOAD [[FIQ1]](p0){{.*}}load 8
383; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP1]], [[VREGQ1]]
384; CHECK: $d0 = COPY [[VREGV]]
385; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $d0
386entry:
387  %v = fadd double %p1, %q1
388  ret double %v
389}
390
391define arm_aapcscc double @test_double_gap_aapcscc(float %filler, double %p0,
392                                                   double %p1) {
393; CHECK-LABEL: name: test_double_gap_aapcscc
394; CHECK: fixedStack:
395; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
396; CHECK: liveins: $r0, $r2, $r3
397; CHECK-DAG: [[VREGP0LO:%[0-9]+]]:_(s32) = COPY $r2
398; CHECK-DAG: [[VREGP0HI:%[0-9]+]]:_(s32) = COPY $r3
399; LITTLE: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0LO]](s32), [[VREGP0HI]](s32)
400; BIG: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0HI]](s32), [[VREGP0LO]](s32)
401; CHECK: [[FIP1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
402; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = G_LOAD [[FIP1]](p0){{.*}}load 8
403; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP0]], [[VREGP1]]
404; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
405; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
406; CHECK-DAG: $r0 = COPY [[VREGVLO]]
407; CHECK-DAG: $r1 = COPY [[VREGVHI]]
408; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
409entry:
410  %v = fadd double %p0, %p1
411  ret double %v
412}
413
414define arm_aapcscc double @test_double_gap2_aapcscc(double %p0, float %filler,
415                                                    double %p1) {
416; CHECK-LABEL: name: test_double_gap2_aapcscc
417; CHECK: fixedStack:
418; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
419; CHECK: liveins: $r0, $r1, $r2
420; CHECK-DAG: [[VREGP0LO:%[0-9]+]]:_(s32) = COPY $r0
421; CHECK-DAG: [[VREGP0HI:%[0-9]+]]:_(s32) = COPY $r1
422; LITTLE: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0LO]](s32), [[VREGP0HI]](s32)
423; BIG: [[VREGP0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[VREGP0HI]](s32), [[VREGP0LO]](s32)
424; CHECK: [[FIP1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
425; CHECK: [[VREGP1:%[0-9]+]]:_(s64) = G_LOAD [[FIP1]](p0){{.*}}load 8
426; CHECK: [[VREGV:%[0-9]+]]:_(s64) = G_FADD [[VREGP0]], [[VREGP1]]
427; LITTLE: [[VREGVLO:%[0-9]+]]:_(s32), [[VREGVHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
428; BIG: [[VREGVHI:%[0-9]+]]:_(s32), [[VREGVLO:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[VREGV]](s64)
429; CHECK-DAG: $r0 = COPY [[VREGVLO]]
430; CHECK-DAG: $r1 = COPY [[VREGVHI]]
431; CHECK: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1
432entry:
433  %v = fadd double %p0, %p1
434  ret double %v
435}
436
437define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
438; CHECK-LABEL: name: test_shufflevector_s32_v2s32
439; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
440; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
441; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
442; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
443  %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
444  %shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
445  %res = extractelement <2 x i32> %shuffle, i32 0
446  ret i32 %res
447}
448
449define i32 @test_shufflevector_s32_s32_s32(i32 %arg) {
450; CHECK-LABEL: name: test_shufflevector_s32_s32_s32
451; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
452; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
453; CHECK: [[VEC:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0)
454  %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
455  %shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <1 x i32> zeroinitializer
456  %res = extractelement <1 x i32> %shuffle, i32 0
457  ret i32 %res
458}
459
460define i32 @test_shufflevector_v2s32_v3s32(i32 %arg1, i32 %arg2) {
461; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
462; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
463; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
464; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
465; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
466; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
467; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
468; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
469; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
470; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
471  %v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
472  %v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
473  %shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
474  %res = extractelement <3 x i32> %shuffle, i32 0
475  ret i32 %res
476}
477
478
479define i32 @test_shufflevector_v2s32_v4s32(i32 %arg1, i32 %arg2) {
480; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
481; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
482; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
483; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
484; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
485; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
486; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
487; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
488; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(0, 0, 0, 0)
489; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<4 x s32>)
490  %v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
491  %v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
492  %shuffle = shufflevector <2 x i32> %v2, <2 x i32> undef, <4 x i32> zeroinitializer
493  %res = extractelement <4 x i32> %shuffle, i32 0
494  ret i32 %res
495}
496
497define i32 @test_shufflevector_v4s32_v2s32(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) {
498; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
499; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $r0
500; CHECK: [[ARG2:%[0-9]+]]:_(s32) = COPY $r1
501; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $r2
502; CHECK: [[ARG4:%[0-9]+]]:_(s32) = COPY $r3
503; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
504; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
505; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
506; CHECK-DAG: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
507; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
508; CHECK-DAG: [[V1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
509; CHECK-DAG: [[V2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
510; CHECK-DAG: [[V3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V2]], [[ARG3]](s32), [[C2]](s32)
511; CHECK-DAG: [[V4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V3]], [[ARG4]](s32), [[C3]](s32)
512; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[V4]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
513; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
514  %v1 = insertelement <4 x i32> undef, i32 %arg1, i32 0
515  %v2 = insertelement <4 x i32> %v1, i32 %arg2, i32 1
516  %v3 = insertelement <4 x i32> %v2, i32 %arg3, i32 2
517  %v4 = insertelement <4 x i32> %v3, i32 %arg4, i32 3
518  %shuffle = shufflevector <4 x i32> %v4, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
519  %res = extractelement <2 x i32> %shuffle, i32 0
520  ret i32 %res
521}
522
523%struct.v2s32 = type { <2 x i32> }
524
525define i32 @test_constantstruct_v2s32() {
526; CHECK-LABEL: name: test_constantstruct_v2s32
527; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
528; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
529; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
530; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
531; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[C3]]
532  %vec = extractvalue %struct.v2s32 {<2 x i32><i32 1, i32 2>}, 0
533  %elt = extractelement <2 x i32> %vec, i32 0
534  ret i32 %elt
535}
536
537%struct.v2s32.s32.s32 = type { <2 x i32>, i32, i32 }
538
539define i32 @test_constantstruct_v2s32_s32_s32() {
540; CHECK-LABEL: name: test_constantstruct_v2s32_s32_s32
541; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
542; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
543; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
544; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
545; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
546; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
547; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[C5]](s32)
548  %vec = extractvalue %struct.v2s32.s32.s32 {<2 x i32><i32 1, i32 2>, i32 3, i32 4}, 0
549  %elt = extractelement <2 x i32> %vec, i32 0
550  ret i32 %elt
551}
552
553define void @test_load_store_struct({i32, i32} *%addr) {
554; Make sure the IRTranslator doesn't use an unnecessarily large GEP index type
555; when breaking up loads and stores of aggregates.
556; CHECK-LABEL: name: test_load_store_struct
557; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
558; CHECK-DAG: [[VAL1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4 from %ir.addr)
559; CHECK-DAG: [[OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
560; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR1]], [[OFFSET]](s32)
561; CHECK-DAG: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4 from %ir.addr + 4)
562; CHECK-DAG: G_STORE [[VAL1]](s32), [[ADDR1]](p0) :: (store 4 into %ir.addr)
563; CHECK-DAG: [[ADDR3:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
564; CHECK-DAG: G_STORE [[VAL2]](s32), [[ADDR3]](p0) :: (store 4 into %ir.addr + 4)
565  %val = load {i32, i32}, {i32, i32} *%addr, align 4
566  store {i32, i32} %val, {i32, i32} *%addr, align 4
567  ret void
568}
569