xref: /llvm-project/llvm/test/CodeGen/X86/memcpy.ll (revision adc6a9e8189cc0a8a02a2fcea3f820ea2b402251)
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 %rcx
206; DARWIN-NEXT:    rep;movsb (%rsi), %es:(%rdi)
207; DARWIN-NEXT:    retq
208;
209; LINUX-LABEL: test3_minsize:
210; LINUX:       # %bb.0:
211; LINUX-NEXT:    pushq $64
212; LINUX-NEXT:    popq %rcx
213; LINUX-NEXT:    rep;movsb (%rsi), %es:(%rdi)
214; LINUX-NEXT:    retq
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.p0.p0.i64(ptr %A, ptr %B, i64 64, i1 false)
247  ret void
248}
249
250define void @test3_minsize_optsize(ptr nocapture %A, ptr 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 %rcx
255; DARWIN-NEXT:    rep;movsb (%rsi), %es:(%rdi)
256; DARWIN-NEXT:    retq
257;
258; LINUX-LABEL: test3_minsize_optsize:
259; LINUX:       # %bb.0:
260; LINUX-NEXT:    pushq $64
261; LINUX-NEXT:    popq %rcx
262; LINUX-NEXT:    rep;movsb (%rsi), %es:(%rdi)
263; LINUX-NEXT:    retq
264;
265; LINUX-SKL-LABEL: test3_minsize_optsize:
266; LINUX-SKL:       # %bb.0:
267; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
268; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
269; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
270; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
271; LINUX-SKL-NEXT:    vzeroupper
272; LINUX-SKL-NEXT:    retq
273;
274; LINUX-SKX-LABEL: test3_minsize_optsize:
275; LINUX-SKX:       # %bb.0:
276; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
277; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
278; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
279; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
280; LINUX-SKX-NEXT:    vzeroupper
281; LINUX-SKX-NEXT:    retq
282;
283; LINUX-KNL-LABEL: test3_minsize_optsize:
284; LINUX-KNL:       # %bb.0:
285; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
286; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
287; LINUX-KNL-NEXT:    retq
288;
289; LINUX-AVX512BW-LABEL: test3_minsize_optsize:
290; LINUX-AVX512BW:       # %bb.0:
291; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
292; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
293; LINUX-AVX512BW-NEXT:    vzeroupper
294; LINUX-AVX512BW-NEXT:    retq
295  tail call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 64, i1 false)
296  ret void
297}
298
299; Large constant memcpy's should be inlined when not optimizing for size.
300define void @test4(ptr nocapture %A, ptr nocapture %B) nounwind noredzone {
301; DARWIN-LABEL: test4:
302; DARWIN:       ## %bb.0: ## %entry
303; DARWIN-NEXT:    movq 56(%rsi), %rax
304; DARWIN-NEXT:    movq %rax, 56(%rdi)
305; DARWIN-NEXT:    movq 48(%rsi), %rax
306; DARWIN-NEXT:    movq %rax, 48(%rdi)
307; DARWIN-NEXT:    movq 40(%rsi), %rax
308; DARWIN-NEXT:    movq %rax, 40(%rdi)
309; DARWIN-NEXT:    movq 32(%rsi), %rax
310; DARWIN-NEXT:    movq %rax, 32(%rdi)
311; DARWIN-NEXT:    movq 24(%rsi), %rax
312; DARWIN-NEXT:    movq %rax, 24(%rdi)
313; DARWIN-NEXT:    movq 16(%rsi), %rax
314; DARWIN-NEXT:    movq %rax, 16(%rdi)
315; DARWIN-NEXT:    movq (%rsi), %rax
316; DARWIN-NEXT:    movq 8(%rsi), %rcx
317; DARWIN-NEXT:    movq %rcx, 8(%rdi)
318; DARWIN-NEXT:    movq %rax, (%rdi)
319; DARWIN-NEXT:    retq
320;
321; LINUX-LABEL: test4:
322; LINUX:       # %bb.0: # %entry
323; LINUX-NEXT:    movq 56(%rsi), %rax
324; LINUX-NEXT:    movq %rax, 56(%rdi)
325; LINUX-NEXT:    movq 48(%rsi), %rax
326; LINUX-NEXT:    movq %rax, 48(%rdi)
327; LINUX-NEXT:    movq 40(%rsi), %rax
328; LINUX-NEXT:    movq %rax, 40(%rdi)
329; LINUX-NEXT:    movq 32(%rsi), %rax
330; LINUX-NEXT:    movq %rax, 32(%rdi)
331; LINUX-NEXT:    movq 24(%rsi), %rax
332; LINUX-NEXT:    movq %rax, 24(%rdi)
333; LINUX-NEXT:    movq 16(%rsi), %rax
334; LINUX-NEXT:    movq %rax, 16(%rdi)
335; LINUX-NEXT:    movq (%rsi), %rax
336; LINUX-NEXT:    movq 8(%rsi), %rcx
337; LINUX-NEXT:    movq %rcx, 8(%rdi)
338; LINUX-NEXT:    movq %rax, (%rdi)
339; LINUX-NEXT:    retq
340;
341; LINUX-SKL-LABEL: test4:
342; LINUX-SKL:       # %bb.0: # %entry
343; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
344; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
345; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
346; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
347; LINUX-SKL-NEXT:    vzeroupper
348; LINUX-SKL-NEXT:    retq
349;
350; LINUX-SKX-LABEL: test4:
351; LINUX-SKX:       # %bb.0: # %entry
352; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
353; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
354; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
355; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
356; LINUX-SKX-NEXT:    vzeroupper
357; LINUX-SKX-NEXT:    retq
358;
359; LINUX-KNL-LABEL: test4:
360; LINUX-KNL:       # %bb.0: # %entry
361; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
362; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
363; LINUX-KNL-NEXT:    retq
364;
365; LINUX-AVX512BW-LABEL: test4:
366; LINUX-AVX512BW:       # %bb.0: # %entry
367; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
368; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
369; LINUX-AVX512BW-NEXT:    vzeroupper
370; LINUX-AVX512BW-NEXT:    retq
371entry:
372  tail call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 64, i1 false)
373  ret void
374}
375
376
377@.str = private unnamed_addr constant [30 x i8] c"\00aaaaaaaaaaaaaaaaaaaaaaaaaaaa\00", align 1
378
379define void @test5(ptr nocapture %C) nounwind uwtable ssp {
380; DARWIN-LABEL: test5:
381; DARWIN:       ## %bb.0: ## %entry
382; DARWIN-NEXT:    movabsq $7016996765293437281, %rax ## imm = 0x6161616161616161
383; DARWIN-NEXT:    movq %rax, 8(%rdi)
384; DARWIN-NEXT:    movabsq $7016996765293437184, %rax ## imm = 0x6161616161616100
385; DARWIN-NEXT:    movq %rax, (%rdi)
386; DARWIN-NEXT:    retq
387;
388; LINUX-LABEL: test5:
389; LINUX:       # %bb.0: # %entry
390; LINUX-NEXT:    movabsq $7016996765293437281, %rax # imm = 0x6161616161616161
391; LINUX-NEXT:    movq %rax, 8(%rdi)
392; LINUX-NEXT:    movabsq $7016996765293437184, %rax # imm = 0x6161616161616100
393; LINUX-NEXT:    movq %rax, (%rdi)
394; LINUX-NEXT:    retq
395;
396; LINUX-SKL-LABEL: test5:
397; LINUX-SKL:       # %bb.0: # %entry
398; LINUX-SKL-NEXT:    vmovups .L.str(%rip), %xmm0
399; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
400; LINUX-SKL-NEXT:    retq
401;
402; LINUX-SKX-LABEL: test5:
403; LINUX-SKX:       # %bb.0: # %entry
404; LINUX-SKX-NEXT:    vmovups .L.str(%rip), %xmm0
405; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
406; LINUX-SKX-NEXT:    retq
407;
408; LINUX-KNL-LABEL: test5:
409; LINUX-KNL:       # %bb.0: # %entry
410; LINUX-KNL-NEXT:    vmovups .L.str(%rip), %xmm0
411; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
412; LINUX-KNL-NEXT:    retq
413;
414; LINUX-AVX512BW-LABEL: test5:
415; LINUX-AVX512BW:       # %bb.0: # %entry
416; LINUX-AVX512BW-NEXT:    vmovups .L.str(%rip), %xmm0
417; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
418; LINUX-AVX512BW-NEXT:    retq
419entry:
420  tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str, i64 16, i1 false)
421  ret void
422}
423
424
425; PR14896
426@.str2 = private unnamed_addr constant [2 x i8] c"x\00", align 1
427
428define void @test6() nounwind uwtable {
429; DARWIN-LABEL: test6:
430; DARWIN:       ## %bb.0: ## %entry
431; DARWIN-NEXT:    movw $0, 8
432; DARWIN-NEXT:    movq $120, 0
433; DARWIN-NEXT:    retq
434;
435; LINUX-LABEL: test6:
436; LINUX:       # %bb.0: # %entry
437; LINUX-NEXT:    movw $0, 8
438; LINUX-NEXT:    movq $120, 0
439; LINUX-NEXT:    retq
440;
441; LINUX-SKL-LABEL: test6:
442; LINUX-SKL:       # %bb.0: # %entry
443; LINUX-SKL-NEXT:    movw $0, 8
444; LINUX-SKL-NEXT:    movq $120, 0
445; LINUX-SKL-NEXT:    retq
446;
447; LINUX-SKX-LABEL: test6:
448; LINUX-SKX:       # %bb.0: # %entry
449; LINUX-SKX-NEXT:    movw $0, 8
450; LINUX-SKX-NEXT:    movq $120, 0
451; LINUX-SKX-NEXT:    retq
452;
453; LINUX-KNL-LABEL: test6:
454; LINUX-KNL:       # %bb.0: # %entry
455; LINUX-KNL-NEXT:    movw $0, 8
456; LINUX-KNL-NEXT:    movq $120, 0
457; LINUX-KNL-NEXT:    retq
458;
459; LINUX-AVX512BW-LABEL: test6:
460; LINUX-AVX512BW:       # %bb.0: # %entry
461; LINUX-AVX512BW-NEXT:    movw $0, 8
462; LINUX-AVX512BW-NEXT:    movq $120, 0
463; LINUX-AVX512BW-NEXT:    retq
464entry:
465  tail call void @llvm.memcpy.p0.p0.i64(ptr null, ptr @.str2, i64 10, i1 false)
466  ret void
467}
468
469define void @PR15348(ptr %a, ptr %b) {
470; Ensure that alignment of '0' in an @llvm.memcpy intrinsic results in
471; unaligned loads and stores.
472; DARWIN-LABEL: PR15348:
473; DARWIN:       ## %bb.0:
474; DARWIN-NEXT:    movzbl 16(%rsi), %eax
475; DARWIN-NEXT:    movb %al, 16(%rdi)
476; DARWIN-NEXT:    movq (%rsi), %rax
477; DARWIN-NEXT:    movq 8(%rsi), %rcx
478; DARWIN-NEXT:    movq %rcx, 8(%rdi)
479; DARWIN-NEXT:    movq %rax, (%rdi)
480; DARWIN-NEXT:    retq
481;
482; LINUX-LABEL: PR15348:
483; LINUX:       # %bb.0:
484; LINUX-NEXT:    movzbl 16(%rsi), %eax
485; LINUX-NEXT:    movb %al, 16(%rdi)
486; LINUX-NEXT:    movq (%rsi), %rax
487; LINUX-NEXT:    movq 8(%rsi), %rcx
488; LINUX-NEXT:    movq %rcx, 8(%rdi)
489; LINUX-NEXT:    movq %rax, (%rdi)
490; LINUX-NEXT:    retq
491;
492; LINUX-SKL-LABEL: PR15348:
493; LINUX-SKL:       # %bb.0:
494; LINUX-SKL-NEXT:    movzbl 16(%rsi), %eax
495; LINUX-SKL-NEXT:    movb %al, 16(%rdi)
496; LINUX-SKL-NEXT:    vmovups (%rsi), %xmm0
497; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
498; LINUX-SKL-NEXT:    retq
499;
500; LINUX-SKX-LABEL: PR15348:
501; LINUX-SKX:       # %bb.0:
502; LINUX-SKX-NEXT:    movzbl 16(%rsi), %eax
503; LINUX-SKX-NEXT:    movb %al, 16(%rdi)
504; LINUX-SKX-NEXT:    vmovups (%rsi), %xmm0
505; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
506; LINUX-SKX-NEXT:    retq
507;
508; LINUX-KNL-LABEL: PR15348:
509; LINUX-KNL:       # %bb.0:
510; LINUX-KNL-NEXT:    movzbl 16(%rsi), %eax
511; LINUX-KNL-NEXT:    movb %al, 16(%rdi)
512; LINUX-KNL-NEXT:    vmovups (%rsi), %xmm0
513; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
514; LINUX-KNL-NEXT:    retq
515;
516; LINUX-AVX512BW-LABEL: PR15348:
517; LINUX-AVX512BW:       # %bb.0:
518; LINUX-AVX512BW-NEXT:    movzbl 16(%rsi), %eax
519; LINUX-AVX512BW-NEXT:    movb %al, 16(%rdi)
520; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %xmm0
521; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
522; LINUX-AVX512BW-NEXT:    retq
523  call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 17, i1 false)
524  ret void
525}
526
527; Memcpys from / to address space 256 should be lowered to appropriate loads /
528; stores if small enough.
529define void @addrspace256(ptr addrspace(256) %a, ptr addrspace(256) %b) nounwind {
530; DARWIN-LABEL: addrspace256:
531; DARWIN:       ## %bb.0:
532; DARWIN-NEXT:    movq %gs:(%rsi), %rax
533; DARWIN-NEXT:    movq %gs:8(%rsi), %rcx
534; DARWIN-NEXT:    movq %rcx, %gs:8(%rdi)
535; DARWIN-NEXT:    movq %rax, %gs:(%rdi)
536; DARWIN-NEXT:    retq
537;
538; LINUX-LABEL: addrspace256:
539; LINUX:       # %bb.0:
540; LINUX-NEXT:    movq %gs:(%rsi), %rax
541; LINUX-NEXT:    movq %gs:8(%rsi), %rcx
542; LINUX-NEXT:    movq %rcx, %gs:8(%rdi)
543; LINUX-NEXT:    movq %rax, %gs:(%rdi)
544; LINUX-NEXT:    retq
545;
546; LINUX-SKL-LABEL: addrspace256:
547; LINUX-SKL:       # %bb.0:
548; LINUX-SKL-NEXT:    vmovups %gs:(%rsi), %xmm0
549; LINUX-SKL-NEXT:    vmovups %xmm0, %gs:(%rdi)
550; LINUX-SKL-NEXT:    retq
551;
552; LINUX-SKX-LABEL: addrspace256:
553; LINUX-SKX:       # %bb.0:
554; LINUX-SKX-NEXT:    vmovups %gs:(%rsi), %xmm0
555; LINUX-SKX-NEXT:    vmovups %xmm0, %gs:(%rdi)
556; LINUX-SKX-NEXT:    retq
557;
558; LINUX-KNL-LABEL: addrspace256:
559; LINUX-KNL:       # %bb.0:
560; LINUX-KNL-NEXT:    vmovups %gs:(%rsi), %xmm0
561; LINUX-KNL-NEXT:    vmovups %xmm0, %gs:(%rdi)
562; LINUX-KNL-NEXT:    retq
563;
564; LINUX-AVX512BW-LABEL: addrspace256:
565; LINUX-AVX512BW:       # %bb.0:
566; LINUX-AVX512BW-NEXT:    vmovups %gs:(%rsi), %xmm0
567; LINUX-AVX512BW-NEXT:    vmovups %xmm0, %gs:(%rdi)
568; LINUX-AVX512BW-NEXT:    retq
569  tail call void @llvm.memcpy.p256.p256.i64(ptr addrspace(256) align 8 %a, ptr addrspace(256) align 8 %b, i64 16, i1 false)
570  ret void
571}
572
573!llvm.module.flags = !{!0}
574!0 = !{i32 1, !"ProfileSummary", !1}
575!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
576!2 = !{!"ProfileFormat", !"InstrProf"}
577!3 = !{!"TotalCount", i64 10000}
578!4 = !{!"MaxCount", i64 10}
579!5 = !{!"MaxInternalCount", i64 1}
580!6 = !{!"MaxFunctionCount", i64 1000}
581!7 = !{!"NumCounts", i64 3}
582!8 = !{!"NumFunctions", i64 3}
583!9 = !{!"DetailedSummary", !10}
584!10 = !{!11, !12, !13}
585!11 = !{i32 10000, i64 100, i32 1}
586!12 = !{i32 999000, i64 100, i32 1}
587!13 = !{i32 999999, i64 1, i32 2}
588!14 = !{!"function_entry_count", i64 0}
589