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