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=+sse | FileCheck %s --check-prefix=X86 --check-prefix=SSE --check-prefix=X86-SSE1 4; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=SSE --check-prefix=X86-SSE2 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 --check-prefix=X64-SSE2 6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX1 7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx2 | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX2 8 9; This tests codegen time inlining/optimization of memcmp 10; rdar://6480398 11 12@.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1 13 14declare i32 @memcmp(i8*, i8*, i64) 15 16define i32 @length0(i8* %X, i8* %Y) nounwind { 17; X86-LABEL: length0: 18; X86: # %bb.0: 19; X86-NEXT: xorl %eax, %eax 20; X86-NEXT: retl 21; 22; X64-LABEL: length0: 23; X64: # %bb.0: 24; X64-NEXT: xorl %eax, %eax 25; X64-NEXT: retq 26 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 0) nounwind 27 ret i32 %m 28 } 29 30define i1 @length0_eq(i8* %X, i8* %Y) nounwind { 31; X86-LABEL: length0_eq: 32; X86: # %bb.0: 33; X86-NEXT: movb $1, %al 34; X86-NEXT: retl 35; 36; X64-LABEL: length0_eq: 37; X64: # %bb.0: 38; X64-NEXT: movb $1, %al 39; X64-NEXT: retq 40 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 0) nounwind 41 %c = icmp eq i32 %m, 0 42 ret i1 %c 43} 44 45define i32 @length2(i8* %X, i8* %Y) nounwind { 46; X86-LABEL: length2: 47; X86: # %bb.0: 48; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 49; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 50; X86-NEXT: movzwl (%ecx), %ecx 51; X86-NEXT: movzwl (%eax), %edx 52; X86-NEXT: rolw $8, %cx 53; X86-NEXT: rolw $8, %dx 54; X86-NEXT: movzwl %cx, %eax 55; X86-NEXT: movzwl %dx, %ecx 56; X86-NEXT: subl %ecx, %eax 57; X86-NEXT: retl 58; 59; X64-LABEL: length2: 60; X64: # %bb.0: 61; X64-NEXT: movzwl (%rdi), %eax 62; X64-NEXT: movzwl (%rsi), %ecx 63; X64-NEXT: rolw $8, %ax 64; X64-NEXT: rolw $8, %cx 65; X64-NEXT: movzwl %ax, %eax 66; X64-NEXT: movzwl %cx, %ecx 67; X64-NEXT: subl %ecx, %eax 68; X64-NEXT: retq 69 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 70 ret i32 %m 71} 72 73define i1 @length2_eq(i8* %X, i8* %Y) nounwind { 74; X86-LABEL: length2_eq: 75; X86: # %bb.0: 76; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 77; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 78; X86-NEXT: movzwl (%ecx), %ecx 79; X86-NEXT: cmpw (%eax), %cx 80; X86-NEXT: sete %al 81; X86-NEXT: retl 82; 83; X64-LABEL: length2_eq: 84; X64: # %bb.0: 85; X64-NEXT: movzwl (%rdi), %eax 86; X64-NEXT: cmpw (%rsi), %ax 87; X64-NEXT: sete %al 88; X64-NEXT: retq 89 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 90 %c = icmp eq i32 %m, 0 91 ret i1 %c 92} 93 94define i1 @length2_eq_const(i8* %X) nounwind { 95; X86-LABEL: length2_eq_const: 96; X86: # %bb.0: 97; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 98; X86-NEXT: movzwl (%eax), %eax 99; X86-NEXT: cmpl $12849, %eax # imm = 0x3231 100; X86-NEXT: setne %al 101; X86-NEXT: retl 102; 103; X64-LABEL: length2_eq_const: 104; X64: # %bb.0: 105; X64-NEXT: movzwl (%rdi), %eax 106; X64-NEXT: cmpl $12849, %eax # imm = 0x3231 107; X64-NEXT: setne %al 108; X64-NEXT: retq 109 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind 110 %c = icmp ne i32 %m, 0 111 ret i1 %c 112} 113 114define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind { 115; X86-LABEL: length2_eq_nobuiltin_attr: 116; X86: # %bb.0: 117; X86-NEXT: pushl $0 118; X86-NEXT: pushl $2 119; X86-NEXT: pushl {{[0-9]+}}(%esp) 120; X86-NEXT: pushl {{[0-9]+}}(%esp) 121; X86-NEXT: calll memcmp 122; X86-NEXT: addl $16, %esp 123; X86-NEXT: testl %eax, %eax 124; X86-NEXT: sete %al 125; X86-NEXT: retl 126; 127; X64-LABEL: length2_eq_nobuiltin_attr: 128; X64: # %bb.0: 129; X64-NEXT: pushq %rax 130; X64-NEXT: movl $2, %edx 131; X64-NEXT: callq memcmp 132; X64-NEXT: testl %eax, %eax 133; X64-NEXT: sete %al 134; X64-NEXT: popq %rcx 135; X64-NEXT: retq 136 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin 137 %c = icmp eq i32 %m, 0 138 ret i1 %c 139} 140 141define i32 @length3(i8* %X, i8* %Y) nounwind { 142; X86-LABEL: length3: 143; X86: # %bb.0: # %loadbb 144; X86-NEXT: pushl %esi 145; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 146; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 147; X86-NEXT: movzwl (%eax), %edx 148; X86-NEXT: movzwl (%ecx), %esi 149; X86-NEXT: rolw $8, %dx 150; X86-NEXT: rolw $8, %si 151; X86-NEXT: cmpw %si, %dx 152; X86-NEXT: jne .LBB6_1 153; X86-NEXT: # %bb.2: # %loadbb1 154; X86-NEXT: movzbl 2(%eax), %eax 155; X86-NEXT: movzbl 2(%ecx), %ecx 156; X86-NEXT: subl %ecx, %eax 157; X86-NEXT: popl %esi 158; X86-NEXT: retl 159; X86-NEXT: .LBB6_1: # %res_block 160; X86-NEXT: setae %al 161; X86-NEXT: movzbl %al, %eax 162; X86-NEXT: leal -1(%eax,%eax), %eax 163; X86-NEXT: popl %esi 164; X86-NEXT: retl 165; 166; X64-LABEL: length3: 167; X64: # %bb.0: # %loadbb 168; X64-NEXT: movzwl (%rdi), %eax 169; X64-NEXT: movzwl (%rsi), %ecx 170; X64-NEXT: rolw $8, %ax 171; X64-NEXT: rolw $8, %cx 172; X64-NEXT: cmpw %cx, %ax 173; X64-NEXT: jne .LBB6_1 174; X64-NEXT: # %bb.2: # %loadbb1 175; X64-NEXT: movzbl 2(%rdi), %eax 176; X64-NEXT: movzbl 2(%rsi), %ecx 177; X64-NEXT: subl %ecx, %eax 178; X64-NEXT: retq 179; X64-NEXT: .LBB6_1: # %res_block 180; X64-NEXT: setae %al 181; X64-NEXT: movzbl %al, %eax 182; X64-NEXT: leal -1(%rax,%rax), %eax 183; X64-NEXT: retq 184 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 185 ret i32 %m 186} 187 188define i1 @length3_eq(i8* %X, i8* %Y) nounwind { 189; X86-LABEL: length3_eq: 190; X86: # %bb.0: 191; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 192; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 193; X86-NEXT: movzwl (%ecx), %edx 194; X86-NEXT: xorw (%eax), %dx 195; X86-NEXT: movb 2(%ecx), %cl 196; X86-NEXT: xorb 2(%eax), %cl 197; X86-NEXT: movzbl %cl, %eax 198; X86-NEXT: orw %dx, %ax 199; X86-NEXT: setne %al 200; X86-NEXT: retl 201; 202; X64-LABEL: length3_eq: 203; X64: # %bb.0: 204; X64-NEXT: movzwl (%rdi), %eax 205; X64-NEXT: xorw (%rsi), %ax 206; X64-NEXT: movb 2(%rdi), %cl 207; X64-NEXT: xorb 2(%rsi), %cl 208; X64-NEXT: movzbl %cl, %ecx 209; X64-NEXT: orw %ax, %cx 210; X64-NEXT: setne %al 211; X64-NEXT: retq 212 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 213 %c = icmp ne i32 %m, 0 214 ret i1 %c 215} 216 217define i32 @length4(i8* %X, i8* %Y) nounwind { 218; X86-LABEL: length4: 219; X86: # %bb.0: 220; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 221; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 222; X86-NEXT: movl (%ecx), %ecx 223; X86-NEXT: movl (%eax), %edx 224; X86-NEXT: bswapl %ecx 225; X86-NEXT: bswapl %edx 226; X86-NEXT: xorl %eax, %eax 227; X86-NEXT: cmpl %edx, %ecx 228; X86-NEXT: seta %al 229; X86-NEXT: sbbl $0, %eax 230; X86-NEXT: retl 231; 232; X64-LABEL: length4: 233; X64: # %bb.0: 234; X64-NEXT: movl (%rdi), %ecx 235; X64-NEXT: movl (%rsi), %edx 236; X64-NEXT: bswapl %ecx 237; X64-NEXT: bswapl %edx 238; X64-NEXT: xorl %eax, %eax 239; X64-NEXT: cmpl %edx, %ecx 240; X64-NEXT: seta %al 241; X64-NEXT: sbbl $0, %eax 242; X64-NEXT: retq 243 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 244 ret i32 %m 245} 246 247define i1 @length4_eq(i8* %X, i8* %Y) nounwind { 248; X86-LABEL: length4_eq: 249; X86: # %bb.0: 250; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 251; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 252; X86-NEXT: movl (%ecx), %ecx 253; X86-NEXT: cmpl (%eax), %ecx 254; X86-NEXT: setne %al 255; X86-NEXT: retl 256; 257; X64-LABEL: length4_eq: 258; X64: # %bb.0: 259; X64-NEXT: movl (%rdi), %eax 260; X64-NEXT: cmpl (%rsi), %eax 261; X64-NEXT: setne %al 262; X64-NEXT: retq 263 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 264 %c = icmp ne i32 %m, 0 265 ret i1 %c 266} 267 268define i1 @length4_eq_const(i8* %X) nounwind { 269; X86-LABEL: length4_eq_const: 270; X86: # %bb.0: 271; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 272; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231 273; X86-NEXT: sete %al 274; X86-NEXT: retl 275; 276; X64-LABEL: length4_eq_const: 277; X64: # %bb.0: 278; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231 279; X64-NEXT: sete %al 280; X64-NEXT: retq 281 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind 282 %c = icmp eq i32 %m, 0 283 ret i1 %c 284} 285 286define i32 @length5(i8* %X, i8* %Y) nounwind { 287; X86-LABEL: length5: 288; X86: # %bb.0: # %loadbb 289; X86-NEXT: pushl %esi 290; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 291; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 292; X86-NEXT: movl (%eax), %edx 293; X86-NEXT: movl (%ecx), %esi 294; X86-NEXT: bswapl %edx 295; X86-NEXT: bswapl %esi 296; X86-NEXT: cmpl %esi, %edx 297; X86-NEXT: jne .LBB11_1 298; X86-NEXT: # %bb.2: # %loadbb1 299; X86-NEXT: movzbl 4(%eax), %eax 300; X86-NEXT: movzbl 4(%ecx), %ecx 301; X86-NEXT: subl %ecx, %eax 302; X86-NEXT: popl %esi 303; X86-NEXT: retl 304; X86-NEXT: .LBB11_1: # %res_block 305; X86-NEXT: setae %al 306; X86-NEXT: movzbl %al, %eax 307; X86-NEXT: leal -1(%eax,%eax), %eax 308; X86-NEXT: popl %esi 309; X86-NEXT: retl 310; 311; X64-LABEL: length5: 312; X64: # %bb.0: # %loadbb 313; X64-NEXT: movl (%rdi), %eax 314; X64-NEXT: movl (%rsi), %ecx 315; X64-NEXT: bswapl %eax 316; X64-NEXT: bswapl %ecx 317; X64-NEXT: cmpl %ecx, %eax 318; X64-NEXT: jne .LBB11_1 319; X64-NEXT: # %bb.2: # %loadbb1 320; X64-NEXT: movzbl 4(%rdi), %eax 321; X64-NEXT: movzbl 4(%rsi), %ecx 322; X64-NEXT: subl %ecx, %eax 323; X64-NEXT: retq 324; X64-NEXT: .LBB11_1: # %res_block 325; X64-NEXT: setae %al 326; X64-NEXT: movzbl %al, %eax 327; X64-NEXT: leal -1(%rax,%rax), %eax 328; X64-NEXT: retq 329 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 330 ret i32 %m 331} 332 333define i1 @length5_eq(i8* %X, i8* %Y) nounwind { 334; X86-LABEL: length5_eq: 335; X86: # %bb.0: 336; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 337; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 338; X86-NEXT: movl (%ecx), %edx 339; X86-NEXT: xorl (%eax), %edx 340; X86-NEXT: movb 4(%ecx), %cl 341; X86-NEXT: xorb 4(%eax), %cl 342; X86-NEXT: movzbl %cl, %eax 343; X86-NEXT: orl %edx, %eax 344; X86-NEXT: setne %al 345; X86-NEXT: retl 346; 347; X64-LABEL: length5_eq: 348; X64: # %bb.0: 349; X64-NEXT: movl (%rdi), %eax 350; X64-NEXT: xorl (%rsi), %eax 351; X64-NEXT: movb 4(%rdi), %cl 352; X64-NEXT: xorb 4(%rsi), %cl 353; X64-NEXT: movzbl %cl, %ecx 354; X64-NEXT: orl %eax, %ecx 355; X64-NEXT: setne %al 356; X64-NEXT: retq 357 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 358 %c = icmp ne i32 %m, 0 359 ret i1 %c 360} 361 362define i1 @length7_eq(i8* %X, i8* %Y) nounwind { 363; X86-LABEL: length7_eq: 364; X86: # %bb.0: 365; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 366; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 367; X86-NEXT: movl (%ecx), %edx 368; X86-NEXT: movl 3(%ecx), %ecx 369; X86-NEXT: xorl (%eax), %edx 370; X86-NEXT: xorl 3(%eax), %ecx 371; X86-NEXT: orl %edx, %ecx 372; X86-NEXT: setne %al 373; X86-NEXT: retl 374; 375; X64-LABEL: length7_eq: 376; X64: # %bb.0: 377; X64-NEXT: movl (%rdi), %eax 378; X64-NEXT: movl 3(%rdi), %ecx 379; X64-NEXT: xorl (%rsi), %eax 380; X64-NEXT: xorl 3(%rsi), %ecx 381; X64-NEXT: orl %eax, %ecx 382; X64-NEXT: setne %al 383; X64-NEXT: retq 384 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 7) nounwind 385 %c = icmp ne i32 %m, 0 386 ret i1 %c 387} 388 389define i32 @length8(i8* %X, i8* %Y) nounwind { 390; X86-LABEL: length8: 391; X86: # %bb.0: 392; X86-NEXT: pushl %esi 393; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 394; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 395; X86-NEXT: movl (%esi), %ecx 396; X86-NEXT: movl (%eax), %edx 397; X86-NEXT: bswapl %ecx 398; X86-NEXT: bswapl %edx 399; X86-NEXT: cmpl %edx, %ecx 400; X86-NEXT: jne .LBB14_2 401; X86-NEXT: # %bb.1: # %loadbb1 402; X86-NEXT: movl 4(%esi), %ecx 403; X86-NEXT: movl 4(%eax), %edx 404; X86-NEXT: bswapl %ecx 405; X86-NEXT: bswapl %edx 406; X86-NEXT: xorl %eax, %eax 407; X86-NEXT: cmpl %edx, %ecx 408; X86-NEXT: je .LBB14_3 409; X86-NEXT: .LBB14_2: # %res_block 410; X86-NEXT: xorl %eax, %eax 411; X86-NEXT: cmpl %edx, %ecx 412; X86-NEXT: setae %al 413; X86-NEXT: leal -1(%eax,%eax), %eax 414; X86-NEXT: .LBB14_3: # %endblock 415; X86-NEXT: popl %esi 416; X86-NEXT: retl 417; 418; X64-LABEL: length8: 419; X64: # %bb.0: 420; X64-NEXT: movq (%rdi), %rcx 421; X64-NEXT: movq (%rsi), %rdx 422; X64-NEXT: bswapq %rcx 423; X64-NEXT: bswapq %rdx 424; X64-NEXT: xorl %eax, %eax 425; X64-NEXT: cmpq %rdx, %rcx 426; X64-NEXT: seta %al 427; X64-NEXT: sbbl $0, %eax 428; X64-NEXT: retq 429 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 430 ret i32 %m 431} 432 433define i1 @length8_eq(i8* %X, i8* %Y) nounwind { 434; X86-LABEL: length8_eq: 435; X86: # %bb.0: 436; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 437; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 438; X86-NEXT: movl (%ecx), %edx 439; X86-NEXT: movl 4(%ecx), %ecx 440; X86-NEXT: xorl (%eax), %edx 441; X86-NEXT: xorl 4(%eax), %ecx 442; X86-NEXT: orl %edx, %ecx 443; X86-NEXT: sete %al 444; X86-NEXT: retl 445; 446; X64-LABEL: length8_eq: 447; X64: # %bb.0: 448; X64-NEXT: movq (%rdi), %rax 449; X64-NEXT: cmpq (%rsi), %rax 450; X64-NEXT: sete %al 451; X64-NEXT: retq 452 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 453 %c = icmp eq i32 %m, 0 454 ret i1 %c 455} 456 457define i1 @length8_eq_const(i8* %X) nounwind { 458; X86-LABEL: length8_eq_const: 459; X86: # %bb.0: 460; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 461; X86-NEXT: movl $858927408, %ecx # imm = 0x33323130 462; X86-NEXT: xorl (%eax), %ecx 463; X86-NEXT: movl $926299444, %edx # imm = 0x37363534 464; X86-NEXT: xorl 4(%eax), %edx 465; X86-NEXT: orl %ecx, %edx 466; X86-NEXT: setne %al 467; X86-NEXT: retl 468; 469; X64-LABEL: length8_eq_const: 470; X64: # %bb.0: 471; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130 472; X64-NEXT: cmpq %rax, (%rdi) 473; X64-NEXT: setne %al 474; X64-NEXT: retq 475 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind 476 %c = icmp ne i32 %m, 0 477 ret i1 %c 478} 479 480define i1 @length9_eq(i8* %X, i8* %Y) nounwind { 481; X86-LABEL: length9_eq: 482; X86: # %bb.0: 483; X86-NEXT: pushl $0 484; X86-NEXT: pushl $9 485; X86-NEXT: pushl {{[0-9]+}}(%esp) 486; X86-NEXT: pushl {{[0-9]+}}(%esp) 487; X86-NEXT: calll memcmp 488; X86-NEXT: addl $16, %esp 489; X86-NEXT: testl %eax, %eax 490; X86-NEXT: sete %al 491; X86-NEXT: retl 492; 493; X64-LABEL: length9_eq: 494; X64: # %bb.0: 495; X64-NEXT: movq (%rdi), %rax 496; X64-NEXT: xorq (%rsi), %rax 497; X64-NEXT: movb 8(%rdi), %cl 498; X64-NEXT: xorb 8(%rsi), %cl 499; X64-NEXT: movzbl %cl, %ecx 500; X64-NEXT: orq %rax, %rcx 501; X64-NEXT: sete %al 502; X64-NEXT: retq 503 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9) nounwind 504 %c = icmp eq i32 %m, 0 505 ret i1 %c 506} 507 508define i1 @length10_eq(i8* %X, i8* %Y) nounwind { 509; X86-LABEL: length10_eq: 510; X86: # %bb.0: 511; X86-NEXT: pushl $0 512; X86-NEXT: pushl $10 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: length10_eq: 522; X64: # %bb.0: 523; X64-NEXT: movq (%rdi), %rax 524; X64-NEXT: xorq (%rsi), %rax 525; X64-NEXT: movzwl 8(%rdi), %ecx 526; X64-NEXT: xorw 8(%rsi), %cx 527; X64-NEXT: movzwl %cx, %ecx 528; X64-NEXT: orq %rax, %rcx 529; X64-NEXT: sete %al 530; X64-NEXT: retq 531 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 10) nounwind 532 %c = icmp eq i32 %m, 0 533 ret i1 %c 534} 535 536define i1 @length11_eq(i8* %X, i8* %Y) nounwind { 537; X86-LABEL: length11_eq: 538; X86: # %bb.0: 539; X86-NEXT: pushl $0 540; X86-NEXT: pushl $11 541; X86-NEXT: pushl {{[0-9]+}}(%esp) 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: sete %al 547; X86-NEXT: retl 548; 549; X64-LABEL: length11_eq: 550; X64: # %bb.0: 551; X64-NEXT: movq (%rdi), %rax 552; X64-NEXT: movq 3(%rdi), %rcx 553; X64-NEXT: xorq (%rsi), %rax 554; X64-NEXT: xorq 3(%rsi), %rcx 555; X64-NEXT: orq %rax, %rcx 556; X64-NEXT: sete %al 557; X64-NEXT: retq 558 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 11) nounwind 559 %c = icmp eq i32 %m, 0 560 ret i1 %c 561} 562 563define i1 @length12_eq(i8* %X, i8* %Y) nounwind { 564; X86-LABEL: length12_eq: 565; X86: # %bb.0: 566; X86-NEXT: pushl $0 567; X86-NEXT: pushl $12 568; X86-NEXT: pushl {{[0-9]+}}(%esp) 569; X86-NEXT: pushl {{[0-9]+}}(%esp) 570; X86-NEXT: calll memcmp 571; X86-NEXT: addl $16, %esp 572; X86-NEXT: testl %eax, %eax 573; X86-NEXT: setne %al 574; X86-NEXT: retl 575; 576; X64-LABEL: length12_eq: 577; X64: # %bb.0: 578; X64-NEXT: movq (%rdi), %rax 579; X64-NEXT: xorq (%rsi), %rax 580; X64-NEXT: movl 8(%rdi), %ecx 581; X64-NEXT: xorl 8(%rsi), %ecx 582; X64-NEXT: orq %rax, %rcx 583; X64-NEXT: setne %al 584; X64-NEXT: retq 585 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 586 %c = icmp ne i32 %m, 0 587 ret i1 %c 588} 589 590define i32 @length12(i8* %X, i8* %Y) nounwind { 591; X86-LABEL: length12: 592; X86: # %bb.0: 593; X86-NEXT: pushl $0 594; X86-NEXT: pushl $12 595; X86-NEXT: pushl {{[0-9]+}}(%esp) 596; X86-NEXT: pushl {{[0-9]+}}(%esp) 597; X86-NEXT: calll memcmp 598; X86-NEXT: addl $16, %esp 599; X86-NEXT: retl 600; 601; X64-LABEL: length12: 602; X64: # %bb.0: 603; X64-NEXT: movq (%rdi), %rcx 604; X64-NEXT: movq (%rsi), %rdx 605; X64-NEXT: bswapq %rcx 606; X64-NEXT: bswapq %rdx 607; X64-NEXT: cmpq %rdx, %rcx 608; X64-NEXT: jne .LBB21_2 609; X64-NEXT: # %bb.1: # %loadbb1 610; X64-NEXT: movl 8(%rdi), %ecx 611; X64-NEXT: movl 8(%rsi), %edx 612; X64-NEXT: bswapl %ecx 613; X64-NEXT: bswapl %edx 614; X64-NEXT: xorl %eax, %eax 615; X64-NEXT: cmpq %rdx, %rcx 616; X64-NEXT: je .LBB21_3 617; X64-NEXT: .LBB21_2: # %res_block 618; X64-NEXT: xorl %eax, %eax 619; X64-NEXT: cmpq %rdx, %rcx 620; X64-NEXT: setae %al 621; X64-NEXT: leal -1(%rax,%rax), %eax 622; X64-NEXT: .LBB21_3: # %endblock 623; X64-NEXT: retq 624 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 625 ret i32 %m 626} 627 628define i1 @length13_eq(i8* %X, i8* %Y) nounwind { 629; X86-LABEL: length13_eq: 630; X86: # %bb.0: 631; X86-NEXT: pushl $0 632; X86-NEXT: pushl $13 633; X86-NEXT: pushl {{[0-9]+}}(%esp) 634; X86-NEXT: pushl {{[0-9]+}}(%esp) 635; X86-NEXT: calll memcmp 636; X86-NEXT: addl $16, %esp 637; X86-NEXT: testl %eax, %eax 638; X86-NEXT: sete %al 639; X86-NEXT: retl 640; 641; X64-LABEL: length13_eq: 642; X64: # %bb.0: 643; X64-NEXT: movq (%rdi), %rax 644; X64-NEXT: movq 5(%rdi), %rcx 645; X64-NEXT: xorq (%rsi), %rax 646; X64-NEXT: xorq 5(%rsi), %rcx 647; X64-NEXT: orq %rax, %rcx 648; X64-NEXT: sete %al 649; X64-NEXT: retq 650 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 13) nounwind 651 %c = icmp eq i32 %m, 0 652 ret i1 %c 653} 654 655define i1 @length14_eq(i8* %X, i8* %Y) nounwind { 656; X86-LABEL: length14_eq: 657; X86: # %bb.0: 658; X86-NEXT: pushl $0 659; X86-NEXT: pushl $14 660; X86-NEXT: pushl {{[0-9]+}}(%esp) 661; X86-NEXT: pushl {{[0-9]+}}(%esp) 662; X86-NEXT: calll memcmp 663; X86-NEXT: addl $16, %esp 664; X86-NEXT: testl %eax, %eax 665; X86-NEXT: sete %al 666; X86-NEXT: retl 667; 668; X64-LABEL: length14_eq: 669; X64: # %bb.0: 670; X64-NEXT: movq (%rdi), %rax 671; X64-NEXT: movq 6(%rdi), %rcx 672; X64-NEXT: xorq (%rsi), %rax 673; X64-NEXT: xorq 6(%rsi), %rcx 674; X64-NEXT: orq %rax, %rcx 675; X64-NEXT: sete %al 676; X64-NEXT: retq 677 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 14) nounwind 678 %c = icmp eq i32 %m, 0 679 ret i1 %c 680} 681 682define i1 @length15_eq(i8* %X, i8* %Y) nounwind { 683; X86-LABEL: length15_eq: 684; X86: # %bb.0: 685; X86-NEXT: pushl $0 686; X86-NEXT: pushl $15 687; X86-NEXT: pushl {{[0-9]+}}(%esp) 688; X86-NEXT: pushl {{[0-9]+}}(%esp) 689; X86-NEXT: calll memcmp 690; X86-NEXT: addl $16, %esp 691; X86-NEXT: testl %eax, %eax 692; X86-NEXT: sete %al 693; X86-NEXT: retl 694; 695; X64-LABEL: length15_eq: 696; X64: # %bb.0: 697; X64-NEXT: movq (%rdi), %rax 698; X64-NEXT: movq 7(%rdi), %rcx 699; X64-NEXT: xorq (%rsi), %rax 700; X64-NEXT: xorq 7(%rsi), %rcx 701; X64-NEXT: orq %rax, %rcx 702; X64-NEXT: sete %al 703; X64-NEXT: retq 704 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 15) nounwind 705 %c = icmp eq i32 %m, 0 706 ret i1 %c 707} 708 709; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329 710 711define i32 @length16(i8* %X, i8* %Y) nounwind { 712; X86-LABEL: length16: 713; X86: # %bb.0: 714; X86-NEXT: pushl $0 715; X86-NEXT: pushl $16 716; X86-NEXT: pushl {{[0-9]+}}(%esp) 717; X86-NEXT: pushl {{[0-9]+}}(%esp) 718; X86-NEXT: calll memcmp 719; X86-NEXT: addl $16, %esp 720; X86-NEXT: retl 721; 722; X64-LABEL: length16: 723; X64: # %bb.0: 724; X64-NEXT: movq (%rdi), %rcx 725; X64-NEXT: movq (%rsi), %rdx 726; X64-NEXT: bswapq %rcx 727; X64-NEXT: bswapq %rdx 728; X64-NEXT: cmpq %rdx, %rcx 729; X64-NEXT: jne .LBB25_2 730; X64-NEXT: # %bb.1: # %loadbb1 731; X64-NEXT: movq 8(%rdi), %rcx 732; X64-NEXT: movq 8(%rsi), %rdx 733; X64-NEXT: bswapq %rcx 734; X64-NEXT: bswapq %rdx 735; X64-NEXT: xorl %eax, %eax 736; X64-NEXT: cmpq %rdx, %rcx 737; X64-NEXT: je .LBB25_3 738; X64-NEXT: .LBB25_2: # %res_block 739; X64-NEXT: xorl %eax, %eax 740; X64-NEXT: cmpq %rdx, %rcx 741; X64-NEXT: setae %al 742; X64-NEXT: leal -1(%rax,%rax), %eax 743; X64-NEXT: .LBB25_3: # %endblock 744; X64-NEXT: retq 745 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind 746 ret i32 %m 747} 748 749define i1 @length16_eq(i8* %x, i8* %y) nounwind { 750; X86-NOSSE-LABEL: length16_eq: 751; X86-NOSSE: # %bb.0: 752; X86-NOSSE-NEXT: pushl $0 753; X86-NOSSE-NEXT: pushl $16 754; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 755; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 756; X86-NOSSE-NEXT: calll memcmp 757; X86-NOSSE-NEXT: addl $16, %esp 758; X86-NOSSE-NEXT: testl %eax, %eax 759; X86-NOSSE-NEXT: setne %al 760; X86-NOSSE-NEXT: retl 761; 762; X86-SSE1-LABEL: length16_eq: 763; X86-SSE1: # %bb.0: 764; X86-SSE1-NEXT: pushl $0 765; X86-SSE1-NEXT: pushl $16 766; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 767; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 768; X86-SSE1-NEXT: calll memcmp 769; X86-SSE1-NEXT: addl $16, %esp 770; X86-SSE1-NEXT: testl %eax, %eax 771; X86-SSE1-NEXT: setne %al 772; X86-SSE1-NEXT: retl 773; 774; X86-SSE2-LABEL: length16_eq: 775; X86-SSE2: # %bb.0: 776; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 777; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 778; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 779; X86-SSE2-NEXT: movdqu (%eax), %xmm1 780; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 781; X86-SSE2-NEXT: pmovmskb %xmm1, %eax 782; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 783; X86-SSE2-NEXT: setne %al 784; X86-SSE2-NEXT: retl 785; 786; X64-SSE2-LABEL: length16_eq: 787; X64-SSE2: # %bb.0: 788; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 789; X64-SSE2-NEXT: movdqu (%rsi), %xmm1 790; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 791; X64-SSE2-NEXT: pmovmskb %xmm1, %eax 792; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 793; X64-SSE2-NEXT: setne %al 794; X64-SSE2-NEXT: retq 795; 796; X64-AVX-LABEL: length16_eq: 797; X64-AVX: # %bb.0: 798; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 799; X64-AVX-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 800; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 801; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 802; X64-AVX-NEXT: setne %al 803; X64-AVX-NEXT: retq 804 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind 805 %cmp = icmp ne i32 %call, 0 806 ret i1 %cmp 807} 808 809define i1 @length16_eq_const(i8* %X) nounwind { 810; X86-NOSSE-LABEL: length16_eq_const: 811; X86-NOSSE: # %bb.0: 812; X86-NOSSE-NEXT: pushl $0 813; X86-NOSSE-NEXT: pushl $16 814; X86-NOSSE-NEXT: pushl $.L.str 815; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 816; X86-NOSSE-NEXT: calll memcmp 817; X86-NOSSE-NEXT: addl $16, %esp 818; X86-NOSSE-NEXT: testl %eax, %eax 819; X86-NOSSE-NEXT: sete %al 820; X86-NOSSE-NEXT: retl 821; 822; X86-SSE1-LABEL: length16_eq_const: 823; X86-SSE1: # %bb.0: 824; X86-SSE1-NEXT: pushl $0 825; X86-SSE1-NEXT: pushl $16 826; X86-SSE1-NEXT: pushl $.L.str 827; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 828; X86-SSE1-NEXT: calll memcmp 829; X86-SSE1-NEXT: addl $16, %esp 830; X86-SSE1-NEXT: testl %eax, %eax 831; X86-SSE1-NEXT: sete %al 832; X86-SSE1-NEXT: retl 833; 834; X86-SSE2-LABEL: length16_eq_const: 835; X86-SSE2: # %bb.0: 836; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 837; X86-SSE2-NEXT: movdqu (%eax), %xmm0 838; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 839; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 840; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 841; X86-SSE2-NEXT: sete %al 842; X86-SSE2-NEXT: retl 843; 844; X64-SSE2-LABEL: length16_eq_const: 845; X64-SSE2: # %bb.0: 846; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 847; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 848; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 849; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 850; X64-SSE2-NEXT: sete %al 851; X64-SSE2-NEXT: retq 852; 853; X64-AVX-LABEL: length16_eq_const: 854; X64-AVX: # %bb.0: 855; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 856; X64-AVX-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 857; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 858; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 859; X64-AVX-NEXT: sete %al 860; X64-AVX-NEXT: retq 861 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind 862 %c = icmp eq i32 %m, 0 863 ret i1 %c 864} 865 866; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914 867 868define i32 @length24(i8* %X, i8* %Y) nounwind { 869; X86-LABEL: length24: 870; X86: # %bb.0: 871; X86-NEXT: pushl $0 872; X86-NEXT: pushl $24 873; X86-NEXT: pushl {{[0-9]+}}(%esp) 874; X86-NEXT: pushl {{[0-9]+}}(%esp) 875; X86-NEXT: calll memcmp 876; X86-NEXT: addl $16, %esp 877; X86-NEXT: retl 878; 879; X64-LABEL: length24: 880; X64: # %bb.0: 881; X64-NEXT: movl $24, %edx 882; X64-NEXT: jmp memcmp # TAILCALL 883 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind 884 ret i32 %m 885} 886 887define i1 @length24_eq(i8* %x, i8* %y) nounwind { 888; X86-NOSSE-LABEL: length24_eq: 889; X86-NOSSE: # %bb.0: 890; X86-NOSSE-NEXT: pushl $0 891; X86-NOSSE-NEXT: pushl $24 892; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 893; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 894; X86-NOSSE-NEXT: calll memcmp 895; X86-NOSSE-NEXT: addl $16, %esp 896; X86-NOSSE-NEXT: testl %eax, %eax 897; X86-NOSSE-NEXT: sete %al 898; X86-NOSSE-NEXT: retl 899; 900; X86-SSE1-LABEL: length24_eq: 901; X86-SSE1: # %bb.0: 902; X86-SSE1-NEXT: pushl $0 903; X86-SSE1-NEXT: pushl $24 904; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 905; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 906; X86-SSE1-NEXT: calll memcmp 907; X86-SSE1-NEXT: addl $16, %esp 908; X86-SSE1-NEXT: testl %eax, %eax 909; X86-SSE1-NEXT: sete %al 910; X86-SSE1-NEXT: retl 911; 912; X86-SSE2-LABEL: length24_eq: 913; X86-SSE2: # %bb.0: 914; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 915; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 916; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 917; X86-SSE2-NEXT: movdqu 8(%ecx), %xmm1 918; X86-SSE2-NEXT: movdqu (%eax), %xmm2 919; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 920; X86-SSE2-NEXT: movdqu 8(%eax), %xmm0 921; X86-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 922; X86-SSE2-NEXT: pand %xmm2, %xmm0 923; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 924; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 925; X86-SSE2-NEXT: sete %al 926; X86-SSE2-NEXT: retl 927; 928; X64-SSE2-LABEL: length24_eq: 929; X64-SSE2: # %bb.0: 930; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 931; X64-SSE2-NEXT: movdqu (%rsi), %xmm1 932; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 933; X64-SSE2-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 934; X64-SSE2-NEXT: movq {{.*#+}} xmm2 = mem[0],zero 935; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 936; X64-SSE2-NEXT: pand %xmm1, %xmm2 937; X64-SSE2-NEXT: pmovmskb %xmm2, %eax 938; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 939; X64-SSE2-NEXT: sete %al 940; X64-SSE2-NEXT: retq 941; 942; X64-AVX-LABEL: length24_eq: 943; X64-AVX: # %bb.0: 944; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 945; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 946; X64-AVX-NEXT: vmovq {{.*#+}} xmm2 = mem[0],zero 947; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 948; X64-AVX-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 949; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 950; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 951; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 952; X64-AVX-NEXT: sete %al 953; X64-AVX-NEXT: retq 954 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind 955 %cmp = icmp eq i32 %call, 0 956 ret i1 %cmp 957} 958 959define i1 @length24_eq_const(i8* %X) nounwind { 960; X86-NOSSE-LABEL: length24_eq_const: 961; X86-NOSSE: # %bb.0: 962; X86-NOSSE-NEXT: pushl $0 963; X86-NOSSE-NEXT: pushl $24 964; X86-NOSSE-NEXT: pushl $.L.str 965; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 966; X86-NOSSE-NEXT: calll memcmp 967; X86-NOSSE-NEXT: addl $16, %esp 968; X86-NOSSE-NEXT: testl %eax, %eax 969; X86-NOSSE-NEXT: setne %al 970; X86-NOSSE-NEXT: retl 971; 972; X86-SSE1-LABEL: length24_eq_const: 973; X86-SSE1: # %bb.0: 974; X86-SSE1-NEXT: pushl $0 975; X86-SSE1-NEXT: pushl $24 976; X86-SSE1-NEXT: pushl $.L.str 977; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 978; X86-SSE1-NEXT: calll memcmp 979; X86-SSE1-NEXT: addl $16, %esp 980; X86-SSE1-NEXT: testl %eax, %eax 981; X86-SSE1-NEXT: setne %al 982; X86-SSE1-NEXT: retl 983; 984; X86-SSE2-LABEL: length24_eq_const: 985; X86-SSE2: # %bb.0: 986; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 987; X86-SSE2-NEXT: movdqu (%eax), %xmm0 988; X86-SSE2-NEXT: movdqu 8(%eax), %xmm1 989; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm1 990; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 991; X86-SSE2-NEXT: pand %xmm1, %xmm0 992; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 993; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 994; X86-SSE2-NEXT: setne %al 995; X86-SSE2-NEXT: retl 996; 997; X64-SSE2-LABEL: length24_eq_const: 998; X64-SSE2: # %bb.0: 999; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 1000; X64-SSE2-NEXT: movq {{.*#+}} xmm1 = mem[0],zero 1001; X64-SSE2-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 1002; X64-SSE2-NEXT: movq %rax, %xmm2 1003; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm2 1004; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 1005; X64-SSE2-NEXT: pand %xmm2, %xmm0 1006; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 1007; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1008; X64-SSE2-NEXT: setne %al 1009; X64-SSE2-NEXT: retq 1010; 1011; X64-AVX-LABEL: length24_eq_const: 1012; X64-AVX: # %bb.0: 1013; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 1014; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 1015; X64-AVX-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 1016; X64-AVX-NEXT: vmovq %rax, %xmm2 1017; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 1018; X64-AVX-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 1019; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 1020; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 1021; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1022; X64-AVX-NEXT: setne %al 1023; X64-AVX-NEXT: retq 1024 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind 1025 %c = icmp ne i32 %m, 0 1026 ret i1 %c 1027} 1028 1029define i32 @length32(i8* %X, i8* %Y) nounwind { 1030; X86-LABEL: length32: 1031; X86: # %bb.0: 1032; X86-NEXT: pushl $0 1033; X86-NEXT: pushl $32 1034; X86-NEXT: pushl {{[0-9]+}}(%esp) 1035; X86-NEXT: pushl {{[0-9]+}}(%esp) 1036; X86-NEXT: calll memcmp 1037; X86-NEXT: addl $16, %esp 1038; X86-NEXT: retl 1039; 1040; X64-LABEL: length32: 1041; X64: # %bb.0: 1042; X64-NEXT: movl $32, %edx 1043; X64-NEXT: jmp memcmp # TAILCALL 1044 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind 1045 ret i32 %m 1046} 1047 1048; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 1049 1050define i1 @length32_eq(i8* %x, i8* %y) nounwind { 1051; X86-NOSSE-LABEL: length32_eq: 1052; X86-NOSSE: # %bb.0: 1053; X86-NOSSE-NEXT: pushl $0 1054; X86-NOSSE-NEXT: pushl $32 1055; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1056; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1057; X86-NOSSE-NEXT: calll memcmp 1058; X86-NOSSE-NEXT: addl $16, %esp 1059; X86-NOSSE-NEXT: testl %eax, %eax 1060; X86-NOSSE-NEXT: sete %al 1061; X86-NOSSE-NEXT: retl 1062; 1063; X86-SSE1-LABEL: length32_eq: 1064; X86-SSE1: # %bb.0: 1065; X86-SSE1-NEXT: pushl $0 1066; X86-SSE1-NEXT: pushl $32 1067; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1068; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1069; X86-SSE1-NEXT: calll memcmp 1070; X86-SSE1-NEXT: addl $16, %esp 1071; X86-SSE1-NEXT: testl %eax, %eax 1072; X86-SSE1-NEXT: sete %al 1073; X86-SSE1-NEXT: retl 1074; 1075; X86-SSE2-LABEL: length32_eq: 1076; X86-SSE2: # %bb.0: 1077; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 1078; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 1079; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 1080; X86-SSE2-NEXT: movdqu 16(%ecx), %xmm1 1081; X86-SSE2-NEXT: movdqu (%eax), %xmm2 1082; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 1083; X86-SSE2-NEXT: movdqu 16(%eax), %xmm0 1084; X86-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 1085; X86-SSE2-NEXT: pand %xmm2, %xmm0 1086; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 1087; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1088; X86-SSE2-NEXT: sete %al 1089; X86-SSE2-NEXT: retl 1090; 1091; X64-SSE2-LABEL: length32_eq: 1092; X64-SSE2: # %bb.0: 1093; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 1094; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 1095; X64-SSE2-NEXT: movdqu (%rsi), %xmm2 1096; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 1097; X64-SSE2-NEXT: movdqu 16(%rsi), %xmm0 1098; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 1099; X64-SSE2-NEXT: pand %xmm2, %xmm0 1100; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 1101; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1102; X64-SSE2-NEXT: sete %al 1103; X64-SSE2-NEXT: retq 1104; 1105; X64-AVX1-LABEL: length32_eq: 1106; X64-AVX1: # %bb.0: 1107; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 1108; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1109; X64-AVX1-NEXT: vpcmpeqb 16(%rsi), %xmm1, %xmm1 1110; X64-AVX1-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 1111; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 1112; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 1113; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1114; X64-AVX1-NEXT: sete %al 1115; X64-AVX1-NEXT: retq 1116; 1117; X64-AVX2-LABEL: length32_eq: 1118; X64-AVX2: # %bb.0: 1119; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1120; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 1121; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1122; X64-AVX2-NEXT: cmpl $-1, %eax 1123; X64-AVX2-NEXT: sete %al 1124; X64-AVX2-NEXT: vzeroupper 1125; X64-AVX2-NEXT: retq 1126 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind 1127 %cmp = icmp eq i32 %call, 0 1128 ret i1 %cmp 1129} 1130 1131define i1 @length32_eq_const(i8* %X) nounwind { 1132; X86-NOSSE-LABEL: length32_eq_const: 1133; X86-NOSSE: # %bb.0: 1134; X86-NOSSE-NEXT: pushl $0 1135; X86-NOSSE-NEXT: pushl $32 1136; X86-NOSSE-NEXT: pushl $.L.str 1137; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1138; X86-NOSSE-NEXT: calll memcmp 1139; X86-NOSSE-NEXT: addl $16, %esp 1140; X86-NOSSE-NEXT: testl %eax, %eax 1141; X86-NOSSE-NEXT: setne %al 1142; X86-NOSSE-NEXT: retl 1143; 1144; X86-SSE1-LABEL: length32_eq_const: 1145; X86-SSE1: # %bb.0: 1146; X86-SSE1-NEXT: pushl $0 1147; X86-SSE1-NEXT: pushl $32 1148; X86-SSE1-NEXT: pushl $.L.str 1149; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1150; X86-SSE1-NEXT: calll memcmp 1151; X86-SSE1-NEXT: addl $16, %esp 1152; X86-SSE1-NEXT: testl %eax, %eax 1153; X86-SSE1-NEXT: setne %al 1154; X86-SSE1-NEXT: retl 1155; 1156; X86-SSE2-LABEL: length32_eq_const: 1157; X86-SSE2: # %bb.0: 1158; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 1159; X86-SSE2-NEXT: movdqu (%eax), %xmm0 1160; X86-SSE2-NEXT: movdqu 16(%eax), %xmm1 1161; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm1 1162; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 1163; X86-SSE2-NEXT: pand %xmm1, %xmm0 1164; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 1165; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1166; X86-SSE2-NEXT: setne %al 1167; X86-SSE2-NEXT: retl 1168; 1169; X64-SSE2-LABEL: length32_eq_const: 1170; X64-SSE2: # %bb.0: 1171; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 1172; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 1173; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm1 1174; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 1175; X64-SSE2-NEXT: pand %xmm1, %xmm0 1176; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 1177; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1178; X64-SSE2-NEXT: setne %al 1179; X64-SSE2-NEXT: retq 1180; 1181; X64-AVX1-LABEL: length32_eq_const: 1182; X64-AVX1: # %bb.0: 1183; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 1184; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1185; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm1, %xmm1 1186; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 1187; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 1188; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 1189; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1190; X64-AVX1-NEXT: setne %al 1191; X64-AVX1-NEXT: retq 1192; 1193; X64-AVX2-LABEL: length32_eq_const: 1194; X64-AVX2: # %bb.0: 1195; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1196; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 1197; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1198; X64-AVX2-NEXT: cmpl $-1, %eax 1199; X64-AVX2-NEXT: setne %al 1200; X64-AVX2-NEXT: vzeroupper 1201; X64-AVX2-NEXT: retq 1202 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind 1203 %c = icmp ne i32 %m, 0 1204 ret i1 %c 1205} 1206 1207define i32 @length64(i8* %X, i8* %Y) nounwind { 1208; X86-LABEL: length64: 1209; X86: # %bb.0: 1210; X86-NEXT: pushl $0 1211; X86-NEXT: pushl $64 1212; X86-NEXT: pushl {{[0-9]+}}(%esp) 1213; X86-NEXT: pushl {{[0-9]+}}(%esp) 1214; X86-NEXT: calll memcmp 1215; X86-NEXT: addl $16, %esp 1216; X86-NEXT: retl 1217; 1218; X64-LABEL: length64: 1219; X64: # %bb.0: 1220; X64-NEXT: movl $64, %edx 1221; X64-NEXT: jmp memcmp # TAILCALL 1222 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind 1223 ret i32 %m 1224} 1225 1226define i1 @length64_eq(i8* %x, i8* %y) nounwind { 1227; X86-LABEL: length64_eq: 1228; X86: # %bb.0: 1229; X86-NEXT: pushl $0 1230; X86-NEXT: pushl $64 1231; X86-NEXT: pushl {{[0-9]+}}(%esp) 1232; X86-NEXT: pushl {{[0-9]+}}(%esp) 1233; X86-NEXT: calll memcmp 1234; X86-NEXT: addl $16, %esp 1235; X86-NEXT: testl %eax, %eax 1236; X86-NEXT: setne %al 1237; X86-NEXT: retl 1238; 1239; X64-SSE2-LABEL: length64_eq: 1240; X64-SSE2: # %bb.0: 1241; X64-SSE2-NEXT: pushq %rax 1242; X64-SSE2-NEXT: movl $64, %edx 1243; X64-SSE2-NEXT: callq memcmp 1244; X64-SSE2-NEXT: testl %eax, %eax 1245; X64-SSE2-NEXT: setne %al 1246; X64-SSE2-NEXT: popq %rcx 1247; X64-SSE2-NEXT: retq 1248; 1249; X64-AVX1-LABEL: length64_eq: 1250; X64-AVX1: # %bb.0: 1251; X64-AVX1-NEXT: pushq %rax 1252; X64-AVX1-NEXT: movl $64, %edx 1253; X64-AVX1-NEXT: callq memcmp 1254; X64-AVX1-NEXT: testl %eax, %eax 1255; X64-AVX1-NEXT: setne %al 1256; X64-AVX1-NEXT: popq %rcx 1257; X64-AVX1-NEXT: retq 1258; 1259; X64-AVX2-LABEL: length64_eq: 1260; X64-AVX2: # %bb.0: 1261; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1262; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1263; X64-AVX2-NEXT: vpcmpeqb 32(%rsi), %ymm1, %ymm1 1264; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 1265; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1266; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1267; X64-AVX2-NEXT: cmpl $-1, %eax 1268; X64-AVX2-NEXT: setne %al 1269; X64-AVX2-NEXT: vzeroupper 1270; X64-AVX2-NEXT: retq 1271 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind 1272 %cmp = icmp ne i32 %call, 0 1273 ret i1 %cmp 1274} 1275 1276define i1 @length64_eq_const(i8* %X) nounwind { 1277; X86-LABEL: length64_eq_const: 1278; X86: # %bb.0: 1279; X86-NEXT: pushl $0 1280; X86-NEXT: pushl $64 1281; X86-NEXT: pushl $.L.str 1282; X86-NEXT: pushl {{[0-9]+}}(%esp) 1283; X86-NEXT: calll memcmp 1284; X86-NEXT: addl $16, %esp 1285; X86-NEXT: testl %eax, %eax 1286; X86-NEXT: sete %al 1287; X86-NEXT: retl 1288; 1289; X64-SSE2-LABEL: length64_eq_const: 1290; X64-SSE2: # %bb.0: 1291; X64-SSE2-NEXT: pushq %rax 1292; X64-SSE2-NEXT: movl $.L.str, %esi 1293; X64-SSE2-NEXT: movl $64, %edx 1294; X64-SSE2-NEXT: callq memcmp 1295; X64-SSE2-NEXT: testl %eax, %eax 1296; X64-SSE2-NEXT: sete %al 1297; X64-SSE2-NEXT: popq %rcx 1298; X64-SSE2-NEXT: retq 1299; 1300; X64-AVX1-LABEL: length64_eq_const: 1301; X64-AVX1: # %bb.0: 1302; X64-AVX1-NEXT: pushq %rax 1303; X64-AVX1-NEXT: movl $.L.str, %esi 1304; X64-AVX1-NEXT: movl $64, %edx 1305; X64-AVX1-NEXT: callq memcmp 1306; X64-AVX1-NEXT: testl %eax, %eax 1307; X64-AVX1-NEXT: sete %al 1308; X64-AVX1-NEXT: popq %rcx 1309; X64-AVX1-NEXT: retq 1310; 1311; X64-AVX2-LABEL: length64_eq_const: 1312; X64-AVX2: # %bb.0: 1313; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1314; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1315; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm1, %ymm1 1316; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 1317; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1318; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1319; X64-AVX2-NEXT: cmpl $-1, %eax 1320; X64-AVX2-NEXT: sete %al 1321; X64-AVX2-NEXT: vzeroupper 1322; X64-AVX2-NEXT: retq 1323 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind 1324 %c = icmp eq i32 %m, 0 1325 ret i1 %c 1326} 1327 1328; This checks that we do not do stupid things with huge sizes. 1329define i32 @huge_length(i8* %X, i8* %Y) nounwind { 1330; X86-LABEL: huge_length: 1331; X86: # %bb.0: 1332; X86-NEXT: pushl $2147483647 # imm = 0x7FFFFFFF 1333; X86-NEXT: pushl $-1 1334; X86-NEXT: pushl {{[0-9]+}}(%esp) 1335; X86-NEXT: pushl {{[0-9]+}}(%esp) 1336; X86-NEXT: calll memcmp 1337; X86-NEXT: addl $16, %esp 1338; X86-NEXT: retl 1339; 1340; X64-LABEL: huge_length: 1341; X64: # %bb.0: 1342; X64-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 1343; X64-NEXT: jmp memcmp # TAILCALL 1344 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind 1345 ret i32 %m 1346} 1347