[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / memcpy.ll
blob531117dbcda45e33a60f6082d1023bd1325c8dbb
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
9 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
10 declare void @llvm.memcpy.p256i8.p256i8.i64(i8 addrspace(256)* nocapture, i8 addrspace(256)* nocapture, i64, i1) nounwind
13 ; Variable memcpy's should lower to calls.
14 define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
15 ; DARWIN-LABEL: test1:
16 ; DARWIN:       ## %bb.0: ## %entry
17 ; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
19 ; LINUX-LABEL: test1:
20 ; LINUX:       # %bb.0: # %entry
21 ; LINUX-NEXT:    jmp memcpy # TAILCALL
23 ; LINUX-SKL-LABEL: test1:
24 ; LINUX-SKL:       # %bb.0: # %entry
25 ; LINUX-SKL-NEXT:    jmp memcpy # TAILCALL
27 ; LINUX-SKX-LABEL: test1:
28 ; LINUX-SKX:       # %bb.0: # %entry
29 ; LINUX-SKX-NEXT:    jmp memcpy # TAILCALL
31 ; LINUX-KNL-LABEL: test1:
32 ; LINUX-KNL:       # %bb.0: # %entry
33 ; LINUX-KNL-NEXT:    jmp memcpy # TAILCALL
35 ; LINUX-AVX512BW-LABEL: test1:
36 ; LINUX-AVX512BW:       # %bb.0: # %entry
37 ; LINUX-AVX512BW-NEXT:    jmp memcpy # TAILCALL
38 entry:
39         tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
40         ret i8* %a
43 ; Variable memcpy's should lower to calls.
44 define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
45 ; DARWIN-LABEL: test2:
46 ; DARWIN:       ## %bb.0: ## %entry
47 ; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
49 ; LINUX-LABEL: test2:
50 ; LINUX:       # %bb.0: # %entry
51 ; LINUX-NEXT:    jmp memcpy # TAILCALL
53 ; LINUX-SKL-LABEL: test2:
54 ; LINUX-SKL:       # %bb.0: # %entry
55 ; LINUX-SKL-NEXT:    jmp memcpy # TAILCALL
57 ; LINUX-SKX-LABEL: test2:
58 ; LINUX-SKX:       # %bb.0: # %entry
59 ; LINUX-SKX-NEXT:    jmp memcpy # TAILCALL
61 ; LINUX-KNL-LABEL: test2:
62 ; LINUX-KNL:       # %bb.0: # %entry
63 ; LINUX-KNL-NEXT:    jmp memcpy # TAILCALL
65 ; LINUX-AVX512BW-LABEL: test2:
66 ; LINUX-AVX512BW:       # %bb.0: # %entry
67 ; LINUX-AVX512BW-NEXT:    jmp memcpy # TAILCALL
68 entry:
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
75 ; Large constant memcpy's should lower to a call when optimizing for size.
76 ; PR6623
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
81 define 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
102 ; LINUX-LABEL: test3:
103 ; LINUX:       # %bb.0: # %entry
104 ; LINUX-NEXT:    movl $64, %edx
105 ; LINUX-NEXT:    jmp memcpy # TAILCALL
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
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
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
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
137 entry:
138   tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
139   ret void
142 define void @test3_minsize(i8* nocapture %A, i8* nocapture %B) nounwind minsize noredzone {
143 ; DARWIN-LABEL: test3_minsize:
144 ; DARWIN:       ## %bb.0:
145 ; DARWIN-NEXT:    pushq $64
146 ; DARWIN-NEXT:    popq %rdx
147 ; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
149 ; LINUX-LABEL: test3_minsize:
150 ; LINUX:       # %bb.0:
151 ; LINUX-NEXT:    pushq $64
152 ; LINUX-NEXT:    popq %rdx
153 ; LINUX-NEXT:    jmp memcpy # TAILCALL
155 ; LINUX-SKL-LABEL: test3_minsize:
156 ; LINUX-SKL:       # %bb.0:
157 ; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
158 ; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
159 ; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
160 ; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
161 ; LINUX-SKL-NEXT:    vzeroupper
162 ; LINUX-SKL-NEXT:    retq
164 ; LINUX-SKX-LABEL: test3_minsize:
165 ; LINUX-SKX:       # %bb.0:
166 ; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
167 ; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
168 ; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
169 ; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
170 ; LINUX-SKX-NEXT:    vzeroupper
171 ; LINUX-SKX-NEXT:    retq
173 ; LINUX-KNL-LABEL: test3_minsize:
174 ; LINUX-KNL:       # %bb.0:
175 ; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
176 ; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
177 ; LINUX-KNL-NEXT:    retq
179 ; LINUX-AVX512BW-LABEL: test3_minsize:
180 ; LINUX-AVX512BW:       # %bb.0:
181 ; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
182 ; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
183 ; LINUX-AVX512BW-NEXT:    vzeroupper
184 ; LINUX-AVX512BW-NEXT:    retq
185   tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
186   ret void
189 define void @test3_minsize_optsize(i8* nocapture %A, i8* nocapture %B) nounwind optsize minsize noredzone {
190 ; DARWIN-LABEL: test3_minsize_optsize:
191 ; DARWIN:       ## %bb.0:
192 ; DARWIN-NEXT:    pushq $64
193 ; DARWIN-NEXT:    popq %rdx
194 ; DARWIN-NEXT:    jmp _memcpy ## TAILCALL
196 ; LINUX-LABEL: test3_minsize_optsize:
197 ; LINUX:       # %bb.0:
198 ; LINUX-NEXT:    pushq $64
199 ; LINUX-NEXT:    popq %rdx
200 ; LINUX-NEXT:    jmp memcpy # TAILCALL
202 ; LINUX-SKL-LABEL: test3_minsize_optsize:
203 ; LINUX-SKL:       # %bb.0:
204 ; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
205 ; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
206 ; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
207 ; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
208 ; LINUX-SKL-NEXT:    vzeroupper
209 ; LINUX-SKL-NEXT:    retq
211 ; LINUX-SKX-LABEL: test3_minsize_optsize:
212 ; LINUX-SKX:       # %bb.0:
213 ; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
214 ; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
215 ; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
216 ; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
217 ; LINUX-SKX-NEXT:    vzeroupper
218 ; LINUX-SKX-NEXT:    retq
220 ; LINUX-KNL-LABEL: test3_minsize_optsize:
221 ; LINUX-KNL:       # %bb.0:
222 ; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
223 ; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
224 ; LINUX-KNL-NEXT:    retq
226 ; LINUX-AVX512BW-LABEL: test3_minsize_optsize:
227 ; LINUX-AVX512BW:       # %bb.0:
228 ; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
229 ; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
230 ; LINUX-AVX512BW-NEXT:    vzeroupper
231 ; LINUX-AVX512BW-NEXT:    retq
232   tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
233   ret void
236 ; Large constant memcpy's should be inlined when not optimizing for size.
237 define void @test4(i8* nocapture %A, i8* nocapture %B) nounwind noredzone {
238 ; DARWIN-LABEL: test4:
239 ; DARWIN:       ## %bb.0: ## %entry
240 ; DARWIN-NEXT:    movq 56(%rsi), %rax
241 ; DARWIN-NEXT:    movq %rax, 56(%rdi)
242 ; DARWIN-NEXT:    movq 48(%rsi), %rax
243 ; DARWIN-NEXT:    movq %rax, 48(%rdi)
244 ; DARWIN-NEXT:    movq 40(%rsi), %rax
245 ; DARWIN-NEXT:    movq %rax, 40(%rdi)
246 ; DARWIN-NEXT:    movq 32(%rsi), %rax
247 ; DARWIN-NEXT:    movq %rax, 32(%rdi)
248 ; DARWIN-NEXT:    movq 24(%rsi), %rax
249 ; DARWIN-NEXT:    movq %rax, 24(%rdi)
250 ; DARWIN-NEXT:    movq 16(%rsi), %rax
251 ; DARWIN-NEXT:    movq %rax, 16(%rdi)
252 ; DARWIN-NEXT:    movq (%rsi), %rax
253 ; DARWIN-NEXT:    movq 8(%rsi), %rcx
254 ; DARWIN-NEXT:    movq %rcx, 8(%rdi)
255 ; DARWIN-NEXT:    movq %rax, (%rdi)
256 ; DARWIN-NEXT:    retq
258 ; LINUX-LABEL: test4:
259 ; LINUX:       # %bb.0: # %entry
260 ; LINUX-NEXT:    movq 56(%rsi), %rax
261 ; LINUX-NEXT:    movq %rax, 56(%rdi)
262 ; LINUX-NEXT:    movq 48(%rsi), %rax
263 ; LINUX-NEXT:    movq %rax, 48(%rdi)
264 ; LINUX-NEXT:    movq 40(%rsi), %rax
265 ; LINUX-NEXT:    movq %rax, 40(%rdi)
266 ; LINUX-NEXT:    movq 32(%rsi), %rax
267 ; LINUX-NEXT:    movq %rax, 32(%rdi)
268 ; LINUX-NEXT:    movq 24(%rsi), %rax
269 ; LINUX-NEXT:    movq %rax, 24(%rdi)
270 ; LINUX-NEXT:    movq 16(%rsi), %rax
271 ; LINUX-NEXT:    movq %rax, 16(%rdi)
272 ; LINUX-NEXT:    movq (%rsi), %rax
273 ; LINUX-NEXT:    movq 8(%rsi), %rcx
274 ; LINUX-NEXT:    movq %rcx, 8(%rdi)
275 ; LINUX-NEXT:    movq %rax, (%rdi)
276 ; LINUX-NEXT:    retq
278 ; LINUX-SKL-LABEL: test4:
279 ; LINUX-SKL:       # %bb.0: # %entry
280 ; LINUX-SKL-NEXT:    vmovups (%rsi), %ymm0
281 ; LINUX-SKL-NEXT:    vmovups 32(%rsi), %ymm1
282 ; LINUX-SKL-NEXT:    vmovups %ymm1, 32(%rdi)
283 ; LINUX-SKL-NEXT:    vmovups %ymm0, (%rdi)
284 ; LINUX-SKL-NEXT:    vzeroupper
285 ; LINUX-SKL-NEXT:    retq
287 ; LINUX-SKX-LABEL: test4:
288 ; LINUX-SKX:       # %bb.0: # %entry
289 ; LINUX-SKX-NEXT:    vmovups (%rsi), %ymm0
290 ; LINUX-SKX-NEXT:    vmovups 32(%rsi), %ymm1
291 ; LINUX-SKX-NEXT:    vmovups %ymm1, 32(%rdi)
292 ; LINUX-SKX-NEXT:    vmovups %ymm0, (%rdi)
293 ; LINUX-SKX-NEXT:    vzeroupper
294 ; LINUX-SKX-NEXT:    retq
296 ; LINUX-KNL-LABEL: test4:
297 ; LINUX-KNL:       # %bb.0: # %entry
298 ; LINUX-KNL-NEXT:    vmovups (%rsi), %zmm0
299 ; LINUX-KNL-NEXT:    vmovups %zmm0, (%rdi)
300 ; LINUX-KNL-NEXT:    retq
302 ; LINUX-AVX512BW-LABEL: test4:
303 ; LINUX-AVX512BW:       # %bb.0: # %entry
304 ; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %zmm0
305 ; LINUX-AVX512BW-NEXT:    vmovups %zmm0, (%rdi)
306 ; LINUX-AVX512BW-NEXT:    vzeroupper
307 ; LINUX-AVX512BW-NEXT:    retq
308 entry:
309   tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i1 false)
310   ret void
314 @.str = private unnamed_addr constant [30 x i8] c"\00aaaaaaaaaaaaaaaaaaaaaaaaaaaa\00", align 1
316 define void @test5(i8* nocapture %C) nounwind uwtable ssp {
317 ; DARWIN-LABEL: test5:
318 ; DARWIN:       ## %bb.0: ## %entry
319 ; DARWIN-NEXT:    movabsq $7016996765293437281, %rax ## imm = 0x6161616161616161
320 ; DARWIN-NEXT:    movq %rax, 8(%rdi)
321 ; DARWIN-NEXT:    movabsq $7016996765293437184, %rax ## imm = 0x6161616161616100
322 ; DARWIN-NEXT:    movq %rax, (%rdi)
323 ; DARWIN-NEXT:    retq
325 ; LINUX-LABEL: test5:
326 ; LINUX:       # %bb.0: # %entry
327 ; LINUX-NEXT:    movabsq $7016996765293437281, %rax # imm = 0x6161616161616161
328 ; LINUX-NEXT:    movq %rax, 8(%rdi)
329 ; LINUX-NEXT:    movabsq $7016996765293437184, %rax # imm = 0x6161616161616100
330 ; LINUX-NEXT:    movq %rax, (%rdi)
331 ; LINUX-NEXT:    retq
333 ; LINUX-SKL-LABEL: test5:
334 ; LINUX-SKL:       # %bb.0: # %entry
335 ; LINUX-SKL-NEXT:    vmovups {{.*}}(%rip), %xmm0
336 ; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
337 ; LINUX-SKL-NEXT:    retq
339 ; LINUX-SKX-LABEL: test5:
340 ; LINUX-SKX:       # %bb.0: # %entry
341 ; LINUX-SKX-NEXT:    vmovups {{.*}}(%rip), %xmm0
342 ; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
343 ; LINUX-SKX-NEXT:    retq
345 ; LINUX-KNL-LABEL: test5:
346 ; LINUX-KNL:       # %bb.0: # %entry
347 ; LINUX-KNL-NEXT:    vmovups {{.*}}(%rip), %xmm0
348 ; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
349 ; LINUX-KNL-NEXT:    retq
351 ; LINUX-AVX512BW-LABEL: test5:
352 ; LINUX-AVX512BW:       # %bb.0: # %entry
353 ; LINUX-AVX512BW-NEXT:    vmovups {{.*}}(%rip), %xmm0
354 ; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
355 ; LINUX-AVX512BW-NEXT:    retq
356 entry:
357   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)
358   ret void
362 ; PR14896
363 @.str2 = private unnamed_addr constant [2 x i8] c"x\00", align 1
365 define void @test6() nounwind uwtable {
366 ; DARWIN-LABEL: test6:
367 ; DARWIN:       ## %bb.0: ## %entry
368 ; DARWIN-NEXT:    movw $0, 8
369 ; DARWIN-NEXT:    movq $120, 0
370 ; DARWIN-NEXT:    retq
372 ; LINUX-LABEL: test6:
373 ; LINUX:       # %bb.0: # %entry
374 ; LINUX-NEXT:    movw $0, 8
375 ; LINUX-NEXT:    movq $120, 0
376 ; LINUX-NEXT:    retq
378 ; LINUX-SKL-LABEL: test6:
379 ; LINUX-SKL:       # %bb.0: # %entry
380 ; LINUX-SKL-NEXT:    movw $0, 8
381 ; LINUX-SKL-NEXT:    movq $120, 0
382 ; LINUX-SKL-NEXT:    retq
384 ; LINUX-SKX-LABEL: test6:
385 ; LINUX-SKX:       # %bb.0: # %entry
386 ; LINUX-SKX-NEXT:    movw $0, 8
387 ; LINUX-SKX-NEXT:    movq $120, 0
388 ; LINUX-SKX-NEXT:    retq
390 ; LINUX-KNL-LABEL: test6:
391 ; LINUX-KNL:       # %bb.0: # %entry
392 ; LINUX-KNL-NEXT:    movw $0, 8
393 ; LINUX-KNL-NEXT:    movq $120, 0
394 ; LINUX-KNL-NEXT:    retq
396 ; LINUX-AVX512BW-LABEL: test6:
397 ; LINUX-AVX512BW:       # %bb.0: # %entry
398 ; LINUX-AVX512BW-NEXT:    movw $0, 8
399 ; LINUX-AVX512BW-NEXT:    movq $120, 0
400 ; LINUX-AVX512BW-NEXT:    retq
401 entry:
402   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)
403   ret void
406 define void @PR15348(i8* %a, i8* %b) {
407 ; Ensure that alignment of '0' in an @llvm.memcpy intrinsic results in
408 ; unaligned loads and stores.
409 ; DARWIN-LABEL: PR15348:
410 ; DARWIN:       ## %bb.0:
411 ; DARWIN-NEXT:    movb 16(%rsi), %al
412 ; DARWIN-NEXT:    movb %al, 16(%rdi)
413 ; DARWIN-NEXT:    movq (%rsi), %rax
414 ; DARWIN-NEXT:    movq 8(%rsi), %rcx
415 ; DARWIN-NEXT:    movq %rcx, 8(%rdi)
416 ; DARWIN-NEXT:    movq %rax, (%rdi)
417 ; DARWIN-NEXT:    retq
419 ; LINUX-LABEL: PR15348:
420 ; LINUX:       # %bb.0:
421 ; LINUX-NEXT:    movb 16(%rsi), %al
422 ; LINUX-NEXT:    movb %al, 16(%rdi)
423 ; LINUX-NEXT:    movq (%rsi), %rax
424 ; LINUX-NEXT:    movq 8(%rsi), %rcx
425 ; LINUX-NEXT:    movq %rcx, 8(%rdi)
426 ; LINUX-NEXT:    movq %rax, (%rdi)
427 ; LINUX-NEXT:    retq
429 ; LINUX-SKL-LABEL: PR15348:
430 ; LINUX-SKL:       # %bb.0:
431 ; LINUX-SKL-NEXT:    movb 16(%rsi), %al
432 ; LINUX-SKL-NEXT:    movb %al, 16(%rdi)
433 ; LINUX-SKL-NEXT:    vmovups (%rsi), %xmm0
434 ; LINUX-SKL-NEXT:    vmovups %xmm0, (%rdi)
435 ; LINUX-SKL-NEXT:    retq
437 ; LINUX-SKX-LABEL: PR15348:
438 ; LINUX-SKX:       # %bb.0:
439 ; LINUX-SKX-NEXT:    movb 16(%rsi), %al
440 ; LINUX-SKX-NEXT:    movb %al, 16(%rdi)
441 ; LINUX-SKX-NEXT:    vmovups (%rsi), %xmm0
442 ; LINUX-SKX-NEXT:    vmovups %xmm0, (%rdi)
443 ; LINUX-SKX-NEXT:    retq
445 ; LINUX-KNL-LABEL: PR15348:
446 ; LINUX-KNL:       # %bb.0:
447 ; LINUX-KNL-NEXT:    movb 16(%rsi), %al
448 ; LINUX-KNL-NEXT:    movb %al, 16(%rdi)
449 ; LINUX-KNL-NEXT:    vmovups (%rsi), %xmm0
450 ; LINUX-KNL-NEXT:    vmovups %xmm0, (%rdi)
451 ; LINUX-KNL-NEXT:    retq
453 ; LINUX-AVX512BW-LABEL: PR15348:
454 ; LINUX-AVX512BW:       # %bb.0:
455 ; LINUX-AVX512BW-NEXT:    movb 16(%rsi), %al
456 ; LINUX-AVX512BW-NEXT:    movb %al, 16(%rdi)
457 ; LINUX-AVX512BW-NEXT:    vmovups (%rsi), %xmm0
458 ; LINUX-AVX512BW-NEXT:    vmovups %xmm0, (%rdi)
459 ; LINUX-AVX512BW-NEXT:    retq
460   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 17, i1 false)
461   ret void
464 ; Memcpys from / to address space 256 should be lowered to appropriate loads /
465 ; stores if small enough.
466 define void @addrspace256(i8 addrspace(256)* %a, i8 addrspace(256)* %b) nounwind {
467 ; DARWIN-LABEL: addrspace256:
468 ; DARWIN:       ## %bb.0:
469 ; DARWIN-NEXT:    movq %gs:(%rsi), %rax
470 ; DARWIN-NEXT:    movq %gs:8(%rsi), %rcx
471 ; DARWIN-NEXT:    movq %rcx, %gs:8(%rdi)
472 ; DARWIN-NEXT:    movq %rax, %gs:(%rdi)
473 ; DARWIN-NEXT:    retq
475 ; LINUX-LABEL: addrspace256:
476 ; LINUX:       # %bb.0:
477 ; LINUX-NEXT:    movq %gs:(%rsi), %rax
478 ; LINUX-NEXT:    movq %gs:8(%rsi), %rcx
479 ; LINUX-NEXT:    movq %rcx, %gs:8(%rdi)
480 ; LINUX-NEXT:    movq %rax, %gs:(%rdi)
481 ; LINUX-NEXT:    retq
483 ; LINUX-SKL-LABEL: addrspace256:
484 ; LINUX-SKL:       # %bb.0:
485 ; LINUX-SKL-NEXT:    vmovups %gs:(%rsi), %xmm0
486 ; LINUX-SKL-NEXT:    vmovups %xmm0, %gs:(%rdi)
487 ; LINUX-SKL-NEXT:    retq
489 ; LINUX-SKX-LABEL: addrspace256:
490 ; LINUX-SKX:       # %bb.0:
491 ; LINUX-SKX-NEXT:    vmovups %gs:(%rsi), %xmm0
492 ; LINUX-SKX-NEXT:    vmovups %xmm0, %gs:(%rdi)
493 ; LINUX-SKX-NEXT:    retq
495 ; LINUX-KNL-LABEL: addrspace256:
496 ; LINUX-KNL:       # %bb.0:
497 ; LINUX-KNL-NEXT:    vmovups %gs:(%rsi), %xmm0
498 ; LINUX-KNL-NEXT:    vmovups %xmm0, %gs:(%rdi)
499 ; LINUX-KNL-NEXT:    retq
501 ; LINUX-AVX512BW-LABEL: addrspace256:
502 ; LINUX-AVX512BW:       # %bb.0:
503 ; LINUX-AVX512BW-NEXT:    vmovups %gs:(%rsi), %xmm0
504 ; LINUX-AVX512BW-NEXT:    vmovups %xmm0, %gs:(%rdi)
505 ; LINUX-AVX512BW-NEXT:    retq
506   tail call void @llvm.memcpy.p256i8.p256i8.i64(i8 addrspace(256)* align 8 %a, i8 addrspace(256)* align 8 %b, i64 16, i1 false)
507   ret void