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: pushl $0 366; X86-NEXT: pushl $7 367; X86-NEXT: pushl {{[0-9]+}}(%esp) 368; X86-NEXT: pushl {{[0-9]+}}(%esp) 369; X86-NEXT: calll memcmp 370; X86-NEXT: addl $16, %esp 371; X86-NEXT: testl %eax, %eax 372; X86-NEXT: setne %al 373; X86-NEXT: retl 374; 375; X64-LABEL: length7_eq: 376; X64: # %bb.0: 377; X64-NEXT: pushq %rax 378; X64-NEXT: movl $7, %edx 379; X64-NEXT: callq memcmp 380; X64-NEXT: testl %eax, %eax 381; X64-NEXT: setne %al 382; X64-NEXT: popq %rcx 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: pushq %rax 552; X64-NEXT: movl $11, %edx 553; X64-NEXT: callq memcmp 554; X64-NEXT: testl %eax, %eax 555; X64-NEXT: sete %al 556; X64-NEXT: popq %rcx 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: pushq %rax 644; X64-NEXT: movl $13, %edx 645; X64-NEXT: callq memcmp 646; X64-NEXT: testl %eax, %eax 647; X64-NEXT: sete %al 648; X64-NEXT: popq %rcx 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: pushq %rax 671; X64-NEXT: movl $14, %edx 672; X64-NEXT: callq memcmp 673; X64-NEXT: testl %eax, %eax 674; X64-NEXT: sete %al 675; X64-NEXT: popq %rcx 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: pushq %rax 698; X64-NEXT: movl $15, %edx 699; X64-NEXT: callq memcmp 700; X64-NEXT: testl %eax, %eax 701; X64-NEXT: sete %al 702; X64-NEXT: popq %rcx 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-LABEL: length24_eq: 889; X86: # %bb.0: 890; X86-NEXT: pushl $0 891; X86-NEXT: pushl $24 892; X86-NEXT: pushl {{[0-9]+}}(%esp) 893; X86-NEXT: pushl {{[0-9]+}}(%esp) 894; X86-NEXT: calll memcmp 895; X86-NEXT: addl $16, %esp 896; X86-NEXT: testl %eax, %eax 897; X86-NEXT: sete %al 898; X86-NEXT: retl 899; 900; X64-SSE2-LABEL: length24_eq: 901; X64-SSE2: # %bb.0: 902; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 903; X64-SSE2-NEXT: movdqu (%rsi), %xmm1 904; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 905; X64-SSE2-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 906; X64-SSE2-NEXT: movq {{.*#+}} xmm2 = mem[0],zero 907; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 908; X64-SSE2-NEXT: pand %xmm1, %xmm2 909; X64-SSE2-NEXT: pmovmskb %xmm2, %eax 910; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 911; X64-SSE2-NEXT: sete %al 912; X64-SSE2-NEXT: retq 913; 914; X64-AVX-LABEL: length24_eq: 915; X64-AVX: # %bb.0: 916; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 917; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 918; X64-AVX-NEXT: vmovq {{.*#+}} xmm2 = mem[0],zero 919; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 920; X64-AVX-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 921; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 922; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 923; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 924; X64-AVX-NEXT: sete %al 925; X64-AVX-NEXT: retq 926 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind 927 %cmp = icmp eq i32 %call, 0 928 ret i1 %cmp 929} 930 931define i1 @length24_eq_const(i8* %X) nounwind { 932; X86-LABEL: length24_eq_const: 933; X86: # %bb.0: 934; X86-NEXT: pushl $0 935; X86-NEXT: pushl $24 936; X86-NEXT: pushl $.L.str 937; X86-NEXT: pushl {{[0-9]+}}(%esp) 938; X86-NEXT: calll memcmp 939; X86-NEXT: addl $16, %esp 940; X86-NEXT: testl %eax, %eax 941; X86-NEXT: setne %al 942; X86-NEXT: retl 943; 944; X64-SSE2-LABEL: length24_eq_const: 945; X64-SSE2: # %bb.0: 946; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 947; X64-SSE2-NEXT: movq {{.*#+}} xmm1 = mem[0],zero 948; X64-SSE2-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 949; X64-SSE2-NEXT: movq %rax, %xmm2 950; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm2 951; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 952; X64-SSE2-NEXT: pand %xmm2, %xmm0 953; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 954; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 955; X64-SSE2-NEXT: setne %al 956; X64-SSE2-NEXT: retq 957; 958; X64-AVX-LABEL: length24_eq_const: 959; X64-AVX: # %bb.0: 960; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 961; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 962; X64-AVX-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 963; X64-AVX-NEXT: vmovq %rax, %xmm2 964; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 965; X64-AVX-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 966; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 967; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 968; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 969; X64-AVX-NEXT: setne %al 970; X64-AVX-NEXT: retq 971 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind 972 %c = icmp ne i32 %m, 0 973 ret i1 %c 974} 975 976define i32 @length32(i8* %X, i8* %Y) nounwind { 977; X86-LABEL: length32: 978; X86: # %bb.0: 979; X86-NEXT: pushl $0 980; X86-NEXT: pushl $32 981; X86-NEXT: pushl {{[0-9]+}}(%esp) 982; X86-NEXT: pushl {{[0-9]+}}(%esp) 983; X86-NEXT: calll memcmp 984; X86-NEXT: addl $16, %esp 985; X86-NEXT: retl 986; 987; X64-LABEL: length32: 988; X64: # %bb.0: 989; X64-NEXT: movl $32, %edx 990; X64-NEXT: jmp memcmp # TAILCALL 991 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind 992 ret i32 %m 993} 994 995; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 996 997define i1 @length32_eq(i8* %x, i8* %y) nounwind { 998; X86-NOSSE-LABEL: length32_eq: 999; X86-NOSSE: # %bb.0: 1000; X86-NOSSE-NEXT: pushl $0 1001; X86-NOSSE-NEXT: pushl $32 1002; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1003; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1004; X86-NOSSE-NEXT: calll memcmp 1005; X86-NOSSE-NEXT: addl $16, %esp 1006; X86-NOSSE-NEXT: testl %eax, %eax 1007; X86-NOSSE-NEXT: sete %al 1008; X86-NOSSE-NEXT: retl 1009; 1010; X86-SSE1-LABEL: length32_eq: 1011; X86-SSE1: # %bb.0: 1012; X86-SSE1-NEXT: pushl $0 1013; X86-SSE1-NEXT: pushl $32 1014; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1015; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1016; X86-SSE1-NEXT: calll memcmp 1017; X86-SSE1-NEXT: addl $16, %esp 1018; X86-SSE1-NEXT: testl %eax, %eax 1019; X86-SSE1-NEXT: sete %al 1020; X86-SSE1-NEXT: retl 1021; 1022; X86-SSE2-LABEL: length32_eq: 1023; X86-SSE2: # %bb.0: 1024; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 1025; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 1026; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 1027; X86-SSE2-NEXT: movdqu 16(%ecx), %xmm1 1028; X86-SSE2-NEXT: movdqu (%eax), %xmm2 1029; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 1030; X86-SSE2-NEXT: movdqu 16(%eax), %xmm0 1031; X86-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 1032; X86-SSE2-NEXT: pand %xmm2, %xmm0 1033; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 1034; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1035; X86-SSE2-NEXT: sete %al 1036; X86-SSE2-NEXT: retl 1037; 1038; X64-SSE2-LABEL: length32_eq: 1039; X64-SSE2: # %bb.0: 1040; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 1041; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 1042; X64-SSE2-NEXT: movdqu (%rsi), %xmm2 1043; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 1044; X64-SSE2-NEXT: movdqu 16(%rsi), %xmm0 1045; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 1046; X64-SSE2-NEXT: pand %xmm2, %xmm0 1047; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 1048; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1049; X64-SSE2-NEXT: sete %al 1050; X64-SSE2-NEXT: retq 1051; 1052; X64-AVX1-LABEL: length32_eq: 1053; X64-AVX1: # %bb.0: 1054; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 1055; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1056; X64-AVX1-NEXT: vpcmpeqb 16(%rsi), %xmm1, %xmm1 1057; X64-AVX1-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 1058; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 1059; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 1060; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1061; X64-AVX1-NEXT: sete %al 1062; X64-AVX1-NEXT: retq 1063; 1064; X64-AVX2-LABEL: length32_eq: 1065; X64-AVX2: # %bb.0: 1066; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1067; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 1068; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1069; X64-AVX2-NEXT: cmpl $-1, %eax 1070; X64-AVX2-NEXT: sete %al 1071; X64-AVX2-NEXT: vzeroupper 1072; X64-AVX2-NEXT: retq 1073 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind 1074 %cmp = icmp eq i32 %call, 0 1075 ret i1 %cmp 1076} 1077 1078define i1 @length32_eq_const(i8* %X) nounwind { 1079; X86-NOSSE-LABEL: length32_eq_const: 1080; X86-NOSSE: # %bb.0: 1081; X86-NOSSE-NEXT: pushl $0 1082; X86-NOSSE-NEXT: pushl $32 1083; X86-NOSSE-NEXT: pushl $.L.str 1084; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 1085; X86-NOSSE-NEXT: calll memcmp 1086; X86-NOSSE-NEXT: addl $16, %esp 1087; X86-NOSSE-NEXT: testl %eax, %eax 1088; X86-NOSSE-NEXT: setne %al 1089; X86-NOSSE-NEXT: retl 1090; 1091; X86-SSE1-LABEL: length32_eq_const: 1092; X86-SSE1: # %bb.0: 1093; X86-SSE1-NEXT: pushl $0 1094; X86-SSE1-NEXT: pushl $32 1095; X86-SSE1-NEXT: pushl $.L.str 1096; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 1097; X86-SSE1-NEXT: calll memcmp 1098; X86-SSE1-NEXT: addl $16, %esp 1099; X86-SSE1-NEXT: testl %eax, %eax 1100; X86-SSE1-NEXT: setne %al 1101; X86-SSE1-NEXT: retl 1102; 1103; X86-SSE2-LABEL: length32_eq_const: 1104; X86-SSE2: # %bb.0: 1105; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 1106; X86-SSE2-NEXT: movdqu (%eax), %xmm0 1107; X86-SSE2-NEXT: movdqu 16(%eax), %xmm1 1108; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm1 1109; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 1110; X86-SSE2-NEXT: pand %xmm1, %xmm0 1111; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 1112; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1113; X86-SSE2-NEXT: setne %al 1114; X86-SSE2-NEXT: retl 1115; 1116; X64-SSE2-LABEL: length32_eq_const: 1117; X64-SSE2: # %bb.0: 1118; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 1119; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 1120; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm1 1121; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 1122; X64-SSE2-NEXT: pand %xmm1, %xmm0 1123; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 1124; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1125; X64-SSE2-NEXT: setne %al 1126; X64-SSE2-NEXT: retq 1127; 1128; X64-AVX1-LABEL: length32_eq_const: 1129; X64-AVX1: # %bb.0: 1130; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 1131; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1132; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm1, %xmm1 1133; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 1134; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 1135; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 1136; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 1137; X64-AVX1-NEXT: setne %al 1138; X64-AVX1-NEXT: retq 1139; 1140; X64-AVX2-LABEL: length32_eq_const: 1141; X64-AVX2: # %bb.0: 1142; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1143; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 1144; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1145; X64-AVX2-NEXT: cmpl $-1, %eax 1146; X64-AVX2-NEXT: setne %al 1147; X64-AVX2-NEXT: vzeroupper 1148; X64-AVX2-NEXT: retq 1149 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind 1150 %c = icmp ne i32 %m, 0 1151 ret i1 %c 1152} 1153 1154define i32 @length64(i8* %X, i8* %Y) nounwind { 1155; X86-LABEL: length64: 1156; X86: # %bb.0: 1157; X86-NEXT: pushl $0 1158; X86-NEXT: pushl $64 1159; X86-NEXT: pushl {{[0-9]+}}(%esp) 1160; X86-NEXT: pushl {{[0-9]+}}(%esp) 1161; X86-NEXT: calll memcmp 1162; X86-NEXT: addl $16, %esp 1163; X86-NEXT: retl 1164; 1165; X64-LABEL: length64: 1166; X64: # %bb.0: 1167; X64-NEXT: movl $64, %edx 1168; X64-NEXT: jmp memcmp # TAILCALL 1169 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind 1170 ret i32 %m 1171} 1172 1173define i1 @length64_eq(i8* %x, i8* %y) nounwind { 1174; X86-LABEL: length64_eq: 1175; X86: # %bb.0: 1176; X86-NEXT: pushl $0 1177; X86-NEXT: pushl $64 1178; X86-NEXT: pushl {{[0-9]+}}(%esp) 1179; X86-NEXT: pushl {{[0-9]+}}(%esp) 1180; X86-NEXT: calll memcmp 1181; X86-NEXT: addl $16, %esp 1182; X86-NEXT: testl %eax, %eax 1183; X86-NEXT: setne %al 1184; X86-NEXT: retl 1185; 1186; X64-SSE2-LABEL: length64_eq: 1187; X64-SSE2: # %bb.0: 1188; X64-SSE2-NEXT: pushq %rax 1189; X64-SSE2-NEXT: movl $64, %edx 1190; X64-SSE2-NEXT: callq memcmp 1191; X64-SSE2-NEXT: testl %eax, %eax 1192; X64-SSE2-NEXT: setne %al 1193; X64-SSE2-NEXT: popq %rcx 1194; X64-SSE2-NEXT: retq 1195; 1196; X64-AVX1-LABEL: length64_eq: 1197; X64-AVX1: # %bb.0: 1198; X64-AVX1-NEXT: pushq %rax 1199; X64-AVX1-NEXT: movl $64, %edx 1200; X64-AVX1-NEXT: callq memcmp 1201; X64-AVX1-NEXT: testl %eax, %eax 1202; X64-AVX1-NEXT: setne %al 1203; X64-AVX1-NEXT: popq %rcx 1204; X64-AVX1-NEXT: retq 1205; 1206; X64-AVX2-LABEL: length64_eq: 1207; X64-AVX2: # %bb.0: 1208; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1209; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1210; X64-AVX2-NEXT: vpcmpeqb 32(%rsi), %ymm1, %ymm1 1211; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 1212; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1213; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1214; X64-AVX2-NEXT: cmpl $-1, %eax 1215; X64-AVX2-NEXT: setne %al 1216; X64-AVX2-NEXT: vzeroupper 1217; X64-AVX2-NEXT: retq 1218 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind 1219 %cmp = icmp ne i32 %call, 0 1220 ret i1 %cmp 1221} 1222 1223define i1 @length64_eq_const(i8* %X) nounwind { 1224; X86-LABEL: length64_eq_const: 1225; X86: # %bb.0: 1226; X86-NEXT: pushl $0 1227; X86-NEXT: pushl $64 1228; X86-NEXT: pushl $.L.str 1229; X86-NEXT: pushl {{[0-9]+}}(%esp) 1230; X86-NEXT: calll memcmp 1231; X86-NEXT: addl $16, %esp 1232; X86-NEXT: testl %eax, %eax 1233; X86-NEXT: sete %al 1234; X86-NEXT: retl 1235; 1236; X64-SSE2-LABEL: length64_eq_const: 1237; X64-SSE2: # %bb.0: 1238; X64-SSE2-NEXT: pushq %rax 1239; X64-SSE2-NEXT: movl $.L.str, %esi 1240; X64-SSE2-NEXT: movl $64, %edx 1241; X64-SSE2-NEXT: callq memcmp 1242; X64-SSE2-NEXT: testl %eax, %eax 1243; X64-SSE2-NEXT: sete %al 1244; X64-SSE2-NEXT: popq %rcx 1245; X64-SSE2-NEXT: retq 1246; 1247; X64-AVX1-LABEL: length64_eq_const: 1248; X64-AVX1: # %bb.0: 1249; X64-AVX1-NEXT: pushq %rax 1250; X64-AVX1-NEXT: movl $.L.str, %esi 1251; X64-AVX1-NEXT: movl $64, %edx 1252; X64-AVX1-NEXT: callq memcmp 1253; X64-AVX1-NEXT: testl %eax, %eax 1254; X64-AVX1-NEXT: sete %al 1255; X64-AVX1-NEXT: popq %rcx 1256; X64-AVX1-NEXT: retq 1257; 1258; X64-AVX2-LABEL: length64_eq_const: 1259; X64-AVX2: # %bb.0: 1260; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1261; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1262; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm1, %ymm1 1263; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 1264; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1265; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1266; X64-AVX2-NEXT: cmpl $-1, %eax 1267; X64-AVX2-NEXT: sete %al 1268; X64-AVX2-NEXT: vzeroupper 1269; X64-AVX2-NEXT: retq 1270 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind 1271 %c = icmp eq i32 %m, 0 1272 ret i1 %c 1273} 1274 1275; This checks that we do not do stupid things with huge sizes. 1276define i32 @huge_length(i8* %X, i8* %Y) nounwind { 1277; X86-LABEL: huge_length: 1278; X86: # %bb.0: 1279; X86-NEXT: pushl $2147483647 # imm = 0x7FFFFFFF 1280; X86-NEXT: pushl $-1 1281; X86-NEXT: pushl {{[0-9]+}}(%esp) 1282; X86-NEXT: pushl {{[0-9]+}}(%esp) 1283; X86-NEXT: calll memcmp 1284; X86-NEXT: addl $16, %esp 1285; X86-NEXT: retl 1286; 1287; X64-LABEL: huge_length: 1288; X64: # %bb.0: 1289; X64-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 1290; X64-NEXT: jmp memcmp # TAILCALL 1291 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind 1292 ret i32 %m 1293} 1294