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