1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-apple-darwin      -mcpu=core2     | FileCheck %s -check-prefix=DARWIN
3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core2     | FileCheck %s -check-prefix=LINUX
4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake   | FileCheck %s -check-prefix=LINUX-SKL
5; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=skx       | FileCheck %s -check-prefix=LINUX-SKX
6; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=knl       | FileCheck %s -check-prefix=LINUX-KNL
7; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=avx512bw | FileCheck %s -check-prefix=LINUX-AVX512BW
8
9declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
10declare void @llvm.memcpy.p256i8.p256i8.i64(i8 addrspace(256)* nocapture, i8 addrspace(256)* nocapture, i64, i1) nounwind
11
12
13; Variable memcpy's should lower to calls.
14define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
15; DARWIN-LABEL: test1:
16; DARWIN:       ## %bb.0: ## %entry
17; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
18;
19; LINUX-LABEL: test1:
20; LINUX:       # %bb.0: # %entry
21; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
22;
23; LINUX-SKL-LABEL: test1:
24; LINUX-SKL:       # %bb.0: # %entry
25; LINUX-SKL-NEXT:    jmp memcpy@PLT # TAILCALL
26;
27; LINUX-SKX-LABEL: test1:
28; LINUX-SKX:       # %bb.0: # %entry
29; LINUX-SKX-NEXT:    jmp memcpy@PLT # TAILCALL
30;
31; LINUX-KNL-LABEL: test1:
32; LINUX-KNL:       # %bb.0: # %entry
33; LINUX-KNL-NEXT:    jmp memcpy@PLT # TAILCALL
34;
35; LINUX-AVX512BW-LABEL: test1:
36; LINUX-AVX512BW:       # %bb.0: # %entry
37; LINUX-AVX512BW-NEXT:    jmp memcpy@PLT # TAILCALL
38entry:
39	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
40	ret i8* %a
41}
42
43; Variable memcpy's should lower to calls.
44define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
45; DARWIN-LABEL: test2:
46; DARWIN:       ## %bb.0: ## %entry
47; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
48;
49; LINUX-LABEL: test2:
50; LINUX:       # %bb.0: # %entry
51; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
52;
53; LINUX-SKL-LABEL: test2:
54; LINUX-SKL:       # %bb.0: # %entry
55; LINUX-SKL-NEXT:    jmp memcpy@PLT # TAILCALL
56;
57; LINUX-SKX-LABEL: test2:
58; LINUX-SKX:       # %bb.0: # %entry
59; LINUX-SKX-NEXT:    jmp memcpy@PLT # TAILCALL
60;
61; LINUX-KNL-LABEL: test2:
62; LINUX-KNL:       # %bb.0: # %entry
63; LINUX-KNL-NEXT:    jmp memcpy@PLT # TAILCALL
64;
65; LINUX-AVX512BW-LABEL: test2:
66; LINUX-AVX512BW:       # %bb.0: # %entry
67; LINUX-AVX512BW-NEXT:    jmp memcpy@PLT # TAILCALL
68entry:
69	%tmp14 = bitcast i64* %a to i8*
70	%tmp25 = bitcast i64* %b to i8*
71	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp14, i8* align 8 %tmp25, i64 %n, i1 0 )
72	ret i8* %tmp14
73}
74
75; Large constant memcpy's should lower to a call when optimizing for size.
76; PR6623
77
78; On the other hand, Darwin's definition of -Os is optimizing for size without
79; hurting performance so it should just ignore optsize when expanding memcpy.
80; rdar://8821501
81define void @test3(i8* nocapture %A, i8* nocapture %B) nounwind optsize noredzone {
82; DARWIN-LABEL: test3:
83; DARWIN:       ## %bb.0: ## %entry
84; DARWIN-NEXT:    movq 56(%rsi), %rax
85; DARWIN-NEXT:    movq %rax, 56(%rdi)
86; DARWIN-NEXT:    movq 48(%rsi), %rax
87; DARWIN-NEXT:    movq %rax, 48(%rdi)
88; DARWIN-NEXT:    movq 40(%rsi), %rax
89; DARWIN-NEXT:    movq %rax, 40(%rdi)
90; DARWIN-NEXT:    movq 32(%rsi), %rax
91; DARWIN-NEXT:    movq %rax, 32(%rdi)
92; DARWIN-NEXT:    movq 24(%rsi), %rax
93; DARWIN-NEXT:    movq %rax, 24(%rdi)
94; DARWIN-NEXT:    movq 16(%rsi), %rax
95; DARWIN-NEXT:    movq %rax, 16(%rdi)
96; DARWIN-NEXT:    movq (%rsi), %rax
97; DARWIN-NEXT:    movq 8(%rsi), %rcx
98; DARWIN-NEXT:    movq %rcx, 8(%rdi)
99; DARWIN-NEXT:    movq %rax, (%rdi)
100; DARWIN-NEXT:    retq
101;
102; LINUX-LABEL: test3:
103; LINUX:       # %bb.0: # %entry
104; LINUX-NEXT:    movl $64, %edx
105; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
106;
107; LINUX-SKL-LABEL: test3:
108; LINUX-SKL:       # %bb.0: # %entry
109; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
110; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
111; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
112; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
113; LINUX-SKL-NEXT:    vzeroupper
114; LINUX-SKL-NEXT:    retq
115;
116; LINUX-SKX-LABEL: test3:
117; LINUX-SKX:       # %bb.0: # %entry
118; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
119; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
120; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
121; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
122; LINUX-SKX-NEXT:    vzeroupper
123; LINUX-SKX-NEXT:    retq
124;
125; LINUX-KNL-LABEL: test3:
126; LINUX-KNL:       # %bb.0: # %entry
127; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
128; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
129; LINUX-KNL-NEXT:    retq
130;
131; LINUX-AVX512BW-LABEL: test3:
132; LINUX-AVX512BW:       # %bb.0: # %entry
133; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
134; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
135; LINUX-AVX512BW-NEXT:    vzeroupper
136; LINUX-AVX512BW-NEXT:    retq
137entry:
138  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
139  ret void
140}
141
142define void @test3_pgso(i8* nocapture %A, i8* nocapture %B) nounwind noredzone !prof !14 {
143; DARWIN-LABEL: test3_pgso:
144; DARWIN:       ## %bb.0: ## %entry
145; DARWIN-NEXT:    movq 56(%rsi), %rax
146; DARWIN-NEXT:    movq %rax, 56(%rdi)
147; DARWIN-NEXT:    movq 48(%rsi), %rax
148; DARWIN-NEXT:    movq %rax, 48(%rdi)
149; DARWIN-NEXT:    movq 40(%rsi), %rax
150; DARWIN-NEXT:    movq %rax, 40(%rdi)
151; DARWIN-NEXT:    movq 32(%rsi), %rax
152; DARWIN-NEXT:    movq %rax, 32(%rdi)
153; DARWIN-NEXT:    movq 24(%rsi), %rax
154; DARWIN-NEXT:    movq %rax, 24(%rdi)
155; DARWIN-NEXT:    movq 16(%rsi), %rax
156; DARWIN-NEXT:    movq %rax, 16(%rdi)
157; DARWIN-NEXT:    movq (%rsi), %rax
158; DARWIN-NEXT:    movq 8(%rsi), %rcx
159; DARWIN-NEXT:    movq %rcx, 8(%rdi)
160; DARWIN-NEXT:    movq %rax, (%rdi)
161; DARWIN-NEXT:    retq
162;
163; LINUX-LABEL: test3_pgso:
164; LINUX:       # %bb.0: # %entry
165; LINUX-NEXT:    movl $64, %edx
166; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
167;
168; LINUX-SKL-LABEL: test3_pgso:
169; LINUX-SKL:       # %bb.0: # %entry
170; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
171; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
172; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
173; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
174; LINUX-SKL-NEXT:    vzeroupper
175; LINUX-SKL-NEXT:    retq
176;
177; LINUX-SKX-LABEL: test3_pgso:
178; LINUX-SKX:       # %bb.0: # %entry
179; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
180; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
181; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
182; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
183; LINUX-SKX-NEXT:    vzeroupper
184; LINUX-SKX-NEXT:    retq
185;
186; LINUX-KNL-LABEL: test3_pgso:
187; LINUX-KNL:       # %bb.0: # %entry
188; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
189; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
190; LINUX-KNL-NEXT:    retq
191;
192; LINUX-AVX512BW-LABEL: test3_pgso:
193; LINUX-AVX512BW:       # %bb.0: # %entry
194; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
195; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
196; LINUX-AVX512BW-NEXT:    vzeroupper
197; LINUX-AVX512BW-NEXT:    retq
198entry:
199  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
200  ret void
201}
202
203define void @test3_minsize(i8* nocapture %A, i8* nocapture %B) nounwind minsize noredzone {
204; DARWIN-LABEL: test3_minsize:
205; DARWIN:       ## %bb.0:
206; DARWIN-NEXT:    pushq $64
207; DARWIN-NEXT:    popq %rdx
208; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
209;
210; LINUX-LABEL: test3_minsize:
211; LINUX:       # %bb.0:
212; LINUX-NEXT:    pushq $64
213; LINUX-NEXT:    popq %rdx
214; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
215;
216; LINUX-SKL-LABEL: test3_minsize:
217; LINUX-SKL:       # %bb.0:
218; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
219; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
220; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
221; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
222; LINUX-SKL-NEXT:    vzeroupper
223; LINUX-SKL-NEXT:    retq
224;
225; LINUX-SKX-LABEL: test3_minsize:
226; LINUX-SKX:       # %bb.0:
227; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
228; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
229; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
230; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
231; LINUX-SKX-NEXT:    vzeroupper
232; LINUX-SKX-NEXT:    retq
233;
234; LINUX-KNL-LABEL: test3_minsize:
235; LINUX-KNL:       # %bb.0:
236; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
237; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
238; LINUX-KNL-NEXT:    retq
239;
240; LINUX-AVX512BW-LABEL: test3_minsize:
241; LINUX-AVX512BW:       # %bb.0:
242; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
243; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
244; LINUX-AVX512BW-NEXT:    vzeroupper
245; LINUX-AVX512BW-NEXT:    retq
246  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
247  ret void
248}
249
250define void @test3_minsize_optsize(i8* nocapture %A, i8* nocapture %B) nounwind optsize minsize noredzone {
251; DARWIN-LABEL: test3_minsize_optsize:
252; DARWIN:       ## %bb.0:
253; DARWIN-NEXT:    pushq $64
254; DARWIN-NEXT:    popq %rdx
255; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
256;
257; LINUX-LABEL: test3_minsize_optsize:
258; LINUX:       # %bb.0:
259; LINUX-NEXT:    pushq $64
260; LINUX-NEXT:    popq %rdx
261; LINUX-NEXT:    jmp memcpy@PLT # TAILCALL
262;
263; LINUX-SKL-LABEL: test3_minsize_optsize:
264; LINUX-SKL:       # %bb.0:
265; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
266; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
267; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
268; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
269; LINUX-SKL-NEXT:    vzeroupper
270; LINUX-SKL-NEXT:    retq
271;
272; LINUX-SKX-LABEL: test3_minsize_optsize:
273; LINUX-SKX:       # %bb.0:
274; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
275; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
276; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
277; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
278; LINUX-SKX-NEXT:    vzeroupper
279; LINUX-SKX-NEXT:    retq
280;
281; LINUX-KNL-LABEL: test3_minsize_optsize:
282; LINUX-KNL:       # %bb.0:
283; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
284; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
285; LINUX-KNL-NEXT:    retq
286;
287; LINUX-AVX512BW-LABEL: test3_minsize_optsize:
288; LINUX-AVX512BW:       # %bb.0:
289; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
290; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
291; LINUX-AVX512BW-NEXT:    vzeroupper
292; LINUX-AVX512BW-NEXT:    retq
293  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
294  ret void
295}
296
297; Large constant memcpy's should be inlined when not optimizing for size.
298define void @test4(i8* nocapture %A, i8* nocapture %B) nounwind noredzone {
299; DARWIN-LABEL: test4:
300; DARWIN:       ## %bb.0: ## %entry
301; DARWIN-NEXT:    movq 56(%rsi), %rax
302; DARWIN-NEXT:    movq %rax, 56(%rdi)
303; DARWIN-NEXT:    movq 48(%rsi), %rax
304; DARWIN-NEXT:    movq %rax, 48(%rdi)
305; DARWIN-NEXT:    movq 40(%rsi), %rax
306; DARWIN-NEXT:    movq %rax, 40(%rdi)
307; DARWIN-NEXT:    movq 32(%rsi), %rax
308; DARWIN-NEXT:    movq %rax, 32(%rdi)
309; DARWIN-NEXT:    movq 24(%rsi), %rax
310; DARWIN-NEXT:    movq %rax, 24(%rdi)
311; DARWIN-NEXT:    movq 16(%rsi), %rax
312; DARWIN-NEXT:    movq %rax, 16(%rdi)
313; DARWIN-NEXT:    movq (%rsi), %rax
314; DARWIN-NEXT:    movq 8(%rsi), %rcx
315; DARWIN-NEXT:    movq %rcx, 8(%rdi)
316; DARWIN-NEXT:    movq %rax, (%rdi)
317; DARWIN-NEXT:    retq
318;
319; LINUX-LABEL: test4:
320; LINUX:       # %bb.0: # %entry
321; LINUX-NEXT:    movq 56(%rsi), %rax
322; LINUX-NEXT:    movq %rax, 56(%rdi)
323; LINUX-NEXT:    movq 48(%rsi), %rax
324; LINUX-NEXT:    movq %rax, 48(%rdi)
325; LINUX-NEXT:    movq 40(%rsi), %rax
326; LINUX-NEXT:    movq %rax, 40(%rdi)
327; LINUX-NEXT:    movq 32(%rsi), %rax
328; LINUX-NEXT:    movq %rax, 32(%rdi)
329; LINUX-NEXT:    movq 24(%rsi), %rax
330; LINUX-NEXT:    movq %rax, 24(%rdi)
331; LINUX-NEXT:    movq 16(%rsi), %rax
332; LINUX-NEXT:    movq %rax, 16(%rdi)
333; LINUX-NEXT:    movq (%rsi), %rax
334; LINUX-NEXT:    movq 8(%rsi), %rcx
335; LINUX-NEXT:    movq %rcx, 8(%rdi)
336; LINUX-NEXT:    movq %rax, (%rdi)
337; LINUX-NEXT:    retq
338;
339; LINUX-SKL-LABEL: test4:
340; LINUX-SKL:       # %bb.0: # %entry
341; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
342; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
343; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
344; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
345; LINUX-SKL-NEXT:    vzeroupper
346; LINUX-SKL-NEXT:    retq
347;
348; LINUX-SKX-LABEL: test4:
349; LINUX-SKX:       # %bb.0: # %entry
350; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
351; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
352; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
353; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
354; LINUX-SKX-NEXT:    vzeroupper
355; LINUX-SKX-NEXT:    retq
356;
357; LINUX-KNL-LABEL: test4:
358; LINUX-KNL:       # %bb.0: # %entry
359; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
360; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
361; LINUX-KNL-NEXT:    retq
362;
363; LINUX-AVX512BW-LABEL: test4:
364; LINUX-AVX512BW:       # %bb.0: # %entry
365; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
366; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
367; LINUX-AVX512BW-NEXT:    vzeroupper
368; LINUX-AVX512BW-NEXT:    retq
369entry:
370  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
371  ret void
372}
373
374
375@.str = private unnamed_addr constant [30 x i8] c"\00aaaaaaaaaaaaaaaaaaaaaaaaaaaa\00", align 1
376
377define void @test5(i8* nocapture %C) nounwind uwtable ssp {
378; DARWIN-LABEL: test5:
379; DARWIN:       ## %bb.0: ## %entry
380; DARWIN-NEXT:    movabsq $7016996765293437281, %rax ## imm = 0x6161616161616161
381; DARWIN-NEXT:    movq %rax, 8(%rdi)
382; DARWIN-NEXT:    movabsq $7016996765293437184, %rax ## imm = 0x6161616161616100
383; DARWIN-NEXT:    movq %rax, (%rdi)
384; DARWIN-NEXT:    retq
385;
386; LINUX-LABEL: test5:
387; LINUX:       # %bb.0: # %entry
388; LINUX-NEXT:    movabsq $7016996765293437281, %rax # imm = 0x6161616161616161
389; LINUX-NEXT:    movq %rax, 8(%rdi)
390; LINUX-NEXT:    movabsq $7016996765293437184, %rax # imm = 0x6161616161616100
391; LINUX-NEXT:    movq %rax, (%rdi)
392; LINUX-NEXT:    retq
393;
394; LINUX-SKL-LABEL: test5:
395; LINUX-SKL:       # %bb.0: # %entry
396; LINUX-SKL-NEXT:    vmovups .L.str(%rip), %xmm0
397; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
398; LINUX-SKL-NEXT:    retq
399;
400; LINUX-SKX-LABEL: test5:
401; LINUX-SKX:       # %bb.0: # %entry
402; LINUX-SKX-NEXT:    vmovups .L.str(%rip), %xmm0
403; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
404; LINUX-SKX-NEXT:    retq
405;
406; LINUX-KNL-LABEL: test5:
407; LINUX-KNL:       # %bb.0: # %entry
408; LINUX-KNL-NEXT:    vmovups .L.str(%rip), %xmm0
409; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
410; LINUX-KNL-NEXT:    retq
411;
412; LINUX-AVX512BW-LABEL: test5:
413; LINUX-AVX512BW:       # %bb.0: # %entry
414; LINUX-AVX512BW-NEXT:    vmovups .L.str(%rip), %xmm0
415; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
416; LINUX-AVX512BW-NEXT:    retq
417entry:
418  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0), i64 16, i1 false)
419  ret void
420}
421
422
423; PR14896
424@.str2 = private unnamed_addr constant [2 x i8] c"x\00", align 1
425
426define void @test6() nounwind uwtable {
427; DARWIN-LABEL: test6:
428; DARWIN:       ## %bb.0: ## %entry
429; DARWIN-NEXT:    movw $0, 8
430; DARWIN-NEXT:    movq $120, 0
431; DARWIN-NEXT:    retq
432;
433; LINUX-LABEL: test6:
434; LINUX:       # %bb.0: # %entry
435; LINUX-NEXT:    movw $0, 8
436; LINUX-NEXT:    movq $120, 0
437; LINUX-NEXT:    retq
438;
439; LINUX-SKL-LABEL: test6:
440; LINUX-SKL:       # %bb.0: # %entry
441; LINUX-SKL-NEXT:    movw $0, 8
442; LINUX-SKL-NEXT:    movq $120, 0
443; LINUX-SKL-NEXT:    retq
444;
445; LINUX-SKX-LABEL: test6:
446; LINUX-SKX:       # %bb.0: # %entry
447; LINUX-SKX-NEXT:    movw $0, 8
448; LINUX-SKX-NEXT:    movq $120, 0
449; LINUX-SKX-NEXT:    retq
450;
451; LINUX-KNL-LABEL: test6:
452; LINUX-KNL:       # %bb.0: # %entry
453; LINUX-KNL-NEXT:    movw $0, 8
454; LINUX-KNL-NEXT:    movq $120, 0
455; LINUX-KNL-NEXT:    retq
456;
457; LINUX-AVX512BW-LABEL: test6:
458; LINUX-AVX512BW:       # %bb.0: # %entry
459; LINUX-AVX512BW-NEXT:    movw $0, 8
460; LINUX-AVX512BW-NEXT:    movq $120, 0
461; LINUX-AVX512BW-NEXT:    retq
462entry:
463  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* null, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str2, i64 0, i64 0), i64 10, i1 false)
464  ret void
465}
466
467define void @PR15348(i8* %a, i8* %b) {
468; Ensure that alignment of '0' in an @llvm.memcpy intrinsic results in
469; unaligned loads and stores.
470; DARWIN-LABEL: PR15348:
471; DARWIN:       ## %bb.0:
472; DARWIN-NEXT:    movb 16(%rsi), %al
473; DARWIN-NEXT:    movb %al, 16(%rdi)
474; DARWIN-NEXT:    movq (%rsi), %rax
475; DARWIN-NEXT:    movq 8(%rsi), %rcx
476; DARWIN-NEXT:    movq %rcx, 8(%rdi)
477; DARWIN-NEXT:    movq %rax, (%rdi)
478; DARWIN-NEXT:    retq
479;
480; LINUX-LABEL: PR15348:
481; LINUX:       # %bb.0:
482; LINUX-NEXT:    movb 16(%rsi), %al
483; LINUX-NEXT:    movb %al, 16(%rdi)
484; LINUX-NEXT:    movq (%rsi), %rax
485; LINUX-NEXT:    movq 8(%rsi), %rcx
486; LINUX-NEXT:    movq %rcx, 8(%rdi)
487; LINUX-NEXT:    movq %rax, (%rdi)
488; LINUX-NEXT:    retq
489;
490; LINUX-SKL-LABEL: PR15348:
491; LINUX-SKL:       # %bb.0:
492; LINUX-SKL-NEXT:    movb 16(%rsi), %al
493; LINUX-SKL-NEXT:    movb %al, 16(%rdi)
494; LINUX-SKL-NEXT:    vmovups (%rsi), %xmm0
495; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
496; LINUX-SKL-NEXT:    retq
497;
498; LINUX-SKX-LABEL: PR15348:
499; LINUX-SKX:       # %bb.0:
500; LINUX-SKX-NEXT:    movb 16(%rsi), %al
501; LINUX-SKX-NEXT:    movb %al, 16(%rdi)
502; LINUX-SKX-NEXT:    vmovups (%rsi), %xmm0
503; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
504; LINUX-SKX-NEXT:    retq
505;
506; LINUX-KNL-LABEL: PR15348:
507; LINUX-KNL:       # %bb.0:
508; LINUX-KNL-NEXT:    movb 16(%rsi), %al
509; LINUX-KNL-NEXT:    movb %al, 16(%rdi)
510; LINUX-KNL-NEXT:    vmovups (%rsi), %xmm0
511; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
512; LINUX-KNL-NEXT:    retq
513;
514; LINUX-AVX512BW-LABEL: PR15348:
515; LINUX-AVX512BW:       # %bb.0:
516; LINUX-AVX512BW-NEXT:    movb 16(%rsi), %al
517; LINUX-AVX512BW-NEXT:    movb %al, 16(%rdi)
518; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %xmm0
519; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
520; LINUX-AVX512BW-NEXT:    retq
521  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 17, i1 false)
522  ret void
523}
524
525; Memcpys from / to address space 256 should be lowered to appropriate loads /
526; stores if small enough.
527define void @addrspace256(i8 addrspace(256)* %a, i8 addrspace(256)* %b) nounwind {
528; DARWIN-LABEL: addrspace256:
529; DARWIN:       ## %bb.0:
530; DARWIN-NEXT:    movq %gs:(%rsi), %rax
531; DARWIN-NEXT:    movq %gs:8(%rsi), %rcx
532; DARWIN-NEXT:    movq %rcx, %gs:8(%rdi)
533; DARWIN-NEXT:    movq %rax, %gs:(%rdi)
534; DARWIN-NEXT:    retq
535;
536; LINUX-LABEL: addrspace256:
537; LINUX:       # %bb.0:
538; LINUX-NEXT:    movq %gs:(%rsi), %rax
539; LINUX-NEXT:    movq %gs:8(%rsi), %rcx
540; LINUX-NEXT:    movq %rcx, %gs:8(%rdi)
541; LINUX-NEXT:    movq %rax, %gs:(%rdi)
542; LINUX-NEXT:    retq
543;
544; LINUX-SKL-LABEL: addrspace256:
545; LINUX-SKL:       # %bb.0:
546; LINUX-SKL-NEXT:    vmovups %gs:(%rsi), %xmm0
547; LINUX-SKL-NEXT:    vmovups %xmm0, %gs:(%rdi)
548; LINUX-SKL-NEXT:    retq
549;
550; LINUX-SKX-LABEL: addrspace256:
551; LINUX-SKX:       # %bb.0:
552; LINUX-SKX-NEXT:    vmovups %gs:(%rsi), %xmm0
553; LINUX-SKX-NEXT:    vmovups %xmm0, %gs:(%rdi)
554; LINUX-SKX-NEXT:    retq
555;
556; LINUX-KNL-LABEL: addrspace256:
557; LINUX-KNL:       # %bb.0:
558; LINUX-KNL-NEXT:    vmovups %gs:(%rsi), %xmm0
559; LINUX-KNL-NEXT:    vmovups %xmm0, %gs:(%rdi)
560; LINUX-KNL-NEXT:    retq
561;
562; LINUX-AVX512BW-LABEL: addrspace256:
563; LINUX-AVX512BW:       # %bb.0:
564; LINUX-AVX512BW-NEXT:    vmovups %gs:(%rsi), %xmm0
565; LINUX-AVX512BW-NEXT:    vmovups %xmm0, %gs:(%rdi)
566; LINUX-AVX512BW-NEXT:    retq
567  tail call void @llvm.memcpy.p256i8.p256i8.i64(i8 addrspace(256)* align 8 %a, i8 addrspace(256)* align 8 %b, i64 16, i1 false)
568  ret void
569}
570
571!llvm.module.flags = !{!0}
572!0 = !{i32 1, !"ProfileSummary", !1}
573!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
574!2 = !{!"ProfileFormat", !"InstrProf"}
575!3 = !{!"TotalCount", i64 10000}
576!4 = !{!"MaxCount", i64 10}
577!5 = !{!"MaxInternalCount", i64 1}
578!6 = !{!"MaxFunctionCount", i64 1000}
579!7 = !{!"NumCounts", i64 3}
580!8 = !{!"NumFunctions", i64 3}
581!9 = !{!"DetailedSummary", !10}
582!10 = !{!11, !12, !13}
583!11 = !{i32 10000, i64 100, i32 1}
584!12 = !{i32 999000, i64 100, i32 1}
585!13 = !{i32 999999, i64 1, i32 2}
586!14 = !{!"function_entry_count", i64 0}
587