1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=cmov | FileCheck %s --check-prefix=X86 --check-prefix=X86-NOSSE 3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE2 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 --check-prefix=X64-SSE2 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX1 6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx2 | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX2 7 8; This tests codegen time inlining/optimization of memcmp 9; rdar://6480398 10 11@.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1 12 13declare dso_local i32 @memcmp(i8*, i8*, i64) 14 15define i32 @length2(i8* %X, i8* %Y) nounwind minsize { 16; X86-LABEL: length2: 17; X86: # %bb.0: 18; X86-NEXT: pushl $0 19; X86-NEXT: pushl $2 20; X86-NEXT: pushl {{[0-9]+}}(%esp) 21; X86-NEXT: pushl {{[0-9]+}}(%esp) 22; X86-NEXT: calll memcmp 23; X86-NEXT: addl $16, %esp 24; X86-NEXT: retl 25; 26; X64-LABEL: length2: 27; X64: # %bb.0: 28; X64-NEXT: pushq $2 29; X64-NEXT: popq %rdx 30; X64-NEXT: jmp memcmp # TAILCALL 31 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 32 ret i32 %m 33} 34 35define i1 @length2_eq(i8* %X, i8* %Y) nounwind minsize { 36; X86-LABEL: length2_eq: 37; X86: # %bb.0: 38; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 39; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 40; X86-NEXT: movzwl (%ecx), %ecx 41; X86-NEXT: cmpw (%eax), %cx 42; X86-NEXT: sete %al 43; X86-NEXT: retl 44; 45; X64-LABEL: length2_eq: 46; X64: # %bb.0: 47; X64-NEXT: movzwl (%rdi), %eax 48; X64-NEXT: cmpw (%rsi), %ax 49; X64-NEXT: sete %al 50; X64-NEXT: retq 51 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 52 %c = icmp eq i32 %m, 0 53 ret i1 %c 54} 55 56define i1 @length2_eq_const(i8* %X) nounwind minsize { 57; X86-LABEL: length2_eq_const: 58; X86: # %bb.0: 59; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 60; X86-NEXT: cmpw $12849, (%eax) # imm = 0x3231 61; X86-NEXT: setne %al 62; X86-NEXT: retl 63; 64; X64-LABEL: length2_eq_const: 65; X64: # %bb.0: 66; X64-NEXT: cmpw $12849, (%rdi) # imm = 0x3231 67; X64-NEXT: setne %al 68; X64-NEXT: retq 69 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind 70 %c = icmp ne i32 %m, 0 71 ret i1 %c 72} 73 74define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind minsize { 75; X86-LABEL: length2_eq_nobuiltin_attr: 76; X86: # %bb.0: 77; X86-NEXT: pushl $0 78; X86-NEXT: pushl $2 79; X86-NEXT: pushl {{[0-9]+}}(%esp) 80; X86-NEXT: pushl {{[0-9]+}}(%esp) 81; X86-NEXT: calll memcmp 82; X86-NEXT: addl $16, %esp 83; X86-NEXT: testl %eax, %eax 84; X86-NEXT: sete %al 85; X86-NEXT: retl 86; 87; X64-LABEL: length2_eq_nobuiltin_attr: 88; X64: # %bb.0: 89; X64-NEXT: pushq %rax 90; X64-NEXT: pushq $2 91; X64-NEXT: popq %rdx 92; X64-NEXT: callq memcmp 93; X64-NEXT: testl %eax, %eax 94; X64-NEXT: sete %al 95; X64-NEXT: popq %rcx 96; X64-NEXT: retq 97 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin 98 %c = icmp eq i32 %m, 0 99 ret i1 %c 100} 101 102define i32 @length3(i8* %X, i8* %Y) nounwind minsize { 103; X86-LABEL: length3: 104; X86: # %bb.0: 105; X86-NEXT: pushl $0 106; X86-NEXT: pushl $3 107; X86-NEXT: pushl {{[0-9]+}}(%esp) 108; X86-NEXT: pushl {{[0-9]+}}(%esp) 109; X86-NEXT: calll memcmp 110; X86-NEXT: addl $16, %esp 111; X86-NEXT: retl 112; 113; X64-LABEL: length3: 114; X64: # %bb.0: 115; X64-NEXT: pushq $3 116; X64-NEXT: popq %rdx 117; X64-NEXT: jmp memcmp # TAILCALL 118 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 119 ret i32 %m 120} 121 122define i1 @length3_eq(i8* %X, i8* %Y) nounwind minsize { 123; X86-LABEL: length3_eq: 124; X86: # %bb.0: 125; X86-NEXT: pushl $0 126; X86-NEXT: pushl $3 127; X86-NEXT: pushl {{[0-9]+}}(%esp) 128; X86-NEXT: pushl {{[0-9]+}}(%esp) 129; X86-NEXT: calll memcmp 130; X86-NEXT: addl $16, %esp 131; X86-NEXT: testl %eax, %eax 132; X86-NEXT: setne %al 133; X86-NEXT: retl 134; 135; X64-LABEL: length3_eq: 136; X64: # %bb.0: 137; X64-NEXT: pushq %rax 138; X64-NEXT: pushq $3 139; X64-NEXT: popq %rdx 140; X64-NEXT: callq memcmp 141; X64-NEXT: testl %eax, %eax 142; X64-NEXT: setne %al 143; X64-NEXT: popq %rcx 144; X64-NEXT: retq 145 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 146 %c = icmp ne i32 %m, 0 147 ret i1 %c 148} 149 150define i32 @length4(i8* %X, i8* %Y) nounwind minsize { 151; X86-LABEL: length4: 152; X86: # %bb.0: 153; X86-NEXT: pushl $0 154; X86-NEXT: pushl $4 155; X86-NEXT: pushl {{[0-9]+}}(%esp) 156; X86-NEXT: pushl {{[0-9]+}}(%esp) 157; X86-NEXT: calll memcmp 158; X86-NEXT: addl $16, %esp 159; X86-NEXT: retl 160; 161; X64-LABEL: length4: 162; X64: # %bb.0: 163; X64-NEXT: pushq $4 164; X64-NEXT: popq %rdx 165; X64-NEXT: jmp memcmp # TAILCALL 166 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 167 ret i32 %m 168} 169 170define i1 @length4_eq(i8* %X, i8* %Y) nounwind minsize { 171; X86-LABEL: length4_eq: 172; X86: # %bb.0: 173; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 174; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 175; X86-NEXT: movl (%ecx), %ecx 176; X86-NEXT: cmpl (%eax), %ecx 177; X86-NEXT: setne %al 178; X86-NEXT: retl 179; 180; X64-LABEL: length4_eq: 181; X64: # %bb.0: 182; X64-NEXT: movl (%rdi), %eax 183; X64-NEXT: cmpl (%rsi), %eax 184; X64-NEXT: setne %al 185; X64-NEXT: retq 186 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 187 %c = icmp ne i32 %m, 0 188 ret i1 %c 189} 190 191define i1 @length4_eq_const(i8* %X) nounwind minsize { 192; X86-LABEL: length4_eq_const: 193; X86: # %bb.0: 194; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 195; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231 196; X86-NEXT: sete %al 197; X86-NEXT: retl 198; 199; X64-LABEL: length4_eq_const: 200; X64: # %bb.0: 201; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231 202; X64-NEXT: sete %al 203; X64-NEXT: retq 204 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind 205 %c = icmp eq i32 %m, 0 206 ret i1 %c 207} 208 209define i32 @length5(i8* %X, i8* %Y) nounwind minsize { 210; X86-LABEL: length5: 211; X86: # %bb.0: 212; X86-NEXT: pushl $0 213; X86-NEXT: pushl $5 214; X86-NEXT: pushl {{[0-9]+}}(%esp) 215; X86-NEXT: pushl {{[0-9]+}}(%esp) 216; X86-NEXT: calll memcmp 217; X86-NEXT: addl $16, %esp 218; X86-NEXT: retl 219; 220; X64-LABEL: length5: 221; X64: # %bb.0: 222; X64-NEXT: pushq $5 223; X64-NEXT: popq %rdx 224; X64-NEXT: jmp memcmp # TAILCALL 225 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 226 ret i32 %m 227} 228 229define i1 @length5_eq(i8* %X, i8* %Y) nounwind minsize { 230; X86-LABEL: length5_eq: 231; X86: # %bb.0: 232; X86-NEXT: pushl $0 233; X86-NEXT: pushl $5 234; X86-NEXT: pushl {{[0-9]+}}(%esp) 235; X86-NEXT: pushl {{[0-9]+}}(%esp) 236; X86-NEXT: calll memcmp 237; X86-NEXT: addl $16, %esp 238; X86-NEXT: testl %eax, %eax 239; X86-NEXT: setne %al 240; X86-NEXT: retl 241; 242; X64-LABEL: length5_eq: 243; X64: # %bb.0: 244; X64-NEXT: pushq %rax 245; X64-NEXT: pushq $5 246; X64-NEXT: popq %rdx 247; X64-NEXT: callq memcmp 248; X64-NEXT: testl %eax, %eax 249; X64-NEXT: setne %al 250; X64-NEXT: popq %rcx 251; X64-NEXT: retq 252 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 253 %c = icmp ne i32 %m, 0 254 ret i1 %c 255} 256 257define i32 @length8(i8* %X, i8* %Y) nounwind minsize { 258; X86-LABEL: length8: 259; X86: # %bb.0: 260; X86-NEXT: pushl $0 261; X86-NEXT: pushl $8 262; X86-NEXT: pushl {{[0-9]+}}(%esp) 263; X86-NEXT: pushl {{[0-9]+}}(%esp) 264; X86-NEXT: calll memcmp 265; X86-NEXT: addl $16, %esp 266; X86-NEXT: retl 267; 268; X64-LABEL: length8: 269; X64: # %bb.0: 270; X64-NEXT: pushq $8 271; X64-NEXT: popq %rdx 272; X64-NEXT: jmp memcmp # TAILCALL 273 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 274 ret i32 %m 275} 276 277define i1 @length8_eq(i8* %X, i8* %Y) nounwind minsize { 278; X86-LABEL: length8_eq: 279; X86: # %bb.0: 280; X86-NEXT: pushl $0 281; X86-NEXT: pushl $8 282; X86-NEXT: pushl {{[0-9]+}}(%esp) 283; X86-NEXT: pushl {{[0-9]+}}(%esp) 284; X86-NEXT: calll memcmp 285; X86-NEXT: addl $16, %esp 286; X86-NEXT: testl %eax, %eax 287; X86-NEXT: sete %al 288; X86-NEXT: retl 289; 290; X64-LABEL: length8_eq: 291; X64: # %bb.0: 292; X64-NEXT: movq (%rdi), %rax 293; X64-NEXT: cmpq (%rsi), %rax 294; X64-NEXT: sete %al 295; X64-NEXT: retq 296 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 297 %c = icmp eq i32 %m, 0 298 ret i1 %c 299} 300 301define i1 @length8_eq_const(i8* %X) nounwind minsize { 302; X86-LABEL: length8_eq_const: 303; X86: # %bb.0: 304; X86-NEXT: pushl $0 305; X86-NEXT: pushl $8 306; X86-NEXT: pushl $.L.str 307; X86-NEXT: pushl {{[0-9]+}}(%esp) 308; X86-NEXT: calll memcmp 309; X86-NEXT: addl $16, %esp 310; X86-NEXT: testl %eax, %eax 311; X86-NEXT: setne %al 312; X86-NEXT: retl 313; 314; X64-LABEL: length8_eq_const: 315; X64: # %bb.0: 316; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130 317; X64-NEXT: cmpq %rax, (%rdi) 318; X64-NEXT: setne %al 319; X64-NEXT: retq 320 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind 321 %c = icmp ne i32 %m, 0 322 ret i1 %c 323} 324 325define i1 @length12_eq(i8* %X, i8* %Y) nounwind minsize { 326; X86-LABEL: length12_eq: 327; X86: # %bb.0: 328; X86-NEXT: pushl $0 329; X86-NEXT: pushl $12 330; X86-NEXT: pushl {{[0-9]+}}(%esp) 331; X86-NEXT: pushl {{[0-9]+}}(%esp) 332; X86-NEXT: calll memcmp 333; X86-NEXT: addl $16, %esp 334; X86-NEXT: testl %eax, %eax 335; X86-NEXT: setne %al 336; X86-NEXT: retl 337; 338; X64-LABEL: length12_eq: 339; X64: # %bb.0: 340; X64-NEXT: pushq %rax 341; X64-NEXT: pushq $12 342; X64-NEXT: popq %rdx 343; X64-NEXT: callq memcmp 344; X64-NEXT: testl %eax, %eax 345; X64-NEXT: setne %al 346; X64-NEXT: popq %rcx 347; X64-NEXT: retq 348 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 349 %c = icmp ne i32 %m, 0 350 ret i1 %c 351} 352 353define i32 @length12(i8* %X, i8* %Y) nounwind minsize { 354; X86-LABEL: length12: 355; X86: # %bb.0: 356; X86-NEXT: pushl $0 357; X86-NEXT: pushl $12 358; X86-NEXT: pushl {{[0-9]+}}(%esp) 359; X86-NEXT: pushl {{[0-9]+}}(%esp) 360; X86-NEXT: calll memcmp 361; X86-NEXT: addl $16, %esp 362; X86-NEXT: retl 363; 364; X64-LABEL: length12: 365; X64: # %bb.0: 366; X64-NEXT: pushq $12 367; X64-NEXT: popq %rdx 368; X64-NEXT: jmp memcmp # TAILCALL 369 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 370 ret i32 %m 371} 372 373; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329 374 375define i32 @length16(i8* %X, i8* %Y) nounwind minsize { 376; X86-LABEL: length16: 377; X86: # %bb.0: 378; X86-NEXT: pushl $0 379; X86-NEXT: pushl $16 380; X86-NEXT: pushl {{[0-9]+}}(%esp) 381; X86-NEXT: pushl {{[0-9]+}}(%esp) 382; X86-NEXT: calll memcmp 383; X86-NEXT: addl $16, %esp 384; X86-NEXT: retl 385; 386; X64-LABEL: length16: 387; X64: # %bb.0: 388; X64-NEXT: pushq $16 389; X64-NEXT: popq %rdx 390; X64-NEXT: jmp memcmp # TAILCALL 391 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind 392 ret i32 %m 393} 394 395define i1 @length16_eq(i8* %x, i8* %y) nounwind minsize { 396; X86-NOSSE-LABEL: length16_eq: 397; X86-NOSSE: # %bb.0: 398; X86-NOSSE-NEXT: pushl $0 399; X86-NOSSE-NEXT: pushl $16 400; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 401; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 402; X86-NOSSE-NEXT: calll memcmp 403; X86-NOSSE-NEXT: addl $16, %esp 404; X86-NOSSE-NEXT: testl %eax, %eax 405; X86-NOSSE-NEXT: setne %al 406; X86-NOSSE-NEXT: retl 407; 408; X86-SSE2-LABEL: length16_eq: 409; X86-SSE2: # %bb.0: 410; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 411; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 412; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 413; X86-SSE2-NEXT: movdqu (%eax), %xmm1 414; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 415; X86-SSE2-NEXT: pmovmskb %xmm1, %eax 416; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 417; X86-SSE2-NEXT: setne %al 418; X86-SSE2-NEXT: retl 419; 420; X64-SSE2-LABEL: length16_eq: 421; X64-SSE2: # %bb.0: 422; X64-SSE2-NEXT: movdqu (%rsi), %xmm0 423; X64-SSE2-NEXT: movdqu (%rdi), %xmm1 424; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 425; X64-SSE2-NEXT: pmovmskb %xmm1, %eax 426; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 427; X64-SSE2-NEXT: setne %al 428; X64-SSE2-NEXT: retq 429; 430; X64-AVX-LABEL: length16_eq: 431; X64-AVX: # %bb.0: 432; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 433; X64-AVX-NEXT: vpxor (%rsi), %xmm0, %xmm0 434; X64-AVX-NEXT: vptest %xmm0, %xmm0 435; X64-AVX-NEXT: setne %al 436; X64-AVX-NEXT: retq 437 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind 438 %cmp = icmp ne i32 %call, 0 439 ret i1 %cmp 440} 441 442define i1 @length16_eq_const(i8* %X) nounwind minsize { 443; X86-NOSSE-LABEL: length16_eq_const: 444; X86-NOSSE: # %bb.0: 445; X86-NOSSE-NEXT: pushl $0 446; X86-NOSSE-NEXT: pushl $16 447; X86-NOSSE-NEXT: pushl $.L.str 448; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 449; X86-NOSSE-NEXT: calll memcmp 450; X86-NOSSE-NEXT: addl $16, %esp 451; X86-NOSSE-NEXT: testl %eax, %eax 452; X86-NOSSE-NEXT: sete %al 453; X86-NOSSE-NEXT: retl 454; 455; X86-SSE2-LABEL: length16_eq_const: 456; X86-SSE2: # %bb.0: 457; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 458; X86-SSE2-NEXT: movdqu (%eax), %xmm0 459; X86-SSE2-NEXT: pcmpeqb {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 460; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 461; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 462; X86-SSE2-NEXT: sete %al 463; X86-SSE2-NEXT: retl 464; 465; X64-SSE2-LABEL: length16_eq_const: 466; X64-SSE2: # %bb.0: 467; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 468; X64-SSE2-NEXT: pcmpeqb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 469; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 470; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 471; X64-SSE2-NEXT: sete %al 472; X64-SSE2-NEXT: retq 473; 474; X64-AVX-LABEL: length16_eq_const: 475; X64-AVX: # %bb.0: 476; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 477; X64-AVX-NEXT: vpxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 478; X64-AVX-NEXT: vptest %xmm0, %xmm0 479; X64-AVX-NEXT: sete %al 480; X64-AVX-NEXT: retq 481 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind 482 %c = icmp eq i32 %m, 0 483 ret i1 %c 484} 485 486; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914 487 488define i32 @length24(i8* %X, i8* %Y) nounwind minsize { 489; X86-LABEL: length24: 490; X86: # %bb.0: 491; X86-NEXT: pushl $0 492; X86-NEXT: pushl $24 493; X86-NEXT: pushl {{[0-9]+}}(%esp) 494; X86-NEXT: pushl {{[0-9]+}}(%esp) 495; X86-NEXT: calll memcmp 496; X86-NEXT: addl $16, %esp 497; X86-NEXT: retl 498; 499; X64-LABEL: length24: 500; X64: # %bb.0: 501; X64-NEXT: pushq $24 502; X64-NEXT: popq %rdx 503; X64-NEXT: jmp memcmp # TAILCALL 504 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind 505 ret i32 %m 506} 507 508define i1 @length24_eq(i8* %x, i8* %y) nounwind minsize { 509; X86-LABEL: length24_eq: 510; X86: # %bb.0: 511; X86-NEXT: pushl $0 512; X86-NEXT: pushl $24 513; X86-NEXT: pushl {{[0-9]+}}(%esp) 514; X86-NEXT: pushl {{[0-9]+}}(%esp) 515; X86-NEXT: calll memcmp 516; X86-NEXT: addl $16, %esp 517; X86-NEXT: testl %eax, %eax 518; X86-NEXT: sete %al 519; X86-NEXT: retl 520; 521; X64-LABEL: length24_eq: 522; X64: # %bb.0: 523; X64-NEXT: pushq %rax 524; X64-NEXT: pushq $24 525; X64-NEXT: popq %rdx 526; X64-NEXT: callq memcmp 527; X64-NEXT: testl %eax, %eax 528; X64-NEXT: sete %al 529; X64-NEXT: popq %rcx 530; X64-NEXT: retq 531 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind 532 %cmp = icmp eq i32 %call, 0 533 ret i1 %cmp 534} 535 536define i1 @length24_eq_const(i8* %X) nounwind minsize { 537; X86-LABEL: length24_eq_const: 538; X86: # %bb.0: 539; X86-NEXT: pushl $0 540; X86-NEXT: pushl $24 541; X86-NEXT: pushl $.L.str 542; X86-NEXT: pushl {{[0-9]+}}(%esp) 543; X86-NEXT: calll memcmp 544; X86-NEXT: addl $16, %esp 545; X86-NEXT: testl %eax, %eax 546; X86-NEXT: setne %al 547; X86-NEXT: retl 548; 549; X64-LABEL: length24_eq_const: 550; X64: # %bb.0: 551; X64-NEXT: pushq %rax 552; X64-NEXT: pushq $24 553; X64-NEXT: popq %rdx 554; X64-NEXT: movl $.L.str, %esi 555; X64-NEXT: callq memcmp 556; X64-NEXT: testl %eax, %eax 557; X64-NEXT: setne %al 558; X64-NEXT: popq %rcx 559; X64-NEXT: retq 560 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind 561 %c = icmp ne i32 %m, 0 562 ret i1 %c 563} 564 565define i32 @length32(i8* %X, i8* %Y) nounwind minsize { 566; X86-LABEL: length32: 567; X86: # %bb.0: 568; X86-NEXT: pushl $0 569; X86-NEXT: pushl $32 570; X86-NEXT: pushl {{[0-9]+}}(%esp) 571; X86-NEXT: pushl {{[0-9]+}}(%esp) 572; X86-NEXT: calll memcmp 573; X86-NEXT: addl $16, %esp 574; X86-NEXT: retl 575; 576; X64-LABEL: length32: 577; X64: # %bb.0: 578; X64-NEXT: pushq $32 579; X64-NEXT: popq %rdx 580; X64-NEXT: jmp memcmp # TAILCALL 581 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind 582 ret i32 %m 583} 584 585; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 586 587define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize { 588; X86-LABEL: length32_eq: 589; X86: # %bb.0: 590; X86-NEXT: pushl $0 591; X86-NEXT: pushl $32 592; X86-NEXT: pushl {{[0-9]+}}(%esp) 593; X86-NEXT: pushl {{[0-9]+}}(%esp) 594; X86-NEXT: calll memcmp 595; X86-NEXT: addl $16, %esp 596; X86-NEXT: testl %eax, %eax 597; X86-NEXT: sete %al 598; X86-NEXT: retl 599; 600; X64-SSE2-LABEL: length32_eq: 601; X64-SSE2: # %bb.0: 602; X64-SSE2-NEXT: pushq %rax 603; X64-SSE2-NEXT: pushq $32 604; X64-SSE2-NEXT: popq %rdx 605; X64-SSE2-NEXT: callq memcmp 606; X64-SSE2-NEXT: testl %eax, %eax 607; X64-SSE2-NEXT: sete %al 608; X64-SSE2-NEXT: popq %rcx 609; X64-SSE2-NEXT: retq 610; 611; X64-AVX1-LABEL: length32_eq: 612; X64-AVX1: # %bb.0: 613; X64-AVX1-NEXT: vmovups (%rdi), %ymm0 614; X64-AVX1-NEXT: vxorps (%rsi), %ymm0, %ymm0 615; X64-AVX1-NEXT: vptest %ymm0, %ymm0 616; X64-AVX1-NEXT: sete %al 617; X64-AVX1-NEXT: vzeroupper 618; X64-AVX1-NEXT: retq 619; 620; X64-AVX2-LABEL: length32_eq: 621; X64-AVX2: # %bb.0: 622; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 623; X64-AVX2-NEXT: vpxor (%rsi), %ymm0, %ymm0 624; X64-AVX2-NEXT: vptest %ymm0, %ymm0 625; X64-AVX2-NEXT: sete %al 626; X64-AVX2-NEXT: vzeroupper 627; X64-AVX2-NEXT: retq 628 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind 629 %cmp = icmp eq i32 %call, 0 630 ret i1 %cmp 631} 632 633define i1 @length32_eq_const(i8* %X) nounwind minsize { 634; X86-LABEL: length32_eq_const: 635; X86: # %bb.0: 636; X86-NEXT: pushl $0 637; X86-NEXT: pushl $32 638; X86-NEXT: pushl $.L.str 639; X86-NEXT: pushl {{[0-9]+}}(%esp) 640; X86-NEXT: calll memcmp 641; X86-NEXT: addl $16, %esp 642; X86-NEXT: testl %eax, %eax 643; X86-NEXT: setne %al 644; X86-NEXT: retl 645; 646; X64-SSE2-LABEL: length32_eq_const: 647; X64-SSE2: # %bb.0: 648; X64-SSE2-NEXT: pushq %rax 649; X64-SSE2-NEXT: pushq $32 650; X64-SSE2-NEXT: popq %rdx 651; X64-SSE2-NEXT: movl $.L.str, %esi 652; X64-SSE2-NEXT: callq memcmp 653; X64-SSE2-NEXT: testl %eax, %eax 654; X64-SSE2-NEXT: setne %al 655; X64-SSE2-NEXT: popq %rcx 656; X64-SSE2-NEXT: retq 657; 658; X64-AVX1-LABEL: length32_eq_const: 659; X64-AVX1: # %bb.0: 660; X64-AVX1-NEXT: vmovups (%rdi), %ymm0 661; X64-AVX1-NEXT: vxorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 662; X64-AVX1-NEXT: vptest %ymm0, %ymm0 663; X64-AVX1-NEXT: setne %al 664; X64-AVX1-NEXT: vzeroupper 665; X64-AVX1-NEXT: retq 666; 667; X64-AVX2-LABEL: length32_eq_const: 668; X64-AVX2: # %bb.0: 669; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 670; X64-AVX2-NEXT: vpxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 671; X64-AVX2-NEXT: vptest %ymm0, %ymm0 672; X64-AVX2-NEXT: setne %al 673; X64-AVX2-NEXT: vzeroupper 674; X64-AVX2-NEXT: retq 675 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind 676 %c = icmp ne i32 %m, 0 677 ret i1 %c 678} 679 680define i32 @length64(i8* %X, i8* %Y) nounwind minsize { 681; X86-LABEL: length64: 682; X86: # %bb.0: 683; X86-NEXT: pushl $0 684; X86-NEXT: pushl $64 685; X86-NEXT: pushl {{[0-9]+}}(%esp) 686; X86-NEXT: pushl {{[0-9]+}}(%esp) 687; X86-NEXT: calll memcmp 688; X86-NEXT: addl $16, %esp 689; X86-NEXT: retl 690; 691; X64-LABEL: length64: 692; X64: # %bb.0: 693; X64-NEXT: pushq $64 694; X64-NEXT: popq %rdx 695; X64-NEXT: jmp memcmp # TAILCALL 696 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind 697 ret i32 %m 698} 699 700define i1 @length64_eq(i8* %x, i8* %y) nounwind minsize { 701; X86-LABEL: length64_eq: 702; X86: # %bb.0: 703; X86-NEXT: pushl $0 704; X86-NEXT: pushl $64 705; X86-NEXT: pushl {{[0-9]+}}(%esp) 706; X86-NEXT: pushl {{[0-9]+}}(%esp) 707; X86-NEXT: calll memcmp 708; X86-NEXT: addl $16, %esp 709; X86-NEXT: testl %eax, %eax 710; X86-NEXT: setne %al 711; X86-NEXT: retl 712; 713; X64-LABEL: length64_eq: 714; X64: # %bb.0: 715; X64-NEXT: pushq %rax 716; X64-NEXT: pushq $64 717; X64-NEXT: popq %rdx 718; X64-NEXT: callq memcmp 719; X64-NEXT: testl %eax, %eax 720; X64-NEXT: setne %al 721; X64-NEXT: popq %rcx 722; X64-NEXT: retq 723 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind 724 %cmp = icmp ne i32 %call, 0 725 ret i1 %cmp 726} 727 728define i1 @length64_eq_const(i8* %X) nounwind minsize { 729; X86-LABEL: length64_eq_const: 730; X86: # %bb.0: 731; X86-NEXT: pushl $0 732; X86-NEXT: pushl $64 733; X86-NEXT: pushl $.L.str 734; X86-NEXT: pushl {{[0-9]+}}(%esp) 735; X86-NEXT: calll memcmp 736; X86-NEXT: addl $16, %esp 737; X86-NEXT: testl %eax, %eax 738; X86-NEXT: sete %al 739; X86-NEXT: retl 740; 741; X64-LABEL: length64_eq_const: 742; X64: # %bb.0: 743; X64-NEXT: pushq %rax 744; X64-NEXT: pushq $64 745; X64-NEXT: popq %rdx 746; X64-NEXT: movl $.L.str, %esi 747; X64-NEXT: callq memcmp 748; X64-NEXT: testl %eax, %eax 749; X64-NEXT: sete %al 750; X64-NEXT: popq %rcx 751; X64-NEXT: retq 752 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind 753 %c = icmp eq i32 %m, 0 754 ret i1 %c 755} 756 757