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 @length2(i8* %X, i8* %Y) nounwind { 17; X86-LABEL: length2: 18; X86: # BB#0: 19; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 20; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 21; X86-NEXT: movzwl (%ecx), %ecx 22; X86-NEXT: movzwl (%eax), %edx 23; X86-NEXT: rolw $8, %cx 24; X86-NEXT: rolw $8, %dx 25; X86-NEXT: movzwl %cx, %eax 26; X86-NEXT: movzwl %dx, %ecx 27; X86-NEXT: subl %ecx, %eax 28; X86-NEXT: retl 29; 30; X64-LABEL: length2: 31; X64: # BB#0: 32; X64-NEXT: movzwl (%rdi), %eax 33; X64-NEXT: movzwl (%rsi), %ecx 34; X64-NEXT: rolw $8, %ax 35; X64-NEXT: rolw $8, %cx 36; X64-NEXT: movzwl %ax, %eax 37; X64-NEXT: movzwl %cx, %ecx 38; X64-NEXT: subl %ecx, %eax 39; X64-NEXT: retq 40 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 41 ret i32 %m 42} 43 44define i1 @length2_eq(i8* %X, i8* %Y) nounwind { 45; X86-LABEL: length2_eq: 46; X86: # BB#0: 47; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 48; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 49; X86-NEXT: movzwl (%ecx), %ecx 50; X86-NEXT: cmpw (%eax), %cx 51; X86-NEXT: sete %al 52; X86-NEXT: retl 53; 54; X64-LABEL: length2_eq: 55; X64: # BB#0: 56; X64-NEXT: movzwl (%rdi), %eax 57; X64-NEXT: cmpw (%rsi), %ax 58; X64-NEXT: sete %al 59; X64-NEXT: retq 60 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind 61 %c = icmp eq i32 %m, 0 62 ret i1 %c 63} 64 65define i1 @length2_eq_const(i8* %X) nounwind { 66; X86-LABEL: length2_eq_const: 67; X86: # BB#0: 68; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 69; X86-NEXT: movzwl (%eax), %eax 70; X86-NEXT: cmpl $12849, %eax # imm = 0x3231 71; X86-NEXT: setne %al 72; X86-NEXT: retl 73; 74; X64-LABEL: length2_eq_const: 75; X64: # BB#0: 76; X64-NEXT: movzwl (%rdi), %eax 77; X64-NEXT: cmpl $12849, %eax # imm = 0x3231 78; X64-NEXT: setne %al 79; X64-NEXT: retq 80 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind 81 %c = icmp ne i32 %m, 0 82 ret i1 %c 83} 84 85define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind { 86; X86-LABEL: length2_eq_nobuiltin_attr: 87; X86: # BB#0: 88; X86-NEXT: pushl $0 89; X86-NEXT: pushl $2 90; X86-NEXT: pushl {{[0-9]+}}(%esp) 91; X86-NEXT: pushl {{[0-9]+}}(%esp) 92; X86-NEXT: calll memcmp 93; X86-NEXT: addl $16, %esp 94; X86-NEXT: testl %eax, %eax 95; X86-NEXT: sete %al 96; X86-NEXT: retl 97; 98; X64-LABEL: length2_eq_nobuiltin_attr: 99; X64: # BB#0: 100; X64-NEXT: pushq %rax 101; X64-NEXT: movl $2, %edx 102; X64-NEXT: callq memcmp 103; X64-NEXT: testl %eax, %eax 104; X64-NEXT: sete %al 105; X64-NEXT: popq %rcx 106; X64-NEXT: retq 107 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin 108 %c = icmp eq i32 %m, 0 109 ret i1 %c 110} 111 112define i32 @length3(i8* %X, i8* %Y) nounwind { 113; X86-LABEL: length3: 114; X86: # BB#0: # %loadbb 115; X86-NEXT: pushl %esi 116; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 117; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 118; X86-NEXT: movzwl (%eax), %edx 119; X86-NEXT: movzwl (%ecx), %esi 120; X86-NEXT: rolw $8, %dx 121; X86-NEXT: rolw $8, %si 122; X86-NEXT: cmpw %si, %dx 123; X86-NEXT: jne .LBB4_1 124; X86-NEXT: # BB#2: # %loadbb1 125; X86-NEXT: movzbl 2(%eax), %eax 126; X86-NEXT: movzbl 2(%ecx), %ecx 127; X86-NEXT: subl %ecx, %eax 128; X86-NEXT: popl %esi 129; X86-NEXT: retl 130; X86-NEXT: .LBB4_1: # %res_block 131; X86-NEXT: setae %al 132; X86-NEXT: movzbl %al, %eax 133; X86-NEXT: leal -1(%eax,%eax), %eax 134; X86-NEXT: popl %esi 135; X86-NEXT: retl 136; 137; X64-LABEL: length3: 138; X64: # BB#0: # %loadbb 139; X64-NEXT: movzwl (%rdi), %eax 140; X64-NEXT: movzwl (%rsi), %ecx 141; X64-NEXT: rolw $8, %ax 142; X64-NEXT: rolw $8, %cx 143; X64-NEXT: cmpw %cx, %ax 144; X64-NEXT: jne .LBB4_1 145; X64-NEXT: # BB#2: # %loadbb1 146; X64-NEXT: movzbl 2(%rdi), %eax 147; X64-NEXT: movzbl 2(%rsi), %ecx 148; X64-NEXT: subl %ecx, %eax 149; X64-NEXT: retq 150; X64-NEXT: .LBB4_1: # %res_block 151; X64-NEXT: setae %al 152; X64-NEXT: movzbl %al, %eax 153; X64-NEXT: leal -1(%rax,%rax), %eax 154; X64-NEXT: retq 155 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 156 ret i32 %m 157} 158 159define i1 @length3_eq(i8* %X, i8* %Y) nounwind { 160; X86-LABEL: length3_eq: 161; X86: # BB#0: # %loadbb 162; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 163; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 164; X86-NEXT: movzwl (%eax), %edx 165; X86-NEXT: cmpw (%ecx), %dx 166; X86-NEXT: jne .LBB5_1 167; X86-NEXT: # BB#2: # %loadbb1 168; X86-NEXT: movb 2(%eax), %dl 169; X86-NEXT: xorl %eax, %eax 170; X86-NEXT: cmpb 2(%ecx), %dl 171; X86-NEXT: je .LBB5_3 172; X86-NEXT: .LBB5_1: # %res_block 173; X86-NEXT: movl $1, %eax 174; X86-NEXT: .LBB5_3: # %endblock 175; X86-NEXT: testl %eax, %eax 176; X86-NEXT: setne %al 177; X86-NEXT: retl 178; 179; X64-LABEL: length3_eq: 180; X64: # BB#0: # %loadbb 181; X64-NEXT: movzwl (%rdi), %eax 182; X64-NEXT: cmpw (%rsi), %ax 183; X64-NEXT: jne .LBB5_1 184; X64-NEXT: # BB#2: # %loadbb1 185; X64-NEXT: movb 2(%rdi), %cl 186; X64-NEXT: xorl %eax, %eax 187; X64-NEXT: cmpb 2(%rsi), %cl 188; X64-NEXT: je .LBB5_3 189; X64-NEXT: .LBB5_1: # %res_block 190; X64-NEXT: movl $1, %eax 191; X64-NEXT: .LBB5_3: # %endblock 192; X64-NEXT: testl %eax, %eax 193; X64-NEXT: setne %al 194; X64-NEXT: retq 195 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind 196 %c = icmp ne i32 %m, 0 197 ret i1 %c 198} 199 200define i32 @length4(i8* %X, i8* %Y) nounwind { 201; X86-LABEL: length4: 202; X86: # BB#0: 203; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 204; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 205; X86-NEXT: movl (%ecx), %ecx 206; X86-NEXT: movl (%eax), %edx 207; X86-NEXT: bswapl %ecx 208; X86-NEXT: bswapl %edx 209; X86-NEXT: xorl %eax, %eax 210; X86-NEXT: cmpl %edx, %ecx 211; X86-NEXT: seta %al 212; X86-NEXT: sbbl $0, %eax 213; X86-NEXT: retl 214; 215; X64-LABEL: length4: 216; X64: # BB#0: 217; X64-NEXT: movl (%rdi), %ecx 218; X64-NEXT: movl (%rsi), %edx 219; X64-NEXT: bswapl %ecx 220; X64-NEXT: bswapl %edx 221; X64-NEXT: xorl %eax, %eax 222; X64-NEXT: cmpl %edx, %ecx 223; X64-NEXT: seta %al 224; X64-NEXT: sbbl $0, %eax 225; X64-NEXT: retq 226 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 227 ret i32 %m 228} 229 230define i1 @length4_eq(i8* %X, i8* %Y) nounwind { 231; X86-LABEL: length4_eq: 232; X86: # BB#0: 233; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 234; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 235; X86-NEXT: movl (%ecx), %ecx 236; X86-NEXT: cmpl (%eax), %ecx 237; X86-NEXT: setne %al 238; X86-NEXT: retl 239; 240; X64-LABEL: length4_eq: 241; X64: # BB#0: 242; X64-NEXT: movl (%rdi), %eax 243; X64-NEXT: cmpl (%rsi), %eax 244; X64-NEXT: setne %al 245; X64-NEXT: retq 246 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind 247 %c = icmp ne i32 %m, 0 248 ret i1 %c 249} 250 251define i1 @length4_eq_const(i8* %X) nounwind { 252; X86-LABEL: length4_eq_const: 253; X86: # BB#0: 254; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 255; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231 256; X86-NEXT: sete %al 257; X86-NEXT: retl 258; 259; X64-LABEL: length4_eq_const: 260; X64: # BB#0: 261; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231 262; X64-NEXT: sete %al 263; X64-NEXT: retq 264 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind 265 %c = icmp eq i32 %m, 0 266 ret i1 %c 267} 268 269define i32 @length5(i8* %X, i8* %Y) nounwind { 270; X86-LABEL: length5: 271; X86: # BB#0: # %loadbb 272; X86-NEXT: pushl %esi 273; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 274; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 275; X86-NEXT: movl (%eax), %edx 276; X86-NEXT: movl (%ecx), %esi 277; X86-NEXT: bswapl %edx 278; X86-NEXT: bswapl %esi 279; X86-NEXT: cmpl %esi, %edx 280; X86-NEXT: jne .LBB9_1 281; X86-NEXT: # BB#2: # %loadbb1 282; X86-NEXT: movzbl 4(%eax), %eax 283; X86-NEXT: movzbl 4(%ecx), %ecx 284; X86-NEXT: subl %ecx, %eax 285; X86-NEXT: popl %esi 286; X86-NEXT: retl 287; X86-NEXT: .LBB9_1: # %res_block 288; X86-NEXT: setae %al 289; X86-NEXT: movzbl %al, %eax 290; X86-NEXT: leal -1(%eax,%eax), %eax 291; X86-NEXT: popl %esi 292; X86-NEXT: retl 293; 294; X64-LABEL: length5: 295; X64: # BB#0: # %loadbb 296; X64-NEXT: movl (%rdi), %eax 297; X64-NEXT: movl (%rsi), %ecx 298; X64-NEXT: bswapl %eax 299; X64-NEXT: bswapl %ecx 300; X64-NEXT: cmpl %ecx, %eax 301; X64-NEXT: jne .LBB9_1 302; X64-NEXT: # BB#2: # %loadbb1 303; X64-NEXT: movzbl 4(%rdi), %eax 304; X64-NEXT: movzbl 4(%rsi), %ecx 305; X64-NEXT: subl %ecx, %eax 306; X64-NEXT: retq 307; X64-NEXT: .LBB9_1: # %res_block 308; X64-NEXT: setae %al 309; X64-NEXT: movzbl %al, %eax 310; X64-NEXT: leal -1(%rax,%rax), %eax 311; X64-NEXT: retq 312 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 313 ret i32 %m 314} 315 316define i1 @length5_eq(i8* %X, i8* %Y) nounwind { 317; X86-LABEL: length5_eq: 318; X86: # BB#0: # %loadbb 319; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 320; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 321; X86-NEXT: movl (%eax), %edx 322; X86-NEXT: cmpl (%ecx), %edx 323; X86-NEXT: jne .LBB10_1 324; X86-NEXT: # BB#2: # %loadbb1 325; X86-NEXT: movb 4(%eax), %dl 326; X86-NEXT: xorl %eax, %eax 327; X86-NEXT: cmpb 4(%ecx), %dl 328; X86-NEXT: je .LBB10_3 329; X86-NEXT: .LBB10_1: # %res_block 330; X86-NEXT: movl $1, %eax 331; X86-NEXT: .LBB10_3: # %endblock 332; X86-NEXT: testl %eax, %eax 333; X86-NEXT: setne %al 334; X86-NEXT: retl 335; 336; X64-LABEL: length5_eq: 337; X64: # BB#0: # %loadbb 338; X64-NEXT: movl (%rdi), %eax 339; X64-NEXT: cmpl (%rsi), %eax 340; X64-NEXT: jne .LBB10_1 341; X64-NEXT: # BB#2: # %loadbb1 342; X64-NEXT: movb 4(%rdi), %cl 343; X64-NEXT: xorl %eax, %eax 344; X64-NEXT: cmpb 4(%rsi), %cl 345; X64-NEXT: je .LBB10_3 346; X64-NEXT: .LBB10_1: # %res_block 347; X64-NEXT: movl $1, %eax 348; X64-NEXT: .LBB10_3: # %endblock 349; X64-NEXT: testl %eax, %eax 350; X64-NEXT: setne %al 351; X64-NEXT: retq 352 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind 353 %c = icmp ne i32 %m, 0 354 ret i1 %c 355} 356 357define i32 @length8(i8* %X, i8* %Y) nounwind { 358; X86-LABEL: length8: 359; X86: # BB#0: # %loadbb 360; X86-NEXT: pushl %esi 361; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 362; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 363; X86-NEXT: movl (%esi), %ecx 364; X86-NEXT: movl (%eax), %edx 365; X86-NEXT: bswapl %ecx 366; X86-NEXT: bswapl %edx 367; X86-NEXT: cmpl %edx, %ecx 368; X86-NEXT: jne .LBB11_1 369; X86-NEXT: # BB#2: # %loadbb1 370; X86-NEXT: movl 4(%esi), %ecx 371; X86-NEXT: movl 4(%eax), %edx 372; X86-NEXT: bswapl %ecx 373; X86-NEXT: bswapl %edx 374; X86-NEXT: xorl %eax, %eax 375; X86-NEXT: cmpl %edx, %ecx 376; X86-NEXT: jne .LBB11_1 377; X86-NEXT: # BB#3: # %endblock 378; X86-NEXT: popl %esi 379; X86-NEXT: retl 380; X86-NEXT: .LBB11_1: # %res_block 381; X86-NEXT: xorl %eax, %eax 382; X86-NEXT: cmpl %edx, %ecx 383; X86-NEXT: setae %al 384; X86-NEXT: leal -1(%eax,%eax), %eax 385; X86-NEXT: popl %esi 386; X86-NEXT: retl 387; 388; X64-LABEL: length8: 389; X64: # BB#0: 390; X64-NEXT: movq (%rdi), %rcx 391; X64-NEXT: movq (%rsi), %rdx 392; X64-NEXT: bswapq %rcx 393; X64-NEXT: bswapq %rdx 394; X64-NEXT: xorl %eax, %eax 395; X64-NEXT: cmpq %rdx, %rcx 396; X64-NEXT: seta %al 397; X64-NEXT: sbbl $0, %eax 398; X64-NEXT: retq 399 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 400 ret i32 %m 401} 402 403define i1 @length8_eq(i8* %X, i8* %Y) nounwind { 404; X86-LABEL: length8_eq: 405; X86: # BB#0: # %loadbb 406; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 407; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 408; X86-NEXT: movl (%eax), %edx 409; X86-NEXT: cmpl (%ecx), %edx 410; X86-NEXT: jne .LBB12_1 411; X86-NEXT: # BB#2: # %loadbb1 412; X86-NEXT: movl 4(%eax), %edx 413; X86-NEXT: xorl %eax, %eax 414; X86-NEXT: cmpl 4(%ecx), %edx 415; X86-NEXT: je .LBB12_3 416; X86-NEXT: .LBB12_1: # %res_block 417; X86-NEXT: movl $1, %eax 418; X86-NEXT: .LBB12_3: # %endblock 419; X86-NEXT: testl %eax, %eax 420; X86-NEXT: sete %al 421; X86-NEXT: retl 422; 423; X64-LABEL: length8_eq: 424; X64: # BB#0: 425; X64-NEXT: movq (%rdi), %rax 426; X64-NEXT: cmpq (%rsi), %rax 427; X64-NEXT: sete %al 428; X64-NEXT: retq 429 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind 430 %c = icmp eq i32 %m, 0 431 ret i1 %c 432} 433 434define i1 @length8_eq_const(i8* %X) nounwind { 435; X86-LABEL: length8_eq_const: 436; X86: # BB#0: # %loadbb 437; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 438; X86-NEXT: cmpl $858927408, (%ecx) # imm = 0x33323130 439; X86-NEXT: jne .LBB13_1 440; X86-NEXT: # BB#2: # %loadbb1 441; X86-NEXT: xorl %eax, %eax 442; X86-NEXT: cmpl $926299444, 4(%ecx) # imm = 0x37363534 443; X86-NEXT: je .LBB13_3 444; X86-NEXT: .LBB13_1: # %res_block 445; X86-NEXT: movl $1, %eax 446; X86-NEXT: .LBB13_3: # %endblock 447; X86-NEXT: testl %eax, %eax 448; X86-NEXT: setne %al 449; X86-NEXT: retl 450; 451; X64-LABEL: length8_eq_const: 452; X64: # BB#0: 453; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130 454; X64-NEXT: cmpq %rax, (%rdi) 455; X64-NEXT: setne %al 456; X64-NEXT: retq 457 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind 458 %c = icmp ne i32 %m, 0 459 ret i1 %c 460} 461 462define i1 @length12_eq(i8* %X, i8* %Y) nounwind { 463; X86-LABEL: length12_eq: 464; X86: # BB#0: 465; X86-NEXT: pushl $0 466; X86-NEXT: pushl $12 467; X86-NEXT: pushl {{[0-9]+}}(%esp) 468; X86-NEXT: pushl {{[0-9]+}}(%esp) 469; X86-NEXT: calll memcmp 470; X86-NEXT: addl $16, %esp 471; X86-NEXT: testl %eax, %eax 472; X86-NEXT: setne %al 473; X86-NEXT: retl 474; 475; X64-LABEL: length12_eq: 476; X64: # BB#0: # %loadbb 477; X64-NEXT: movq (%rdi), %rax 478; X64-NEXT: cmpq (%rsi), %rax 479; X64-NEXT: jne .LBB14_1 480; X64-NEXT: # BB#2: # %loadbb1 481; X64-NEXT: movl 8(%rdi), %ecx 482; X64-NEXT: xorl %eax, %eax 483; X64-NEXT: cmpl 8(%rsi), %ecx 484; X64-NEXT: je .LBB14_3 485; X64-NEXT: .LBB14_1: # %res_block 486; X64-NEXT: movl $1, %eax 487; X64-NEXT: .LBB14_3: # %endblock 488; X64-NEXT: testl %eax, %eax 489; X64-NEXT: setne %al 490; X64-NEXT: retq 491 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 492 %c = icmp ne i32 %m, 0 493 ret i1 %c 494} 495 496define i32 @length12(i8* %X, i8* %Y) nounwind { 497; X86-LABEL: length12: 498; X86: # BB#0: 499; X86-NEXT: pushl $0 500; X86-NEXT: pushl $12 501; X86-NEXT: pushl {{[0-9]+}}(%esp) 502; X86-NEXT: pushl {{[0-9]+}}(%esp) 503; X86-NEXT: calll memcmp 504; X86-NEXT: addl $16, %esp 505; X86-NEXT: retl 506; 507; X64-LABEL: length12: 508; X64: # BB#0: # %loadbb 509; X64-NEXT: movq (%rdi), %rcx 510; X64-NEXT: movq (%rsi), %rdx 511; X64-NEXT: bswapq %rcx 512; X64-NEXT: bswapq %rdx 513; X64-NEXT: cmpq %rdx, %rcx 514; X64-NEXT: jne .LBB15_1 515; X64-NEXT: # BB#2: # %loadbb1 516; X64-NEXT: movl 8(%rdi), %ecx 517; X64-NEXT: movl 8(%rsi), %edx 518; X64-NEXT: bswapl %ecx 519; X64-NEXT: bswapl %edx 520; X64-NEXT: xorl %eax, %eax 521; X64-NEXT: cmpq %rdx, %rcx 522; X64-NEXT: jne .LBB15_1 523; X64-NEXT: # BB#3: # %endblock 524; X64-NEXT: retq 525; X64-NEXT: .LBB15_1: # %res_block 526; X64-NEXT: xorl %eax, %eax 527; X64-NEXT: cmpq %rdx, %rcx 528; X64-NEXT: setae %al 529; X64-NEXT: leal -1(%rax,%rax), %eax 530; X64-NEXT: retq 531 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind 532 ret i32 %m 533} 534 535; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329 536 537define i32 @length16(i8* %X, i8* %Y) nounwind { 538; X86-LABEL: length16: 539; X86: # BB#0: 540; X86-NEXT: pushl $0 541; X86-NEXT: pushl $16 542; X86-NEXT: pushl {{[0-9]+}}(%esp) 543; X86-NEXT: pushl {{[0-9]+}}(%esp) 544; X86-NEXT: calll memcmp 545; X86-NEXT: addl $16, %esp 546; X86-NEXT: retl 547; 548; X64-LABEL: length16: 549; X64: # BB#0: # %loadbb 550; X64-NEXT: movq (%rdi), %rcx 551; X64-NEXT: movq (%rsi), %rdx 552; X64-NEXT: bswapq %rcx 553; X64-NEXT: bswapq %rdx 554; X64-NEXT: cmpq %rdx, %rcx 555; X64-NEXT: jne .LBB16_1 556; X64-NEXT: # BB#2: # %loadbb1 557; X64-NEXT: movq 8(%rdi), %rcx 558; X64-NEXT: movq 8(%rsi), %rdx 559; X64-NEXT: bswapq %rcx 560; X64-NEXT: bswapq %rdx 561; X64-NEXT: xorl %eax, %eax 562; X64-NEXT: cmpq %rdx, %rcx 563; X64-NEXT: jne .LBB16_1 564; X64-NEXT: # BB#3: # %endblock 565; X64-NEXT: retq 566; X64-NEXT: .LBB16_1: # %res_block 567; X64-NEXT: xorl %eax, %eax 568; X64-NEXT: cmpq %rdx, %rcx 569; X64-NEXT: setae %al 570; X64-NEXT: leal -1(%rax,%rax), %eax 571; X64-NEXT: retq 572 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind 573 ret i32 %m 574} 575 576define i1 @length16_eq(i8* %x, i8* %y) nounwind { 577; X86-NOSSE-LABEL: length16_eq: 578; X86-NOSSE: # BB#0: 579; X86-NOSSE-NEXT: pushl $0 580; X86-NOSSE-NEXT: pushl $16 581; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 582; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 583; X86-NOSSE-NEXT: calll memcmp 584; X86-NOSSE-NEXT: addl $16, %esp 585; X86-NOSSE-NEXT: testl %eax, %eax 586; X86-NOSSE-NEXT: setne %al 587; X86-NOSSE-NEXT: retl 588; 589; X86-SSE1-LABEL: length16_eq: 590; X86-SSE1: # BB#0: 591; X86-SSE1-NEXT: pushl $0 592; X86-SSE1-NEXT: pushl $16 593; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 594; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 595; X86-SSE1-NEXT: calll memcmp 596; X86-SSE1-NEXT: addl $16, %esp 597; X86-SSE1-NEXT: testl %eax, %eax 598; X86-SSE1-NEXT: setne %al 599; X86-SSE1-NEXT: retl 600; 601; X86-SSE2-LABEL: length16_eq: 602; X86-SSE2: # BB#0: 603; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 604; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 605; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 606; X86-SSE2-NEXT: movdqu (%eax), %xmm1 607; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 608; X86-SSE2-NEXT: pmovmskb %xmm1, %eax 609; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 610; X86-SSE2-NEXT: setne %al 611; X86-SSE2-NEXT: retl 612; 613; X64-LABEL: length16_eq: 614; X64: # BB#0: # %loadbb 615; X64-NEXT: movq (%rdi), %rax 616; X64-NEXT: cmpq (%rsi), %rax 617; X64-NEXT: jne .LBB17_1 618; X64-NEXT: # BB#2: # %loadbb1 619; X64-NEXT: movq 8(%rdi), %rcx 620; X64-NEXT: xorl %eax, %eax 621; X64-NEXT: cmpq 8(%rsi), %rcx 622; X64-NEXT: je .LBB17_3 623; X64-NEXT: .LBB17_1: # %res_block 624; X64-NEXT: movl $1, %eax 625; X64-NEXT: .LBB17_3: # %endblock 626; X64-NEXT: testl %eax, %eax 627; X64-NEXT: setne %al 628; X64-NEXT: retq 629 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind 630 %cmp = icmp ne i32 %call, 0 631 ret i1 %cmp 632} 633 634define i1 @length16_eq_const(i8* %X) nounwind { 635; X86-NOSSE-LABEL: length16_eq_const: 636; X86-NOSSE: # BB#0: 637; X86-NOSSE-NEXT: pushl $0 638; X86-NOSSE-NEXT: pushl $16 639; X86-NOSSE-NEXT: pushl $.L.str 640; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 641; X86-NOSSE-NEXT: calll memcmp 642; X86-NOSSE-NEXT: addl $16, %esp 643; X86-NOSSE-NEXT: testl %eax, %eax 644; X86-NOSSE-NEXT: sete %al 645; X86-NOSSE-NEXT: retl 646; 647; X86-SSE1-LABEL: length16_eq_const: 648; X86-SSE1: # BB#0: 649; X86-SSE1-NEXT: pushl $0 650; X86-SSE1-NEXT: pushl $16 651; X86-SSE1-NEXT: pushl $.L.str 652; X86-SSE1-NEXT: pushl {{[0-9]+}}(%esp) 653; X86-SSE1-NEXT: calll memcmp 654; X86-SSE1-NEXT: addl $16, %esp 655; X86-SSE1-NEXT: testl %eax, %eax 656; X86-SSE1-NEXT: sete %al 657; X86-SSE1-NEXT: retl 658; 659; X86-SSE2-LABEL: length16_eq_const: 660; X86-SSE2: # BB#0: 661; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 662; X86-SSE2-NEXT: movdqu (%eax), %xmm0 663; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0 664; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 665; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 666; X86-SSE2-NEXT: sete %al 667; X86-SSE2-NEXT: retl 668; 669; X64-LABEL: length16_eq_const: 670; X64: # BB#0: # %loadbb 671; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130 672; X64-NEXT: cmpq %rax, (%rdi) 673; X64-NEXT: jne .LBB18_1 674; X64-NEXT: # BB#2: # %loadbb1 675; X64-NEXT: xorl %eax, %eax 676; X64-NEXT: movabsq $3833745473465760056, %rcx # imm = 0x3534333231303938 677; X64-NEXT: cmpq %rcx, 8(%rdi) 678; X64-NEXT: je .LBB18_3 679; X64-NEXT: .LBB18_1: # %res_block 680; X64-NEXT: movl $1, %eax 681; X64-NEXT: .LBB18_3: # %endblock 682; X64-NEXT: testl %eax, %eax 683; X64-NEXT: sete %al 684; X64-NEXT: retq 685 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind 686 %c = icmp eq i32 %m, 0 687 ret i1 %c 688} 689 690; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914 691 692define i32 @length24(i8* %X, i8* %Y) nounwind { 693; X86-LABEL: length24: 694; X86: # BB#0: 695; X86-NEXT: pushl $0 696; X86-NEXT: pushl $24 697; X86-NEXT: pushl {{[0-9]+}}(%esp) 698; X86-NEXT: pushl {{[0-9]+}}(%esp) 699; X86-NEXT: calll memcmp 700; X86-NEXT: addl $16, %esp 701; X86-NEXT: retl 702; 703; X64-LABEL: length24: 704; X64: # BB#0: 705; X64-NEXT: movl $24, %edx 706; X64-NEXT: jmp memcmp # TAILCALL 707 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind 708 ret i32 %m 709} 710 711define i1 @length24_eq(i8* %x, i8* %y) nounwind { 712; X86-LABEL: length24_eq: 713; X86: # BB#0: 714; X86-NEXT: pushl $0 715; X86-NEXT: pushl $24 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: testl %eax, %eax 721; X86-NEXT: sete %al 722; X86-NEXT: retl 723; 724; X64-LABEL: length24_eq: 725; X64: # BB#0: 726; X64-NEXT: pushq %rax 727; X64-NEXT: movl $24, %edx 728; X64-NEXT: callq memcmp 729; X64-NEXT: testl %eax, %eax 730; X64-NEXT: sete %al 731; X64-NEXT: popq %rcx 732; X64-NEXT: retq 733 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind 734 %cmp = icmp eq i32 %call, 0 735 ret i1 %cmp 736} 737 738define i1 @length24_eq_const(i8* %X) nounwind { 739; X86-LABEL: length24_eq_const: 740; X86: # BB#0: 741; X86-NEXT: pushl $0 742; X86-NEXT: pushl $24 743; X86-NEXT: pushl $.L.str 744; X86-NEXT: pushl {{[0-9]+}}(%esp) 745; X86-NEXT: calll memcmp 746; X86-NEXT: addl $16, %esp 747; X86-NEXT: testl %eax, %eax 748; X86-NEXT: setne %al 749; X86-NEXT: retl 750; 751; X64-LABEL: length24_eq_const: 752; X64: # BB#0: 753; X64-NEXT: pushq %rax 754; X64-NEXT: movl $.L.str, %esi 755; X64-NEXT: movl $24, %edx 756; X64-NEXT: callq memcmp 757; X64-NEXT: testl %eax, %eax 758; X64-NEXT: setne %al 759; X64-NEXT: popq %rcx 760; X64-NEXT: retq 761 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind 762 %c = icmp ne i32 %m, 0 763 ret i1 %c 764} 765 766define i32 @length32(i8* %X, i8* %Y) nounwind { 767; X86-LABEL: length32: 768; X86: # BB#0: 769; X86-NEXT: pushl $0 770; X86-NEXT: pushl $32 771; X86-NEXT: pushl {{[0-9]+}}(%esp) 772; X86-NEXT: pushl {{[0-9]+}}(%esp) 773; X86-NEXT: calll memcmp 774; X86-NEXT: addl $16, %esp 775; X86-NEXT: retl 776; 777; X64-LABEL: length32: 778; X64: # BB#0: 779; X64-NEXT: movl $32, %edx 780; X64-NEXT: jmp memcmp # TAILCALL 781 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind 782 ret i32 %m 783} 784 785; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 786 787define i1 @length32_eq(i8* %x, i8* %y) nounwind { 788; X86-LABEL: length32_eq: 789; X86: # BB#0: 790; X86-NEXT: pushl $0 791; X86-NEXT: pushl $32 792; X86-NEXT: pushl {{[0-9]+}}(%esp) 793; X86-NEXT: pushl {{[0-9]+}}(%esp) 794; X86-NEXT: calll memcmp 795; X86-NEXT: addl $16, %esp 796; X86-NEXT: testl %eax, %eax 797; X86-NEXT: sete %al 798; X86-NEXT: retl 799; 800; X64-SSE2-LABEL: length32_eq: 801; X64-SSE2: # BB#0: 802; X64-SSE2-NEXT: pushq %rax 803; X64-SSE2-NEXT: movl $32, %edx 804; X64-SSE2-NEXT: callq memcmp 805; X64-SSE2-NEXT: testl %eax, %eax 806; X64-SSE2-NEXT: sete %al 807; X64-SSE2-NEXT: popq %rcx 808; X64-SSE2-NEXT: retq 809; 810; X64-AVX1-LABEL: length32_eq: 811; X64-AVX1: # BB#0: 812; X64-AVX1-NEXT: movq 16(%rdi), %rax 813; X64-AVX1-NEXT: movq (%rdi), %rcx 814; X64-AVX1-NEXT: movq 8(%rdi), %rdx 815; X64-AVX1-NEXT: movq 24(%rdi), %rdi 816; X64-AVX1-NEXT: xorq 24(%rsi), %rdi 817; X64-AVX1-NEXT: xorq 8(%rsi), %rdx 818; X64-AVX1-NEXT: orq %rdi, %rdx 819; X64-AVX1-NEXT: xorq 16(%rsi), %rax 820; X64-AVX1-NEXT: xorq (%rsi), %rcx 821; X64-AVX1-NEXT: orq %rax, %rcx 822; X64-AVX1-NEXT: orq %rdx, %rcx 823; X64-AVX1-NEXT: sete %al 824; X64-AVX1-NEXT: retq 825; 826; X64-AVX2-LABEL: length32_eq: 827; X64-AVX2: # BB#0: 828; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 829; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0 830; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 831; X64-AVX2-NEXT: cmpl $-1, %eax 832; X64-AVX2-NEXT: sete %al 833; X64-AVX2-NEXT: vzeroupper 834; X64-AVX2-NEXT: retq 835 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind 836 %cmp = icmp eq i32 %call, 0 837 ret i1 %cmp 838} 839 840define i1 @length32_eq_const(i8* %X) nounwind { 841; X86-LABEL: length32_eq_const: 842; X86: # BB#0: 843; X86-NEXT: pushl $0 844; X86-NEXT: pushl $32 845; X86-NEXT: pushl $.L.str 846; X86-NEXT: pushl {{[0-9]+}}(%esp) 847; X86-NEXT: calll memcmp 848; X86-NEXT: addl $16, %esp 849; X86-NEXT: testl %eax, %eax 850; X86-NEXT: setne %al 851; X86-NEXT: retl 852; 853; X64-SSE2-LABEL: length32_eq_const: 854; X64-SSE2: # BB#0: 855; X64-SSE2-NEXT: pushq %rax 856; X64-SSE2-NEXT: movl $.L.str, %esi 857; X64-SSE2-NEXT: movl $32, %edx 858; X64-SSE2-NEXT: callq memcmp 859; X64-SSE2-NEXT: testl %eax, %eax 860; X64-SSE2-NEXT: setne %al 861; X64-SSE2-NEXT: popq %rcx 862; X64-SSE2-NEXT: retq 863; 864; X64-AVX1-LABEL: length32_eq_const: 865; X64-AVX1: # BB#0: 866; X64-AVX1-NEXT: movabsq $3544395820347831604, %rax # imm = 0x3130393837363534 867; X64-AVX1-NEXT: xorq 24(%rdi), %rax 868; X64-AVX1-NEXT: movabsq $3833745473465760056, %rcx # imm = 0x3534333231303938 869; X64-AVX1-NEXT: xorq 8(%rdi), %rcx 870; X64-AVX1-NEXT: orq %rax, %rcx 871; X64-AVX1-NEXT: movabsq $3689065127958034230, %rax # imm = 0x3332313039383736 872; X64-AVX1-NEXT: xorq 16(%rdi), %rax 873; X64-AVX1-NEXT: movabsq $3978425819141910832, %rdx # imm = 0x3736353433323130 874; X64-AVX1-NEXT: xorq (%rdi), %rdx 875; X64-AVX1-NEXT: orq %rax, %rdx 876; X64-AVX1-NEXT: orq %rcx, %rdx 877; X64-AVX1-NEXT: setne %al 878; X64-AVX1-NEXT: retq 879; 880; X64-AVX2-LABEL: length32_eq_const: 881; X64-AVX2: # BB#0: 882; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 883; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0 884; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax 885; X64-AVX2-NEXT: cmpl $-1, %eax 886; X64-AVX2-NEXT: setne %al 887; X64-AVX2-NEXT: vzeroupper 888; X64-AVX2-NEXT: retq 889 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind 890 %c = icmp ne i32 %m, 0 891 ret i1 %c 892} 893 894define i32 @length64(i8* %X, i8* %Y) nounwind { 895; X86-LABEL: length64: 896; X86: # BB#0: 897; X86-NEXT: pushl $0 898; X86-NEXT: pushl $64 899; X86-NEXT: pushl {{[0-9]+}}(%esp) 900; X86-NEXT: pushl {{[0-9]+}}(%esp) 901; X86-NEXT: calll memcmp 902; X86-NEXT: addl $16, %esp 903; X86-NEXT: retl 904; 905; X64-LABEL: length64: 906; X64: # BB#0: 907; X64-NEXT: movl $64, %edx 908; X64-NEXT: jmp memcmp # TAILCALL 909 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind 910 ret i32 %m 911} 912 913define i1 @length64_eq(i8* %x, i8* %y) nounwind { 914; X86-LABEL: length64_eq: 915; X86: # BB#0: 916; X86-NEXT: pushl $0 917; X86-NEXT: pushl $64 918; X86-NEXT: pushl {{[0-9]+}}(%esp) 919; X86-NEXT: pushl {{[0-9]+}}(%esp) 920; X86-NEXT: calll memcmp 921; X86-NEXT: addl $16, %esp 922; X86-NEXT: testl %eax, %eax 923; X86-NEXT: setne %al 924; X86-NEXT: retl 925; 926; X64-LABEL: length64_eq: 927; X64: # BB#0: 928; X64-NEXT: pushq %rax 929; X64-NEXT: movl $64, %edx 930; X64-NEXT: callq memcmp 931; X64-NEXT: testl %eax, %eax 932; X64-NEXT: setne %al 933; X64-NEXT: popq %rcx 934; X64-NEXT: retq 935 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind 936 %cmp = icmp ne i32 %call, 0 937 ret i1 %cmp 938} 939 940define i1 @length64_eq_const(i8* %X) nounwind { 941; X86-LABEL: length64_eq_const: 942; X86: # BB#0: 943; X86-NEXT: pushl $0 944; X86-NEXT: pushl $64 945; X86-NEXT: pushl $.L.str 946; X86-NEXT: pushl {{[0-9]+}}(%esp) 947; X86-NEXT: calll memcmp 948; X86-NEXT: addl $16, %esp 949; X86-NEXT: testl %eax, %eax 950; X86-NEXT: sete %al 951; X86-NEXT: retl 952; 953; X64-LABEL: length64_eq_const: 954; X64: # BB#0: 955; X64-NEXT: pushq %rax 956; X64-NEXT: movl $.L.str, %esi 957; X64-NEXT: movl $64, %edx 958; X64-NEXT: callq memcmp 959; X64-NEXT: testl %eax, %eax 960; X64-NEXT: sete %al 961; X64-NEXT: popq %rcx 962; X64-NEXT: retq 963 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind 964 %c = icmp eq i32 %m, 0 965 ret i1 %c 966} 967 968