xref: /llvm-project/llvm/test/CodeGen/ARM/struct_byval.ll (revision a2088a24dad31ebe44c93751db17307fdbe1f0e2)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2; RUN: llc < %s -mtriple=armv7-apple-ios6.0 | FileCheck %s
3; RUN: llc < %s -mtriple=thumbv7-apple-ios6.0 | FileCheck %s
4; RUN: llc < %s -mtriple=armv7-unknown-nacl-gnueabi | FileCheck %s -check-prefix=NACL
5; RUN: llc < %s -mtriple=armv5-none-linux-gnueabi | FileCheck %s -check-prefix=NOMOVT
6
7; NOMOVT-NOT: movt
8
9; rdar://9877866
10%struct.SmallStruct = type { i32, [8 x i32], [37 x i8] }
11%struct.LargeStruct = type { i32, [1001 x i8], [300 x i32] }
12
13define i32 @f() nounwind ssp {
14; NACL-LABEL: f:
15; NACL:       @ %bb.0: @ %entry
16; NACL-NEXT:    .save {r4, lr}
17; NACL-NEXT:    push {r4, lr}
18; NACL-NEXT:    .pad #152
19; NACL-NEXT:    sub sp, sp, #152
20; NACL-NEXT:    movw r0, :lower16:__stack_chk_guard
21; NACL-NEXT:    add r3, sp, #72
22; NACL-NEXT:    movt r0, :upper16:__stack_chk_guard
23; NACL-NEXT:    mov lr, sp
24; NACL-NEXT:    ldr r0, [r0]
25; NACL-NEXT:    str r0, [sp, #148]
26; NACL-NEXT:    add r0, sp, #72
27; NACL-NEXT:    add r12, r0, #16
28; NACL-NEXT:    ldm r3, {r0, r1, r2, r3}
29; NACL-NEXT:    ldr r4, [r12], #4
30; NACL-NEXT:    str r4, [lr], #4
31; NACL-NEXT:    ldr r4, [r12], #4
32; NACL-NEXT:    str r4, [lr], #4
33; NACL-NEXT:    ldr r4, [r12], #4
34; NACL-NEXT:    str r4, [lr], #4
35; NACL-NEXT:    ldr r4, [r12], #4
36; NACL-NEXT:    str r4, [lr], #4
37; NACL-NEXT:    ldr r4, [r12], #4
38; NACL-NEXT:    str r4, [lr], #4
39; NACL-NEXT:    ldr r4, [r12], #4
40; NACL-NEXT:    str r4, [lr], #4
41; NACL-NEXT:    ldr r4, [r12], #4
42; NACL-NEXT:    str r4, [lr], #4
43; NACL-NEXT:    ldr r4, [r12], #4
44; NACL-NEXT:    str r4, [lr], #4
45; NACL-NEXT:    ldr r4, [r12], #4
46; NACL-NEXT:    str r4, [lr], #4
47; NACL-NEXT:    ldr r4, [r12], #4
48; NACL-NEXT:    str r4, [lr], #4
49; NACL-NEXT:    ldr r4, [r12], #4
50; NACL-NEXT:    str r4, [lr], #4
51; NACL-NEXT:    ldr r4, [r12], #4
52; NACL-NEXT:    str r4, [lr], #4
53; NACL-NEXT:    ldr r4, [r12], #4
54; NACL-NEXT:    str r4, [lr], #4
55; NACL-NEXT:    ldr r4, [r12], #4
56; NACL-NEXT:    str r4, [lr], #4
57; NACL-NEXT:    ldr r4, [r12], #4
58; NACL-NEXT:    str r4, [lr], #4
59; NACL-NEXT:    bl e1
60; NACL-NEXT:    movw r1, :lower16:__stack_chk_guard
61; NACL-NEXT:    ldr r0, [sp, #148]
62; NACL-NEXT:    movt r1, :upper16:__stack_chk_guard
63; NACL-NEXT:    ldr r1, [r1]
64; NACL-NEXT:    cmp r1, r0
65; NACL-NEXT:    moveq r0, #0
66; NACL-NEXT:    addeq sp, sp, #152
67; NACL-NEXT:    popeq {r4, pc}
68; NACL-NEXT:  .LBB0_1: @ %entry
69; NACL-NEXT:    bl __stack_chk_fail
70;
71; NOMOVT-LABEL: f:
72; NOMOVT:       @ %bb.0: @ %entry
73; NOMOVT-NEXT:    .save {r11, lr}
74; NOMOVT-NEXT:    push {r11, lr}
75; NOMOVT-NEXT:    .pad #144
76; NOMOVT-NEXT:    sub sp, sp, #144
77; NOMOVT-NEXT:    ldr r0, .LCPI0_0
78; NOMOVT-NEXT:    mov r1, sp
79; NOMOVT-NEXT:    add r3, sp, #64
80; NOMOVT-NEXT:    ldr r0, [r0]
81; NOMOVT-NEXT:    str r0, [sp, #140]
82; NOMOVT-NEXT:    add r0, sp, #64
83; NOMOVT-NEXT:    add r0, r0, #16
84; NOMOVT-NEXT:    ldr r2, [r0], #4
85; NOMOVT-NEXT:    str r2, [r1], #4
86; NOMOVT-NEXT:    ldr r2, [r0], #4
87; NOMOVT-NEXT:    str r2, [r1], #4
88; NOMOVT-NEXT:    ldr r2, [r0], #4
89; NOMOVT-NEXT:    str r2, [r1], #4
90; NOMOVT-NEXT:    ldr r2, [r0], #4
91; NOMOVT-NEXT:    str r2, [r1], #4
92; NOMOVT-NEXT:    ldr r2, [r0], #4
93; NOMOVT-NEXT:    str r2, [r1], #4
94; NOMOVT-NEXT:    ldr r2, [r0], #4
95; NOMOVT-NEXT:    str r2, [r1], #4
96; NOMOVT-NEXT:    ldr r2, [r0], #4
97; NOMOVT-NEXT:    str r2, [r1], #4
98; NOMOVT-NEXT:    ldr r2, [r0], #4
99; NOMOVT-NEXT:    str r2, [r1], #4
100; NOMOVT-NEXT:    ldr r2, [r0], #4
101; NOMOVT-NEXT:    str r2, [r1], #4
102; NOMOVT-NEXT:    ldr r2, [r0], #4
103; NOMOVT-NEXT:    str r2, [r1], #4
104; NOMOVT-NEXT:    ldr r2, [r0], #4
105; NOMOVT-NEXT:    str r2, [r1], #4
106; NOMOVT-NEXT:    ldr r2, [r0], #4
107; NOMOVT-NEXT:    str r2, [r1], #4
108; NOMOVT-NEXT:    ldr r2, [r0], #4
109; NOMOVT-NEXT:    str r2, [r1], #4
110; NOMOVT-NEXT:    ldr r2, [r0], #4
111; NOMOVT-NEXT:    str r2, [r1], #4
112; NOMOVT-NEXT:    ldr r2, [r0], #4
113; NOMOVT-NEXT:    str r2, [r1], #4
114; NOMOVT-NEXT:    ldm r3, {r0, r1, r2, r3}
115; NOMOVT-NEXT:    bl e1
116; NOMOVT-NEXT:    ldr r0, [sp, #140]
117; NOMOVT-NEXT:    ldr r1, .LCPI0_0
118; NOMOVT-NEXT:    ldr r1, [r1]
119; NOMOVT-NEXT:    cmp r1, r0
120; NOMOVT-NEXT:    moveq r0, #0
121; NOMOVT-NEXT:    addeq sp, sp, #144
122; NOMOVT-NEXT:    popeq {r11, pc}
123; NOMOVT-NEXT:  .LBB0_1: @ %entry
124; NOMOVT-NEXT:    bl __stack_chk_fail
125; NOMOVT-NEXT:    .p2align 2
126; NOMOVT-NEXT:  @ %bb.2:
127; NOMOVT-NEXT:  .LCPI0_0:
128; NOMOVT-NEXT:    .long __stack_chk_guard
129entry:
130  %st = alloca %struct.SmallStruct, align 4
131  %call = call i32 @e1(ptr byval(%struct.SmallStruct) %st)
132  ret i32 0
133}
134
135; Generate a loop for large struct byval
136define i32 @g() nounwind ssp {
137; NACL-LABEL: g:
138; NACL:       @ %bb.0: @ %entry
139; NACL-NEXT:    .save {r4, r5, r11, lr}
140; NACL-NEXT:    push {r4, r5, r11, lr}
141; NACL-NEXT:    .pad #2224
142; NACL-NEXT:    sub sp, sp, #2224
143; NACL-NEXT:    movw r0, :lower16:__stack_chk_guard
144; NACL-NEXT:    movt r0, :upper16:__stack_chk_guard
145; NACL-NEXT:    ldr r0, [r0]
146; NACL-NEXT:    str r0, [sp, #2220]
147; NACL-NEXT:    sub sp, sp, #2192
148; NACL-NEXT:    add lr, sp, #2048
149; NACL-NEXT:    ldr r1, [sp, #2208]
150; NACL-NEXT:    add r0, lr, #156
151; NACL-NEXT:    ldr r2, [sp, #2212]
152; NACL-NEXT:    add r12, r0, #16
153; NACL-NEXT:    ldr r0, [sp, #2204]
154; NACL-NEXT:    ldr r3, [sp, #2216]
155; NACL-NEXT:    movw lr, #2192
156; NACL-NEXT:    mov r4, sp
157; NACL-NEXT:  .LBB1_1: @ %entry
158; NACL-NEXT:    @ =>This Inner Loop Header: Depth=1
159; NACL-NEXT:    ldr r5, [r12], #4
160; NACL-NEXT:    subs lr, lr, #4
161; NACL-NEXT:    str r5, [r4], #4
162; NACL-NEXT:    bne .LBB1_1
163; NACL-NEXT:  @ %bb.2: @ %entry
164; NACL-NEXT:    bl e2
165; NACL-NEXT:    add sp, sp, #2192
166; NACL-NEXT:    movw r1, :lower16:__stack_chk_guard
167; NACL-NEXT:    ldr r0, [sp, #2220]
168; NACL-NEXT:    movt r1, :upper16:__stack_chk_guard
169; NACL-NEXT:    ldr r1, [r1]
170; NACL-NEXT:    cmp r1, r0
171; NACL-NEXT:    moveq r0, #0
172; NACL-NEXT:    addeq sp, sp, #2224
173; NACL-NEXT:    popeq {r4, r5, r11, pc}
174; NACL-NEXT:  .LBB1_3: @ %entry
175; NACL-NEXT:    bl __stack_chk_fail
176;
177; NOMOVT-LABEL: g:
178; NOMOVT:       @ %bb.0: @ %entry
179; NOMOVT-NEXT:    .save {r11, lr}
180; NOMOVT-NEXT:    push {r11, lr}
181; NOMOVT-NEXT:    .pad #168
182; NOMOVT-NEXT:    sub sp, sp, #168
183; NOMOVT-NEXT:    .pad #2048
184; NOMOVT-NEXT:    sub sp, sp, #2048
185; NOMOVT-NEXT:    ldr r0, .LCPI1_1
186; NOMOVT-NEXT:    ldr r0, [r0]
187; NOMOVT-NEXT:    str r0, [sp, #2212]
188; NOMOVT-NEXT:    sub sp, sp, #2192
189; NOMOVT-NEXT:    add lr, sp, #2048
190; NOMOVT-NEXT:    ldr r1, .LCPI1_0
191; NOMOVT-NEXT:    add r0, lr, #148
192; NOMOVT-NEXT:    mov r2, sp
193; NOMOVT-NEXT:    add r0, r0, #16
194; NOMOVT-NEXT:  .LBB1_1: @ %entry
195; NOMOVT-NEXT:    @ =>This Inner Loop Header: Depth=1
196; NOMOVT-NEXT:    ldr r3, [r0], #4
197; NOMOVT-NEXT:    subs r1, r1, #4
198; NOMOVT-NEXT:    str r3, [r2], #4
199; NOMOVT-NEXT:    bne .LBB1_1
200; NOMOVT-NEXT:  @ %bb.2: @ %entry
201; NOMOVT-NEXT:    ldr r0, [sp, #2196]
202; NOMOVT-NEXT:    ldr r1, [sp, #2200]
203; NOMOVT-NEXT:    ldr r2, [sp, #2204]
204; NOMOVT-NEXT:    ldr r3, [sp, #2208]
205; NOMOVT-NEXT:    bl e2
206; NOMOVT-NEXT:    add sp, sp, #2192
207; NOMOVT-NEXT:    ldr r0, [sp, #2212]
208; NOMOVT-NEXT:    ldr r1, .LCPI1_1
209; NOMOVT-NEXT:    ldr r1, [r1]
210; NOMOVT-NEXT:    cmp r1, r0
211; NOMOVT-NEXT:    moveq r0, #0
212; NOMOVT-NEXT:    addeq sp, sp, #168
213; NOMOVT-NEXT:    addeq sp, sp, #2048
214; NOMOVT-NEXT:    popeq {r11, pc}
215; NOMOVT-NEXT:  .LBB1_3: @ %entry
216; NOMOVT-NEXT:    bl __stack_chk_fail
217; NOMOVT-NEXT:    .p2align 2
218; NOMOVT-NEXT:  @ %bb.4:
219; NOMOVT-NEXT:  .LCPI1_0:
220; NOMOVT-NEXT:    .long 2192 @ 0x890
221; NOMOVT-NEXT:  .LCPI1_1:
222; NOMOVT-NEXT:    .long __stack_chk_guard
223entry:
224; Ensure that use movw instead of constpool for the loop trip count. But don't
225; match the __stack_chk_guard movw
226  %st = alloca %struct.LargeStruct, align 4
227  %call = call i32 @e2(ptr byval(%struct.LargeStruct) %st)
228  ret i32 0
229}
230
231; Generate a loop using NEON instructions
232define i32 @h() nounwind ssp {
233; NACL-LABEL: h:
234; NACL:       @ %bb.0: @ %entry
235; NACL-NEXT:    .save {r4, r5, r6, r7, r8, lr}
236; NACL-NEXT:    push {r4, r5, r6, r7, r8, lr}
237; NACL-NEXT:    .pad #168
238; NACL-NEXT:    sub sp, sp, #168
239; NACL-NEXT:    .pad #2048
240; NACL-NEXT:    sub sp, sp, #2048
241; NACL-NEXT:    movw r0, :lower16:__stack_chk_guard
242; NACL-NEXT:    movt r0, :upper16:__stack_chk_guard
243; NACL-NEXT:    ldr r0, [r0]
244; NACL-NEXT:    str r0, [sp, #2212]
245; NACL-NEXT:    sub sp, sp, #2192
246; NACL-NEXT:    add r3, sp, #2192
247; NACL-NEXT:    add r0, sp, #2192
248; NACL-NEXT:    add r12, r0, #16
249; NACL-NEXT:    movw lr, #2192
250; NACL-NEXT:    ldm r3, {r0, r1, r2, r3}
251; NACL-NEXT:    mov r4, sp
252; NACL-NEXT:  .LBB2_1: @ %entry
253; NACL-NEXT:    @ =>This Inner Loop Header: Depth=1
254; NACL-NEXT:    vld1.32 {d16, d17}, [r12]!
255; NACL-NEXT:    subs lr, lr, #16
256; NACL-NEXT:    vst1.32 {d16, d17}, [r4]!
257; NACL-NEXT:    bne .LBB2_1
258; NACL-NEXT:  @ %bb.2: @ %entry
259; NACL-NEXT:    bl e3
260; NACL-NEXT:    add sp, sp, #2192
261; NACL-NEXT:    movw r1, :lower16:__stack_chk_guard
262; NACL-NEXT:    ldr r0, [sp, #2212]
263; NACL-NEXT:    movt r1, :upper16:__stack_chk_guard
264; NACL-NEXT:    ldr r1, [r1]
265; NACL-NEXT:    cmp r1, r0
266; NACL-NEXT:    moveq r0, #0
267; NACL-NEXT:    addeq sp, sp, #168
268; NACL-NEXT:    addeq sp, sp, #2048
269; NACL-NEXT:    popeq {r4, r5, r6, r7, r8, pc}
270; NACL-NEXT:  .LBB2_3: @ %entry
271; NACL-NEXT:    bl __stack_chk_fail
272;
273; NOMOVT-LABEL: h:
274; NOMOVT:       @ %bb.0: @ %entry
275; NOMOVT-NEXT:    .save {r6, r10, r11, lr}
276; NOMOVT-NEXT:    push {r6, r10, r11, lr}
277; NOMOVT-NEXT:    .setfp r11, sp, #8
278; NOMOVT-NEXT:    add r11, sp, #8
279; NOMOVT-NEXT:    .pad #2224
280; NOMOVT-NEXT:    sub sp, sp, #2224
281; NOMOVT-NEXT:    bic sp, sp, #15
282; NOMOVT-NEXT:    ldr r0, .LCPI2_1
283; NOMOVT-NEXT:    mov r6, sp
284; NOMOVT-NEXT:    ldr r0, [r0]
285; NOMOVT-NEXT:    str r0, [r6, #2220]
286; NOMOVT-NEXT:    sub sp, sp, #2192
287; NOMOVT-NEXT:    mov r0, r6
288; NOMOVT-NEXT:    ldr r1, .LCPI2_0
289; NOMOVT-NEXT:    add r0, r0, #16
290; NOMOVT-NEXT:    mov r2, sp
291; NOMOVT-NEXT:  .LBB2_1: @ %entry
292; NOMOVT-NEXT:    @ =>This Inner Loop Header: Depth=1
293; NOMOVT-NEXT:    ldr r3, [r0], #4
294; NOMOVT-NEXT:    subs r1, r1, #4
295; NOMOVT-NEXT:    str r3, [r2], #4
296; NOMOVT-NEXT:    bne .LBB2_1
297; NOMOVT-NEXT:  @ %bb.2: @ %entry
298; NOMOVT-NEXT:    ldm r6, {r0, r1, r2, r3}
299; NOMOVT-NEXT:    bl e3
300; NOMOVT-NEXT:    add sp, sp, #2192
301; NOMOVT-NEXT:    ldr r0, [r6, #2220]
302; NOMOVT-NEXT:    ldr r1, .LCPI2_1
303; NOMOVT-NEXT:    ldr r1, [r1]
304; NOMOVT-NEXT:    cmp r1, r0
305; NOMOVT-NEXT:    moveq r0, #0
306; NOMOVT-NEXT:    subeq sp, r11, #8
307; NOMOVT-NEXT:    popeq {r6, r10, r11, pc}
308; NOMOVT-NEXT:  .LBB2_3: @ %entry
309; NOMOVT-NEXT:    bl __stack_chk_fail
310; NOMOVT-NEXT:    .p2align 2
311; NOMOVT-NEXT:  @ %bb.4:
312; NOMOVT-NEXT:  .LCPI2_0:
313; NOMOVT-NEXT:    .long 2192 @ 0x890
314; NOMOVT-NEXT:  .LCPI2_1:
315; NOMOVT-NEXT:    .long __stack_chk_guard
316entry:
317  %st = alloca %struct.LargeStruct, align 16
318  %call = call i32 @e3(ptr byval(%struct.LargeStruct) align 16 %st)
319  ret i32 0
320}
321
322declare i32 @e1(ptr nocapture byval(%struct.SmallStruct) %in) nounwind
323declare i32 @e2(ptr nocapture byval(%struct.LargeStruct) %in) nounwind
324declare i32 @e3(ptr nocapture byval(%struct.LargeStruct) align 16 %in) nounwind
325
326; rdar://12442472
327; We can't do tail call since address of s is passed to the callee and part of
328; s is in caller's local frame.
329define void @f3(ptr nocapture byval(%struct.SmallStruct) %s) nounwind optsize {
330; NACL-LABEL: f3:
331; NACL:       @ %bb.0: @ %entry
332; NACL-NEXT:    .pad #16
333; NACL-NEXT:    sub sp, sp, #16
334; NACL-NEXT:    stm sp, {r0, r1, r2, r3}
335; NACL-NEXT:    mov r0, sp
336; NACL-NEXT:    mov r1, #80
337; NACL-NEXT:    add sp, sp, #16
338; NACL-NEXT:    b consumestruct
339;
340; NOMOVT-LABEL: f3:
341; NOMOVT:       @ %bb.0: @ %entry
342; NOMOVT-NEXT:    .pad #16
343; NOMOVT-NEXT:    sub sp, sp, #16
344; NOMOVT-NEXT:    stm sp, {r0, r1, r2, r3}
345; NOMOVT-NEXT:    mov r0, sp
346; NOMOVT-NEXT:    mov r1, #80
347; NOMOVT-NEXT:    add sp, sp, #16
348; NOMOVT-NEXT:    b consumestruct
349entry:
350  tail call void @consumestruct(ptr %s, i32 80) optsize
351  ret void
352}
353
354define void @f4(ptr nocapture byval(%struct.SmallStruct) %s) nounwind optsize {
355; NACL-LABEL: f4:
356; NACL:       @ %bb.0: @ %entry
357; NACL-NEXT:    .pad #16
358; NACL-NEXT:    sub sp, sp, #16
359; NACL-NEXT:    stm sp, {r0, r1, r2, r3}
360; NACL-NEXT:    mov r0, sp
361; NACL-NEXT:    mov r1, #80
362; NACL-NEXT:    add sp, sp, #16
363; NACL-NEXT:    b consumestruct
364;
365; NOMOVT-LABEL: f4:
366; NOMOVT:       @ %bb.0: @ %entry
367; NOMOVT-NEXT:    .pad #16
368; NOMOVT-NEXT:    sub sp, sp, #16
369; NOMOVT-NEXT:    stm sp, {r0, r1, r2, r3}
370; NOMOVT-NEXT:    mov r0, sp
371; NOMOVT-NEXT:    mov r1, #80
372; NOMOVT-NEXT:    add sp, sp, #16
373; NOMOVT-NEXT:    b consumestruct
374entry:
375  tail call void @consumestruct(ptr %s, i32 80) optsize
376  ret void
377}
378
379; We can do tail call here since s is in the incoming argument area.
380define void @f5(i32 %a, i32 %b, i32 %c, i32 %d, ptr nocapture byval(%struct.SmallStruct) %s) nounwind optsize {
381; NACL-LABEL: f5:
382; NACL:       @ %bb.0: @ %entry
383; NACL-NEXT:    mov r0, sp
384; NACL-NEXT:    mov r1, #80
385; NACL-NEXT:    b consumestruct
386;
387; NOMOVT-LABEL: f5:
388; NOMOVT:       @ %bb.0: @ %entry
389; NOMOVT-NEXT:    mov r0, sp
390; NOMOVT-NEXT:    mov r1, #80
391; NOMOVT-NEXT:    b consumestruct
392entry:
393  tail call void @consumestruct(ptr %s, i32 80) optsize
394  ret void
395}
396
397define void @f6(i32 %a, i32 %b, i32 %c, i32 %d, ptr nocapture byval(%struct.SmallStruct) %s) nounwind optsize {
398; NACL-LABEL: f6:
399; NACL:       @ %bb.0: @ %entry
400; NACL-NEXT:    mov r0, sp
401; NACL-NEXT:    mov r1, #80
402; NACL-NEXT:    b consumestruct
403;
404; NOMOVT-LABEL: f6:
405; NOMOVT:       @ %bb.0: @ %entry
406; NOMOVT-NEXT:    mov r0, sp
407; NOMOVT-NEXT:    mov r1, #80
408; NOMOVT-NEXT:    b consumestruct
409entry:
410  tail call void @consumestruct(ptr %s, i32 80) optsize
411  ret void
412}
413
414declare void @consumestruct(ptr nocapture %structp, i32 %structsize) nounwind
415
416; PR17309
417%struct.I.8 = type { [10 x i32], [3 x i8] }
418
419declare void @use_I(ptr byval(%struct.I.8))
420define void @test_I_16() {
421; NACL-LABEL: test_I_16:
422; NACL:       @ %bb.0: @ %entry
423; NACL-NEXT:    .save {r11, lr}
424; NACL-NEXT:    push {r11, lr}
425; NACL-NEXT:    .pad #40
426; NACL-NEXT:    sub sp, sp, #40
427; NACL-NEXT:    ldr r0, [r0]
428; NACL-NEXT:    mov r1, sp
429; NACL-NEXT:    vld1.32 {d16, d17}, [r2]!
430; NACL-NEXT:    vst1.32 {d16, d17}, [r1]!
431; NACL-NEXT:    ldrb r3, [r2], #1
432; NACL-NEXT:    strb r3, [r1], #1
433; NACL-NEXT:    ldrb r3, [r2], #1
434; NACL-NEXT:    strb r3, [r1], #1
435; NACL-NEXT:    ldrb r3, [r2], #1
436; NACL-NEXT:    strb r3, [r1], #1
437; NACL-NEXT:    ldrb r3, [r2], #1
438; NACL-NEXT:    strb r3, [r1], #1
439; NACL-NEXT:    ldrb r3, [r2], #1
440; NACL-NEXT:    strb r3, [r1], #1
441; NACL-NEXT:    ldrb r3, [r2], #1
442; NACL-NEXT:    strb r3, [r1], #1
443; NACL-NEXT:    ldrb r3, [r2], #1
444; NACL-NEXT:    strb r3, [r1], #1
445; NACL-NEXT:    ldrb r3, [r2], #1
446; NACL-NEXT:    strb r3, [r1], #1
447; NACL-NEXT:    ldrb r3, [r2], #1
448; NACL-NEXT:    strb r3, [r1], #1
449; NACL-NEXT:    ldrb r3, [r2], #1
450; NACL-NEXT:    strb r3, [r1], #1
451; NACL-NEXT:    ldrb r3, [r2], #1
452; NACL-NEXT:    strb r3, [r1], #1
453; NACL-NEXT:    ldrb r3, [r2], #1
454; NACL-NEXT:    strb r3, [r1], #1
455; NACL-NEXT:    mov r2, r0
456; NACL-NEXT:    mov r1, r0
457; NACL-NEXT:    mov r3, r0
458; NACL-NEXT:    bl use_I
459; NACL-NEXT:    add sp, sp, #40
460; NACL-NEXT:    pop {r11, pc}
461;
462; NOMOVT-LABEL: test_I_16:
463; NOMOVT:       @ %bb.0: @ %entry
464; NOMOVT-NEXT:    .save {r11, lr}
465; NOMOVT-NEXT:    push {r11, lr}
466; NOMOVT-NEXT:    .setfp r11, sp
467; NOMOVT-NEXT:    mov r11, sp
468; NOMOVT-NEXT:    .pad #40
469; NOMOVT-NEXT:    sub sp, sp, #40
470; NOMOVT-NEXT:    bic sp, sp, #15
471; NOMOVT-NEXT:    ldr r0, [r1], #4
472; NOMOVT-NEXT:    mov r2, sp
473; NOMOVT-NEXT:    str r0, [r2], #4
474; NOMOVT-NEXT:    ldr r0, [r1], #4
475; NOMOVT-NEXT:    str r0, [r2], #4
476; NOMOVT-NEXT:    ldr r0, [r1], #4
477; NOMOVT-NEXT:    str r0, [r2], #4
478; NOMOVT-NEXT:    ldr r0, [r1], #4
479; NOMOVT-NEXT:    str r0, [r2], #4
480; NOMOVT-NEXT:    ldr r0, [r1], #4
481; NOMOVT-NEXT:    str r0, [r2], #4
482; NOMOVT-NEXT:    ldr r0, [r1], #4
483; NOMOVT-NEXT:    str r0, [r2], #4
484; NOMOVT-NEXT:    ldr r0, [r1], #4
485; NOMOVT-NEXT:    str r0, [r2], #4
486; NOMOVT-NEXT:    ldr r0, [r0]
487; NOMOVT-NEXT:    mov r1, r0
488; NOMOVT-NEXT:    mov r2, r0
489; NOMOVT-NEXT:    mov r3, r0
490; NOMOVT-NEXT:    bl use_I
491; NOMOVT-NEXT:    mov sp, r11
492; NOMOVT-NEXT:    pop {r11, pc}
493entry:
494  call void @use_I(ptr byval(%struct.I.8) align 16 undef)
495  ret void
496}
497;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
498; CHECK: {{.*}}
499