1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2; RUN: opt < %s  -cost-model -analyze -cost-kind=code-size | \
3; RUN:    FileCheck %s --check-prefixes=COMMON,CHECK-NO-SA
4; RUN: opt < %s  -cost-model -analyze -cost-kind=code-size -mattr=+strict-align | \
5; RUN:    FileCheck %s --check-prefixes=COMMON,CHECK-SA
6
7target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
8target triple = "thumbv7m-arm-unknown-eabi"
9
10;;;;;;;;;;;;
11; Align 1, 1
12;;;;;;;;;;;;
13
14define void @memcpy_1(i8* %d, i8* %s) {
15;
16; with/without strict-align:
17;
18; ldrb r1, [r1]
19; strb r1, [r0]
20;
21; COMMON-LABEL: 'memcpy_1'
22; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 1, i1 false)
23; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
24;
25entry:
26  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 1, i1 false)
27  ret void
28}
29
30define void @memcpy_2(i8* %d, i8* %s) {
31;
32; no strict-align:
33;
34; ldrh	r1, [r1]
35; strh	r1, [r0]
36;
37; strict-align:
38;
39; ldrb  r2, [r1]
40; ldrb  r1, [r1, #1]
41; strb  r1, [r0, #1]
42; strb  r2, [r0]
43;
44; CHECK-NO-SA-LABEL: 'memcpy_2'
45; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 2, i1 false)
46; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
47;
48; CHECK-SA-LABEL: 'memcpy_2'
49; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 2, i1 false)
50; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
51;
52entry:
53  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 2, i1 false)
54  ret void
55}
56
57define void @memcpy_3(i8* %d, i8* %s) {
58;
59; no strict-align:
60;
61; ldrb	r2, [r1, #2]
62; strb	r2, [r0, #2]
63; ldrh	r1, [r1]
64; strh	r1, [r0]
65;
66; strict-align:
67;
68; ldrb  r2, [r1]
69; ldrb  r3, [r1, #1]
70; ldrb  r1, [r1, #2]
71; strb  r1, [r0, #2]
72; strb  r3, [r0, #1]
73; strb  r2, [r0]
74;
75; CHECK-NO-SA-LABEL: 'memcpy_3'
76; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 3, i1 false)
77; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
78;
79; CHECK-SA-LABEL: 'memcpy_3'
80; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 3, i1 false)
81; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
82;
83entry:
84  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 3, i1 false)
85  ret void
86}
87
88define void @memcpy_4(i8* %d, i8* %s) {
89;
90; no strict-align:
91;
92; ldr	r1, [r1]
93; str	r1, [r0]
94;
95; strict-align:
96;
97; ldrb.w  r12, [r1]
98; ldrb  r3, [r1, #1]
99; ldrb  r2, [r1, #2]
100; ldrb  r1, [r1, #3]
101; strb  r1, [r0, #3]
102; strb  r2, [r0, #2]
103; strb  r3, [r0, #1]
104; strb.w  r12, [r0]
105;
106; CHECK-NO-SA-LABEL: 'memcpy_4'
107; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 4, i1 false)
108; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
109;
110; CHECK-SA-LABEL: 'memcpy_4'
111; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 4, i1 false)
112; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
113;
114entry:
115  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 4, i1 false)
116  ret void
117}
118
119define void @memcpy_8(i8* %d, i8* %s) {
120;
121; no strict-align:
122;
123; ldr	r2, [r1]
124; ldr	r1, [r1, #4]
125; str	r1, [r0, #4]
126; str	r2, [r0]
127;
128; strict-align:
129;
130; push  {r7, lr}
131; movs  r2, #8
132; bl  __aeabi_memcpy
133; pop {r7, pc}
134;
135; COMMON-LABEL: 'memcpy_8'
136; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 8, i1 false)
137; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
138;
139entry:
140  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 8, i1 false)
141  ret void
142}
143
144define void @memcpy_16(i8* %d, i8* %s) {
145;
146; no strict-align:
147;
148; ldr.w	r12, [r1]
149; ldr	r3, [r1, #4]
150; ldr	r2, [r1, #8]
151; ldr	r1, [r1, #12]
152; str	r1, [r0, #12]
153; str	r2, [r0, #8]
154; str	r3, [r0, #4]
155; str.w	r12, [r0]
156;
157; strict-align:
158;
159; push  {r7, lr}
160; movs  r2, #8
161; bl  __aeabi_memcpy
162; pop {r7, pc}
163;
164; CHECK-NO-SA-LABEL: 'memcpy_16'
165; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 16, i1 false)
166; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
167;
168; CHECK-SA-LABEL: 'memcpy_16'
169; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 16, i1 false)
170; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
171;
172entry:
173  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 16, i1 false)
174  ret void
175}
176
177define void @memcpy_32(i8* %d, i8* %s, i32 %N) {
178;
179; with/without strict-align:
180;
181; movs	r2, #32
182; bl	__aeabi_memcpy
183;
184; COMMON-LABEL: 'memcpy_32'
185; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 32, i1 false)
186; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
187;
188entry:
189  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 32, i1 false)
190  ret void
191}
192
193define void @memcpy_N(i8* %d, i8* %s, i32 %N) {
194;
195; with/without strict-align:
196;
197; bl __aeabi_memcpy
198;
199; COMMON-LABEL: 'memcpy_N'
200; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 %N, i1 false)
201; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
202;
203entry:
204  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 1 %s, i32 %N, i1 false)
205  ret void
206}
207
208;;;;;;;;;;;;;
209; Align 2, 2
210;;;;;;;;;;;;;
211
212define void @memcpy_1_al2(i8* %d, i8* %s) {
213;
214; with/without strict-align:
215;
216; ldrb r1, [r1]
217; strb r1, [r0]
218;
219; COMMON-LABEL: 'memcpy_1_al2'
220; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 1, i1 false)
221; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
222;
223entry:
224  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 1, i1 false)
225  ret void
226}
227
228define void @memcpy_2_al2(i8* %d, i8* %s) {
229;
230; with/without strict-align:
231;
232; ldrh r1, [r1]
233; strh r1, [r0]
234;
235; COMMON-LABEL: 'memcpy_2_al2'
236; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 2, i1 false)
237; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
238;
239entry:
240  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 2, i1 false)
241  ret void
242}
243
244define void @memcpy_3_al2(i8* %d, i8* %s) {
245;
246; with/without strict-align:
247;
248; ldrb r2, [r1, #2]
249; strb r2, [r0, #2]
250; ldrh r1, [r1]
251; strh r1, [r0]
252;
253; COMMON-LABEL: 'memcpy_3_al2'
254; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 3, i1 false)
255; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
256;
257entry:
258  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 3, i1 false)
259  ret void
260}
261
262define void @memcpy_4_al2(i8* %d, i8* %s) {
263;
264; no strict-align:
265;
266; ldr r1, [r1]
267; str r1, [r0]
268;
269; strict-align:
270;
271; ldrh  r2, [r1, #2]
272; strh  r2, [r0, #2]
273; ldrh  r1, [r1]
274; strh  r1, [r0]
275;
276; CHECK-NO-SA-LABEL: 'memcpy_4_al2'
277; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 4, i1 false)
278; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
279;
280; CHECK-SA-LABEL: 'memcpy_4_al2'
281; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 4, i1 false)
282; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
283;
284entry:
285  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 4, i1 false)
286  ret void
287}
288
289define void @memcpy_8_al2(i8* %d, i8* %s) {
290;
291; no strict-align:
292;
293; ldr r2, [r1]
294; ldr r1, [r1, #4]
295; str r1, [r0, #4]
296; str r2, [r0]
297;
298; strict-align:
299;
300;	ldrh	r2, [r1, #6]
301;	strh	r2, [r0, #6]
302;	ldrh	r2, [r1, #4]
303;	strh	r2, [r0, #4]
304;	ldrh	r2, [r1, #2]
305;	strh	r2, [r0, #2]
306;	ldrh	r1, [r1]
307;	strh	r1, [r0]
308;
309; CHECK-NO-SA-LABEL: 'memcpy_8_al2'
310; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 8, i1 false)
311; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
312;
313; CHECK-SA-LABEL: 'memcpy_8_al2'
314; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 8, i1 false)
315; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
316;
317entry:
318  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 8, i1 false)
319  ret void
320}
321
322define void @memcpy_16_al2(i8* %d, i8* %s) {
323;
324; no strict-align:
325;
326; ldr.w	r12, [r1]
327; ldr r3, [r1, #4]
328; ldr r2, [r1, #8]
329; ldr r1, [r1, #12]
330; str r1, [r0, #12]
331; str r2, [r0, #8]
332; str r3, [r0, #4]
333; str.w r12, [r0]
334;
335; strict-align:
336;
337;	movs	r2, #16
338;	bl	__aeabi_memcpy
339;
340; CHECK-NO-SA-LABEL: 'memcpy_16_al2'
341; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 16, i1 false)
342; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
343;
344; CHECK-SA-LABEL: 'memcpy_16_al2'
345; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 16, i1 false)
346; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
347;
348entry:
349  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 16, i1 false)
350  ret void
351}
352
353define void @memcpy_32_al2(i8* %d, i8* %s, i32 %N) {
354;
355; with/without strict-align:
356;
357; movs r2, #32
358; bl __aeabi_memcpy
359;
360; COMMON-LABEL: 'memcpy_32_al2'
361; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 32, i1 false)
362; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
363;
364entry:
365  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 32, i1 false)
366  ret void
367}
368
369define void @memcpy_N_al2(i8* %d, i8* %s, i32 %N) {
370;
371; with/without strict-align:
372;
373; bl __aeabi_memcpy
374;
375; COMMON-LABEL: 'memcpy_N_al2'
376; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 %N, i1 false)
377; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
378;
379entry:
380  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %d, i8* align 2 %s, i32 %N, i1 false)
381  ret void
382}
383
384;;;;;;;;;;;;;
385; Align 4, 4
386;;;;;;;;;;;;;
387
388define void @memcpy_1_al4(i8* %d, i8* %s) {
389;
390; with/without strict-align:
391;
392; ldrb r1, [r1]
393; strb r1, [r0]
394;
395; COMMON-LABEL: 'memcpy_1_al4'
396; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 1, i1 false)
397; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
398;
399entry:
400  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 1, i1 false)
401  ret void
402}
403
404define void @memcpy_2_al4(i8* %d, i8* %s) {
405;
406; with/without strict-align:
407;
408; ldrh r1, [r1]
409; strh r1, [r0]
410;
411; COMMON-LABEL: 'memcpy_2_al4'
412; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 2, i1 false)
413; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
414;
415entry:
416  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 2, i1 false)
417  ret void
418}
419
420define void @memcpy_3_al4(i8* %d, i8* %s) {
421;
422; with/without strict-align:
423;
424; ldrb r2, [r1, #2]
425; strb r2, [r0, #2]
426; ldrh r1, [r1]
427; strh r1, [r0]
428;
429; COMMON-LABEL: 'memcpy_3_al4'
430; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 3, i1 false)
431; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
432;
433entry:
434  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 3, i1 false)
435  ret void
436}
437
438define void @memcpy_4_al4(i8* %d, i8* %s) {
439;
440; with/without strict-align:
441;
442; ldr r1, [r1]
443; str r1, [r0]
444;
445; COMMON-LABEL: 'memcpy_4_al4'
446; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 4, i1 false)
447; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
448;
449entry:
450  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 4, i1 false)
451  ret void
452}
453
454define void @memcpy_8_al4(i8* %d, i8* %s) {
455;
456; with/without strict-align:
457;
458; ldrd r2, r1, [r1]
459; strd r2, r1, [r0]
460;
461; COMMON-LABEL: 'memcpy_8_al4'
462; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 8, i1 false)
463; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
464;
465entry:
466  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 8, i1 false)
467  ret void
468}
469
470define void @memcpy_16_al4(i8* %d, i8* %s) {
471;
472; with/without strict-align:
473;
474; ldm.w  r1, {r2, r3, r12}
475; ldr    r1, [r1, #12]
476; stm.w  r0, {r2, r3, r12}
477; str    r1, [r0, #12]
478;
479; COMMON-LABEL: 'memcpy_16_al4'
480; COMMON-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 16, i1 false)
481; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
482;
483entry:
484  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 16, i1 false)
485  ret void
486}
487
488define void @memcpy_32_al4(i8* %d, i8* %s, i32 %N) {
489;
490; with/without strict-align:
491;
492; ldm.w  r1!, {r2, r3, r12, lr}
493; stm.w  r0!, {r2, r3, r12, lr}
494; ldm.w  r1, {r2, r3, r12, lr}
495; stm.w  r0, {r2, r3, r12, lr}
496;
497; COMMON-LABEL: 'memcpy_32_al4'
498; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 32, i1 false)
499; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
500;
501entry:
502  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 32, i1 false)
503  ret void
504}
505
506define void @memcpy_N_al4(i8* %d, i8* %s, i32 %N) {
507;
508; with/without strict-align:
509;
510; bl  __aeabi_memcpy4
511;
512; COMMON-LABEL: 'memcpy_N_al4'
513; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 %N, i1 false)
514; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
515;
516entry:
517  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 4 %s, i32 %N, i1 false)
518  ret void
519}
520
521;;;;;;;;;;;;;
522; Align 1, 4
523;;;;;;;;;;;;;
524
525define void @memcpy_1_al14(i8* %d, i8* %s) {
526;
527; with/without strict-align:
528;
529; ldrb r1, [r1]
530; strb r1, [r0]
531;
532; COMMON-LABEL: 'memcpy_1_al14'
533; COMMON-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 1, i1 false)
534; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
535;
536entry:
537  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 1, i1 false)
538  ret void
539}
540
541define void @memcpy_2_al14(i8* %d, i8* %s) {
542;
543; no strict-align:
544;
545; ldrh r1, [r1]
546; strh r1, [r0]
547;
548; strict-align:
549;
550; ldrb	r2, [r1]
551; ldrb	r1, [r1, #1]
552; strb	r1, [r0, #1]
553; strb	r2, [r0]
554;
555; CHECK-NO-SA-LABEL: 'memcpy_2_al14'
556; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 2, i1 false)
557; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
558;
559; CHECK-SA-LABEL: 'memcpy_2_al14'
560; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 2, i1 false)
561; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
562;
563entry:
564  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 2, i1 false)
565  ret void
566}
567
568define void @memcpy_3_al14(i8* %d, i8* %s) {
569;
570; no strict-align:
571;
572; ldrb r2, [r1, #2]
573; strb r2, [r0, #2]
574; ldrh r1, [r1]
575; strh r1, [r0]
576;
577; strict-align:
578;
579; ldrb	r2, [r1]
580; ldrb	r3, [r1, #1]
581; ldrb	r1, [r1, #2]
582; strb	r1, [r0, #2]
583; strb	r3, [r0, #1]
584; strb	r2, [r0]
585;
586; CHECK-NO-SA-LABEL: 'memcpy_3_al14'
587; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 3, i1 false)
588; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
589;
590; CHECK-SA-LABEL: 'memcpy_3_al14'
591; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 3, i1 false)
592; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
593;
594entry:
595  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 3, i1 false)
596  ret void
597}
598
599define void @memcpy_4_al14(i8* %d, i8* %s) {
600;
601; no strict-align:
602;
603; ldr r1, [r1]
604; str r1, [r0]
605;
606; strict-align:
607;
608; ldrb.w	r12, [r1]
609; ldrb	r3, [r1, #1]
610; ldrb	r2, [r1, #2]
611; ldrb	r1, [r1, #3]
612; strb	r1, [r0, #3]
613; strb	r2, [r0, #2]
614; strb	r3, [r0, #1]
615; strb.w	r12, [r0]
616;
617; CHECK-NO-SA-LABEL: 'memcpy_4_al14'
618; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 4, i1 false)
619; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
620;
621; CHECK-SA-LABEL: 'memcpy_4_al14'
622; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 4, i1 false)
623; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
624;
625entry:
626  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 4, i1 false)
627  ret void
628}
629
630define void @memcpy_8_al14(i8* %d, i8* %s) {
631;
632; no strict-align:
633;
634; ldr r2, [r1]
635; ldr r1, [r1, #4]
636; str r1, [r0, #4]
637; str r2, [r0]
638;
639; strict-align:
640;
641; push  {r7, lr}
642; movs  r2, #8
643; bl  __aeabi_memcpy
644; pop {r7, pc}
645;
646; COMMON-LABEL: 'memcpy_8_al14'
647; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 8, i1 false)
648; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
649;
650entry:
651  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 8, i1 false)
652  ret void
653}
654
655define void @memcpy_16_al14(i8* %d, i8* %s) {
656;
657; no strict-align:
658;
659; ldr.w r12, [r1]
660; ldr   r3, [r1, #4]
661; ldr   r2, [r1, #8]
662; ldr   r1, [r1, #12]
663; str   r1, [r0, #12]
664; str   r2, [r0, #8]
665; str   r3, [r0, #4]
666; str.w r12, [r0]
667;
668; strict-align:
669;
670;	movs	r2, #16
671;	bl	__aeabi_memcpy
672;
673; CHECK-NO-SA-LABEL: 'memcpy_16_al14'
674; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 16, i1 false)
675; CHECK-NO-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
676;
677; CHECK-SA-LABEL: 'memcpy_16_al14'
678; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 16, i1 false)
679; CHECK-SA-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
680;
681entry:
682  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 16, i1 false)
683  ret void
684}
685
686define void @memcpy_32_al14(i8* %d, i8* %s) {
687;
688; with/without strict-align:
689;
690; movs r2, #32
691; bl   __aeabi_memcpy
692;
693; COMMON-LABEL: 'memcpy_32_al14'
694; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 32, i1 false)
695; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
696;
697entry:
698  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 32, i1 false)
699  ret void
700}
701
702define void @memcpy_N_al14(i8* %d, i8* %s, i32 %N) {
703;
704; with/without strict-align:
705;
706; bl  __aeabi_memcpy4
707;
708; COMMON-LABEL: 'memcpy_N_al14'
709; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 %N, i1 false)
710; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
711;
712entry:
713  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %d, i8* align 4 %s, i32 %N, i1 false)
714  ret void
715}
716
717;;;;;;;;;;;;;
718; Align 4, 1
719;;;;;;;;;;;;;
720
721define void @memcpy_1_al41(i8* %d, i8* %s) {
722;
723; with/without strict-align:
724;
725; ldrb  r1, [r1]
726; strb  r1, [r0]
727;
728; COMMON-LABEL: 'memcpy_1_al41'
729; COMMON-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 1 %s, i32 1, i1 false)
730; COMMON-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret void
731;
732entry:
733  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %d, i8* align 1 %s, i32 1, i1 false)
734  ret void
735}
736
737declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1) #1
738