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 i32 @length8(i8* %X, i8* %Y) nounwind { 363; X86-LABEL: length8: 364; X86: # %bb.0: 365; X86-NEXT: pushl %esi 366; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 367; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 368; X86-NEXT: movl (%esi), %ecx 369; X86-NEXT: movl (%eax), %edx 370; X86-NEXT: bswapl %ecx 371; X86-NEXT: bswapl %edx 372; X86-NEXT: cmpl %edx, %ecx 373; X86-NEXT: jne .LBB13_2 374; X86-NEXT: # %bb.1: # %loadbb1 375; X86-NEXT: movl 4(%esi), %ecx 376; X86-NEXT: movl 4(%eax), %edx 377; X86-NEXT: bswapl %ecx 378; X86-NEXT: bswapl %edx 379; X86-NEXT: xorl %eax, %eax 380; X86-NEXT: cmpl %edx, %ecx 381; X86-NEXT: je .LBB13_3 382; X86-NEXT: .LBB13_2: # %res_block 383; X86-NEXT: xorl %eax, %eax 384; X86-NEXT: cmpl %edx, %ecx 385; X86-NEXT: setae %al 386; X86-NEXT: leal -1(%eax,%eax), %eax 387; X86-NEXT: .LBB13_3: # %endblock 388; X86-NEXT: popl %esi 389; X86-NEXT: retl 390; 391; X64-LABEL: length8: 392; X64: # %bb.0: 393; X64-NEXT: movq (%rdi), %rcx 394; X64-NEXT: movq (%rsi), %rdx 395; X64-NEXT: bswapq %rcx 396; X64-NEXT: bswapq %rdx 397; X64-NEXT: xorl %eax, %eax 398; X64-NEXT: cmpq %rdx, %rcx 399; X64-NEXT: seta %al 400; X64-NEXT: sbbl $0, %eax 401; X64-NEXT: retq 402 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 403 ret i32 %m 404} 405 406define i1 @length8_eq(i8* %X, i8* %Y) nounwind { 407; X86-LABEL: length8_eq: 408; X86: # %bb.0: 409; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 410; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 411; X86-NEXT: movl (%ecx), %edx 412; X86-NEXT: movl 4(%ecx), %ecx 413; X86-NEXT: xorl (%eax), %edx 414; X86-NEXT: xorl 4(%eax), %ecx 415; X86-NEXT: orl %edx, %ecx 416; X86-NEXT: sete %al 417; X86-NEXT: retl 418; 419; X64-LABEL: length8_eq: 420; X64: # %bb.0: 421; X64-NEXT: movq (%rdi), %rax 422; X64-NEXT: cmpq (%rsi), %rax 423; X64-NEXT: sete %al 424; X64-NEXT: retq 425 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 426 %c = icmp eq i32 %m, 0 427 ret i1 %c 428} 429 430define i1 @length8_eq_const(i8* %X) nounwind { 431; X86-LABEL: length8_eq_const: 432; X86: # %bb.0: 433; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 434; X86-NEXT: movl $858927408, %ecx # imm = 0x33323130 435; X86-NEXT: xorl (%eax), %ecx 436; X86-NEXT: movl $926299444, %edx # imm = 0x37363534 437; X86-NEXT: xorl 4(%eax), %edx 438; X86-NEXT: orl %ecx, %edx 439; X86-NEXT: setne %al 440; X86-NEXT: retl 441; 442; X64-LABEL: length8_eq_const: 443; X64: # %bb.0: 444; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130 445; X64-NEXT: cmpq %rax, (%rdi) 446; X64-NEXT: setne %al 447; X64-NEXT: retq 448 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind 449 %c = icmp ne i32 %m, 0 450 ret i1 %c 451} 452 453define i1 @length12_eq(i8* %X, i8* %Y) nounwind { 454; X86-LABEL: length12_eq: 455; X86: # %bb.0: 456; X86-NEXT: pushl $0 457; X86-NEXT: pushl $12 458; X86-NEXT: pushl {{[0-9]+}}(%esp) 459; X86-NEXT: pushl {{[0-9]+}}(%esp) 460; X86-NEXT: calll memcmp 461; X86-NEXT: addl $16, %esp 462; X86-NEXT: testl %eax, %eax 463; X86-NEXT: setne %al 464; X86-NEXT: retl 465; 466; X64-LABEL: length12_eq: 467; X64: # %bb.0: 468; X64-NEXT: movq (%rdi), %rax 469; X64-NEXT: xorq (%rsi), %rax 470; X64-NEXT: movl 8(%rdi), %ecx 471; X64-NEXT: xorl 8(%rsi), %ecx 472; X64-NEXT: orq %rax, %rcx 473; X64-NEXT: setne %al 474; X64-NEXT: retq 475 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 476 %c = icmp ne i32 %m, 0 477 ret i1 %c 478} 479 480define i32 @length12(i8* %X, i8* %Y) nounwind { 481; X86-LABEL: length12: 482; X86: # %bb.0: 483; X86-NEXT: pushl $0 484; X86-NEXT: pushl $12 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: retl 490; 491; X64-LABEL: length12: 492; X64: # %bb.0: 493; X64-NEXT: movq (%rdi), %rcx 494; X64-NEXT: movq (%rsi), %rdx 495; X64-NEXT: bswapq %rcx 496; X64-NEXT: bswapq %rdx 497; X64-NEXT: cmpq %rdx, %rcx 498; X64-NEXT: jne .LBB17_2 499; X64-NEXT: # %bb.1: # %loadbb1 500; X64-NEXT: movl 8(%rdi), %ecx 501; X64-NEXT: movl 8(%rsi), %edx 502; X64-NEXT: bswapl %ecx 503; X64-NEXT: bswapl %edx 504; X64-NEXT: xorl %eax, %eax 505; X64-NEXT: cmpq %rdx, %rcx 506; X64-NEXT: je .LBB17_3 507; X64-NEXT: .LBB17_2: # %res_block 508; X64-NEXT: xorl %eax, %eax 509; X64-NEXT: cmpq %rdx, %rcx 510; X64-NEXT: setae %al 511; X64-NEXT: leal -1(%rax,%rax), %eax 512; X64-NEXT: .LBB17_3: # %endblock 513; X64-NEXT: retq 514 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 515 ret i32 %m 516} 517 518; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329 519 520define i32 @length16(i8* %X, i8* %Y) nounwind { 521; X86-LABEL: length16: 522; X86: # %bb.0: 523; X86-NEXT: pushl $0 524; X86-NEXT: pushl $16 525; X86-NEXT: pushl {{[0-9]+}}(%esp) 526; X86-NEXT: pushl {{[0-9]+}}(%esp) 527; X86-NEXT: calll memcmp 528; X86-NEXT: addl $16, %esp 529; X86-NEXT: retl 530; 531; X64-LABEL: length16: 532; X64: # %bb.0: 533; X64-NEXT: movq (%rdi), %rcx 534; X64-NEXT: movq (%rsi), %rdx 535; X64-NEXT: bswapq %rcx 536; X64-NEXT: bswapq %rdx 537; X64-NEXT: cmpq %rdx, %rcx 538; X64-NEXT: jne .LBB18_2 539; X64-NEXT: # %bb.1: # %loadbb1 540; X64-NEXT: movq 8(%rdi), %rcx 541; X64-NEXT: movq 8(%rsi), %rdx 542; X64-NEXT: bswapq %rcx 543; X64-NEXT: bswapq %rdx 544; X64-NEXT: xorl %eax, %eax 545; X64-NEXT: cmpq %rdx, %rcx 546; X64-NEXT: je .LBB18_3 547; X64-NEXT: .LBB18_2: # %res_block 548; X64-NEXT: xorl %eax, %eax 549; X64-NEXT: cmpq %rdx, %rcx 550; X64-NEXT: setae %al 551; X64-NEXT: leal -1(%rax,%rax), %eax 552; X64-NEXT: .LBB18_3: # %endblock 553; X64-NEXT: retq 554 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind 555 ret i32 %m 556} 557 558define i1 @length16_eq(i8* %x, i8* %y) nounwind { 559; X86-NOSSE-LABEL: length16_eq: 560; X86-NOSSE: # %bb.0: 561; X86-NOSSE-NEXT: pushl $0 562; X86-NOSSE-NEXT: pushl $16 563; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 564; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 565; X86-NOSSE-NEXT: calll memcmp 566; X86-NOSSE-NEXT: addl $16, %esp 567; X86-NOSSE-NEXT: testl %eax, %eax 568; X86-NOSSE-NEXT: setne %al 569; X86-NOSSE-NEXT: retl 570; 571; X86-SSE1-LABEL: length16_eq: 572; X86-SSE1: # %bb.0: 573; X86-SSE1-NEXT: pushl $0 574; X86-SSE1-NEXT: pushl $16 575; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 576; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 577; X86-SSE1-NEXT: calll memcmp 578; X86-SSE1-NEXT: addl $16, %esp 579; X86-SSE1-NEXT: testl %eax, %eax 580; X86-SSE1-NEXT: setne %al 581; X86-SSE1-NEXT: retl 582; 583; X86-SSE2-LABEL: length16_eq: 584; X86-SSE2: # %bb.0: 585; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 586; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 587; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 588; X86-SSE2-NEXT: movdqu (%eax), %xmm1 589; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 590; X86-SSE2-NEXT: pmovmskb %xmm1, %eax 591; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 592; X86-SSE2-NEXT: setne %al 593; X86-SSE2-NEXT: retl 594; 595; X64-SSE2-LABEL: length16_eq: 596; X64-SSE2: # %bb.0: 597; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 598; X64-SSE2-NEXT: movdqu (%rsi), %xmm1 599; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 600; X64-SSE2-NEXT: pmovmskb %xmm1, %eax 601; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 602; X64-SSE2-NEXT: setne %al 603; X64-SSE2-NEXT: retq 604; 605; X64-AVX-LABEL: length16_eq: 606; X64-AVX: # %bb.0: 607; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 608; X64-AVX-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 609; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 610; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 611; X64-AVX-NEXT: setne %al 612; X64-AVX-NEXT: retq 613 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind 614 %cmp = icmp ne i32 %call, 0 615 ret i1 %cmp 616} 617 618define i1 @length16_eq_const(i8* %X) nounwind { 619; X86-NOSSE-LABEL: length16_eq_const: 620; X86-NOSSE: # %bb.0: 621; X86-NOSSE-NEXT: pushl $0 622; X86-NOSSE-NEXT: pushl $16 623; X86-NOSSE-NEXT: pushl $.L.str 624; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 625; X86-NOSSE-NEXT: calll memcmp 626; X86-NOSSE-NEXT: addl $16, %esp 627; X86-NOSSE-NEXT: testl %eax, %eax 628; X86-NOSSE-NEXT: sete %al 629; X86-NOSSE-NEXT: retl 630; 631; X86-SSE1-LABEL: length16_eq_const: 632; X86-SSE1: # %bb.0: 633; X86-SSE1-NEXT: pushl $0 634; X86-SSE1-NEXT: pushl $16 635; X86-SSE1-NEXT: pushl $.L.str 636; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 637; X86-SSE1-NEXT: calll memcmp 638; X86-SSE1-NEXT: addl $16, %esp 639; X86-SSE1-NEXT: testl %eax, %eax 640; X86-SSE1-NEXT: sete %al 641; X86-SSE1-NEXT: retl 642; 643; X86-SSE2-LABEL: length16_eq_const: 644; X86-SSE2: # %bb.0: 645; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 646; X86-SSE2-NEXT: movdqu (%eax), %xmm0 647; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 648; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 649; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 650; X86-SSE2-NEXT: sete %al 651; X86-SSE2-NEXT: retl 652; 653; X64-SSE2-LABEL: length16_eq_const: 654; X64-SSE2: # %bb.0: 655; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 656; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 657; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 658; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 659; X64-SSE2-NEXT: sete %al 660; X64-SSE2-NEXT: retq 661; 662; X64-AVX-LABEL: length16_eq_const: 663; X64-AVX: # %bb.0: 664; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 665; X64-AVX-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 666; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 667; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 668; X64-AVX-NEXT: sete %al 669; X64-AVX-NEXT: retq 670 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind 671 %c = icmp eq i32 %m, 0 672 ret i1 %c 673} 674 675; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914 676 677define i32 @length24(i8* %X, i8* %Y) nounwind { 678; X86-LABEL: length24: 679; X86: # %bb.0: 680; X86-NEXT: pushl $0 681; X86-NEXT: pushl $24 682; X86-NEXT: pushl {{[0-9]+}}(%esp) 683; X86-NEXT: pushl {{[0-9]+}}(%esp) 684; X86-NEXT: calll memcmp 685; X86-NEXT: addl $16, %esp 686; X86-NEXT: retl 687; 688; X64-LABEL: length24: 689; X64: # %bb.0: 690; X64-NEXT: movl $24, %edx 691; X64-NEXT: jmp memcmp # TAILCALL 692 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind 693 ret i32 %m 694} 695 696define i1 @length24_eq(i8* %x, i8* %y) nounwind { 697; X86-LABEL: length24_eq: 698; X86: # %bb.0: 699; X86-NEXT: pushl $0 700; X86-NEXT: pushl $24 701; X86-NEXT: pushl {{[0-9]+}}(%esp) 702; X86-NEXT: pushl {{[0-9]+}}(%esp) 703; X86-NEXT: calll memcmp 704; X86-NEXT: addl $16, %esp 705; X86-NEXT: testl %eax, %eax 706; X86-NEXT: sete %al 707; X86-NEXT: retl 708; 709; X64-SSE2-LABEL: length24_eq: 710; X64-SSE2: # %bb.0: 711; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 712; X64-SSE2-NEXT: movdqu (%rsi), %xmm1 713; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 714; X64-SSE2-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 715; X64-SSE2-NEXT: movq {{.*#+}} xmm2 = mem[0],zero 716; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 717; X64-SSE2-NEXT: pand %xmm1, %xmm2 718; X64-SSE2-NEXT: pmovmskb %xmm2, %eax 719; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 720; X64-SSE2-NEXT: sete %al 721; X64-SSE2-NEXT: retq 722; 723; X64-AVX-LABEL: length24_eq: 724; X64-AVX: # %bb.0: 725; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 726; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 727; X64-AVX-NEXT: vmovq {{.*#+}} xmm2 = mem[0],zero 728; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 729; X64-AVX-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 730; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 731; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 732; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 733; X64-AVX-NEXT: sete %al 734; X64-AVX-NEXT: retq 735 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind 736 %cmp = icmp eq i32 %call, 0 737 ret i1 %cmp 738} 739 740define i1 @length24_eq_const(i8* %X) nounwind { 741; X86-LABEL: length24_eq_const: 742; X86: # %bb.0: 743; X86-NEXT: pushl $0 744; X86-NEXT: pushl $24 745; X86-NEXT: pushl $.L.str 746; X86-NEXT: pushl {{[0-9]+}}(%esp) 747; X86-NEXT: calll memcmp 748; X86-NEXT: addl $16, %esp 749; X86-NEXT: testl %eax, %eax 750; X86-NEXT: setne %al 751; X86-NEXT: retl 752; 753; X64-SSE2-LABEL: length24_eq_const: 754; X64-SSE2: # %bb.0: 755; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 756; X64-SSE2-NEXT: movq {{.*#+}} xmm1 = mem[0],zero 757; X64-SSE2-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 758; X64-SSE2-NEXT: movq %rax, %xmm2 759; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm2 760; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 761; X64-SSE2-NEXT: pand %xmm2, %xmm0 762; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 763; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 764; X64-SSE2-NEXT: setne %al 765; X64-SSE2-NEXT: retq 766; 767; X64-AVX-LABEL: length24_eq_const: 768; X64-AVX: # %bb.0: 769; X64-AVX-NEXT: vmovdqu (%rdi), %xmm0 770; X64-AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 771; X64-AVX-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 772; X64-AVX-NEXT: vmovq %rax, %xmm2 773; X64-AVX-NEXT: vpcmpeqb %xmm2, %xmm1, %xmm1 774; X64-AVX-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 775; X64-AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 776; X64-AVX-NEXT: vpmovmskb %xmm0, %eax 777; X64-AVX-NEXT: cmpl $65535, %eax # imm = 0xFFFF 778; X64-AVX-NEXT: setne %al 779; X64-AVX-NEXT: retq 780 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind 781 %c = icmp ne i32 %m, 0 782 ret i1 %c 783} 784 785define i32 @length32(i8* %X, i8* %Y) nounwind { 786; X86-LABEL: length32: 787; X86: # %bb.0: 788; X86-NEXT: pushl $0 789; X86-NEXT: pushl $32 790; X86-NEXT: pushl {{[0-9]+}}(%esp) 791; X86-NEXT: pushl {{[0-9]+}}(%esp) 792; X86-NEXT: calll memcmp 793; X86-NEXT: addl $16, %esp 794; X86-NEXT: retl 795; 796; X64-LABEL: length32: 797; X64: # %bb.0: 798; X64-NEXT: movl $32, %edx 799; X64-NEXT: jmp memcmp # TAILCALL 800 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind 801 ret i32 %m 802} 803 804; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 805 806define i1 @length32_eq(i8* %x, i8* %y) nounwind { 807; X86-NOSSE-LABEL: length32_eq: 808; X86-NOSSE: # %bb.0: 809; X86-NOSSE-NEXT: pushl $0 810; X86-NOSSE-NEXT: pushl $32 811; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 812; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 813; X86-NOSSE-NEXT: calll memcmp 814; X86-NOSSE-NEXT: addl $16, %esp 815; X86-NOSSE-NEXT: testl %eax, %eax 816; X86-NOSSE-NEXT: sete %al 817; X86-NOSSE-NEXT: retl 818; 819; X86-SSE1-LABEL: length32_eq: 820; X86-SSE1: # %bb.0: 821; X86-SSE1-NEXT: pushl $0 822; X86-SSE1-NEXT: pushl $32 823; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 824; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 825; X86-SSE1-NEXT: calll memcmp 826; X86-SSE1-NEXT: addl $16, %esp 827; X86-SSE1-NEXT: testl %eax, %eax 828; X86-SSE1-NEXT: sete %al 829; X86-SSE1-NEXT: retl 830; 831; X86-SSE2-LABEL: length32_eq: 832; X86-SSE2: # %bb.0: 833; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 834; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 835; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 836; X86-SSE2-NEXT: movdqu 16(%ecx), %xmm1 837; X86-SSE2-NEXT: movdqu (%eax), %xmm2 838; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 839; X86-SSE2-NEXT: movdqu 16(%eax), %xmm0 840; X86-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 841; X86-SSE2-NEXT: pand %xmm2, %xmm0 842; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 843; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 844; X86-SSE2-NEXT: sete %al 845; X86-SSE2-NEXT: retl 846; 847; X64-SSE2-LABEL: length32_eq: 848; X64-SSE2: # %bb.0: 849; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 850; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 851; X64-SSE2-NEXT: movdqu (%rsi), %xmm2 852; X64-SSE2-NEXT: pcmpeqb %xmm0, %xmm2 853; X64-SSE2-NEXT: movdqu 16(%rsi), %xmm0 854; X64-SSE2-NEXT: pcmpeqb %xmm1, %xmm0 855; X64-SSE2-NEXT: pand %xmm2, %xmm0 856; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 857; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 858; X64-SSE2-NEXT: sete %al 859; X64-SSE2-NEXT: retq 860; 861; X64-AVX1-LABEL: length32_eq: 862; X64-AVX1: # %bb.0: 863; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 864; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 865; X64-AVX1-NEXT: vpcmpeqb 16(%rsi), %xmm1, %xmm1 866; X64-AVX1-NEXT: vpcmpeqb (%rsi), %xmm0, %xmm0 867; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 868; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 869; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 870; X64-AVX1-NEXT: sete %al 871; X64-AVX1-NEXT: retq 872; 873; X64-AVX2-LABEL: length32_eq: 874; X64-AVX2: # %bb.0: 875; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 876; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 877; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 878; X64-AVX2-NEXT: cmpl $-1, %eax 879; X64-AVX2-NEXT: sete %al 880; X64-AVX2-NEXT: vzeroupper 881; X64-AVX2-NEXT: retq 882 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind 883 %cmp = icmp eq i32 %call, 0 884 ret i1 %cmp 885} 886 887define i1 @length32_eq_const(i8* %X) nounwind { 888; X86-NOSSE-LABEL: length32_eq_const: 889; X86-NOSSE: # %bb.0: 890; X86-NOSSE-NEXT: pushl $0 891; X86-NOSSE-NEXT: pushl $32 892; X86-NOSSE-NEXT: pushl $.L.str 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: setne %al 898; X86-NOSSE-NEXT: retl 899; 900; X86-SSE1-LABEL: length32_eq_const: 901; X86-SSE1: # %bb.0: 902; X86-SSE1-NEXT: pushl $0 903; X86-SSE1-NEXT: pushl $32 904; X86-SSE1-NEXT: pushl $.L.str 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: setne %al 910; X86-SSE1-NEXT: retl 911; 912; X86-SSE2-LABEL: length32_eq_const: 913; X86-SSE2: # %bb.0: 914; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 915; X86-SSE2-NEXT: movdqu (%eax), %xmm0 916; X86-SSE2-NEXT: movdqu 16(%eax), %xmm1 917; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm1 918; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 919; X86-SSE2-NEXT: pand %xmm1, %xmm0 920; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 921; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 922; X86-SSE2-NEXT: setne %al 923; X86-SSE2-NEXT: retl 924; 925; X64-SSE2-LABEL: length32_eq_const: 926; X64-SSE2: # %bb.0: 927; X64-SSE2-NEXT: movdqu (%rdi), %xmm0 928; X64-SSE2-NEXT: movdqu 16(%rdi), %xmm1 929; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm1 930; X64-SSE2-NEXT: pcmpeqb {{.*}}(%rip), %xmm0 931; X64-SSE2-NEXT: pand %xmm1, %xmm0 932; X64-SSE2-NEXT: pmovmskb %xmm0, %eax 933; X64-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 934; X64-SSE2-NEXT: setne %al 935; X64-SSE2-NEXT: retq 936; 937; X64-AVX1-LABEL: length32_eq_const: 938; X64-AVX1: # %bb.0: 939; X64-AVX1-NEXT: vmovdqu (%rdi), %xmm0 940; X64-AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 941; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm1, %xmm1 942; X64-AVX1-NEXT: vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0 943; X64-AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 944; X64-AVX1-NEXT: vpmovmskb %xmm0, %eax 945; X64-AVX1-NEXT: cmpl $65535, %eax # imm = 0xFFFF 946; X64-AVX1-NEXT: setne %al 947; X64-AVX1-NEXT: retq 948; 949; X64-AVX2-LABEL: length32_eq_const: 950; X64-AVX2: # %bb.0: 951; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 952; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 953; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 954; X64-AVX2-NEXT: cmpl $-1, %eax 955; X64-AVX2-NEXT: setne %al 956; X64-AVX2-NEXT: vzeroupper 957; X64-AVX2-NEXT: retq 958 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind 959 %c = icmp ne i32 %m, 0 960 ret i1 %c 961} 962 963define i32 @length64(i8* %X, i8* %Y) nounwind { 964; X86-LABEL: length64: 965; X86: # %bb.0: 966; X86-NEXT: pushl $0 967; X86-NEXT: pushl $64 968; X86-NEXT: pushl {{[0-9]+}}(%esp) 969; X86-NEXT: pushl {{[0-9]+}}(%esp) 970; X86-NEXT: calll memcmp 971; X86-NEXT: addl $16, %esp 972; X86-NEXT: retl 973; 974; X64-LABEL: length64: 975; X64: # %bb.0: 976; X64-NEXT: movl $64, %edx 977; X64-NEXT: jmp memcmp # TAILCALL 978 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind 979 ret i32 %m 980} 981 982define i1 @length64_eq(i8* %x, i8* %y) nounwind { 983; X86-LABEL: length64_eq: 984; X86: # %bb.0: 985; X86-NEXT: pushl $0 986; X86-NEXT: pushl $64 987; X86-NEXT: pushl {{[0-9]+}}(%esp) 988; X86-NEXT: pushl {{[0-9]+}}(%esp) 989; X86-NEXT: calll memcmp 990; X86-NEXT: addl $16, %esp 991; X86-NEXT: testl %eax, %eax 992; X86-NEXT: setne %al 993; X86-NEXT: retl 994; 995; X64-SSE2-LABEL: length64_eq: 996; X64-SSE2: # %bb.0: 997; X64-SSE2-NEXT: pushq %rax 998; X64-SSE2-NEXT: movl $64, %edx 999; X64-SSE2-NEXT: callq memcmp 1000; X64-SSE2-NEXT: testl %eax, %eax 1001; X64-SSE2-NEXT: setne %al 1002; X64-SSE2-NEXT: popq %rcx 1003; X64-SSE2-NEXT: retq 1004; 1005; X64-AVX1-LABEL: length64_eq: 1006; X64-AVX1: # %bb.0: 1007; X64-AVX1-NEXT: pushq %rax 1008; X64-AVX1-NEXT: movl $64, %edx 1009; X64-AVX1-NEXT: callq memcmp 1010; X64-AVX1-NEXT: testl %eax, %eax 1011; X64-AVX1-NEXT: setne %al 1012; X64-AVX1-NEXT: popq %rcx 1013; X64-AVX1-NEXT: retq 1014; 1015; X64-AVX2-LABEL: length64_eq: 1016; X64-AVX2: # %bb.0: 1017; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1018; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1019; X64-AVX2-NEXT: vpcmpeqb 32(%rsi), %ymm1, %ymm1 1020; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 1021; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1022; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1023; X64-AVX2-NEXT: cmpl $-1, %eax 1024; X64-AVX2-NEXT: setne %al 1025; X64-AVX2-NEXT: vzeroupper 1026; X64-AVX2-NEXT: retq 1027 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind 1028 %cmp = icmp ne i32 %call, 0 1029 ret i1 %cmp 1030} 1031 1032define i1 @length64_eq_const(i8* %X) nounwind { 1033; X86-LABEL: length64_eq_const: 1034; X86: # %bb.0: 1035; X86-NEXT: pushl $0 1036; X86-NEXT: pushl $64 1037; X86-NEXT: pushl $.L.str 1038; X86-NEXT: pushl {{[0-9]+}}(%esp) 1039; X86-NEXT: calll memcmp 1040; X86-NEXT: addl $16, %esp 1041; X86-NEXT: testl %eax, %eax 1042; X86-NEXT: sete %al 1043; X86-NEXT: retl 1044; 1045; X64-SSE2-LABEL: length64_eq_const: 1046; X64-SSE2: # %bb.0: 1047; X64-SSE2-NEXT: pushq %rax 1048; X64-SSE2-NEXT: movl $.L.str, %esi 1049; X64-SSE2-NEXT: movl $64, %edx 1050; X64-SSE2-NEXT: callq memcmp 1051; X64-SSE2-NEXT: testl %eax, %eax 1052; X64-SSE2-NEXT: sete %al 1053; X64-SSE2-NEXT: popq %rcx 1054; X64-SSE2-NEXT: retq 1055; 1056; X64-AVX1-LABEL: length64_eq_const: 1057; X64-AVX1: # %bb.0: 1058; X64-AVX1-NEXT: pushq %rax 1059; X64-AVX1-NEXT: movl $.L.str, %esi 1060; X64-AVX1-NEXT: movl $64, %edx 1061; X64-AVX1-NEXT: callq memcmp 1062; X64-AVX1-NEXT: testl %eax, %eax 1063; X64-AVX1-NEXT: sete %al 1064; X64-AVX1-NEXT: popq %rcx 1065; X64-AVX1-NEXT: retq 1066; 1067; X64-AVX2-LABEL: length64_eq_const: 1068; X64-AVX2: # %bb.0: 1069; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 1070; X64-AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1071; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm1, %ymm1 1072; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 1073; X64-AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 1074; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 1075; X64-AVX2-NEXT: cmpl $-1, %eax 1076; X64-AVX2-NEXT: sete %al 1077; X64-AVX2-NEXT: vzeroupper 1078; X64-AVX2-NEXT: retq 1079 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind 1080 %c = icmp eq i32 %m, 0 1081 ret i1 %c 1082} 1083 1084; This checks that we do not do stupid things with huge sizes. 1085define i32 @huge_length(i8* %X, i8* %Y) nounwind { 1086; X86-LABEL: huge_length: 1087; X86: # %bb.0: 1088; X86-NEXT: pushl $2147483647 # imm = 0x7FFFFFFF 1089; X86-NEXT: pushl $-1 1090; X86-NEXT: pushl {{[0-9]+}}(%esp) 1091; X86-NEXT: pushl {{[0-9]+}}(%esp) 1092; X86-NEXT: calll memcmp 1093; X86-NEXT: addl $16, %esp 1094; X86-NEXT: retl 1095; 1096; X64-LABEL: huge_length: 1097; X64: # %bb.0: 1098; X64-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF 1099; X64-NEXT: jmp memcmp # TAILCALL 1100 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind 1101 ret i32 %m 1102} 1103 1104 1105