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-prefixes=X86,X86-NOSSE 3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=X86,X86-SSE2 4 5; This tests codegen time inlining/optimization of memcmp 6; rdar://6480398 7 8@.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1 9 10declare dso_local i32 @memcmp(ptr, ptr, i32) 11 12define i32 @length2(ptr %X, ptr %Y) nounwind minsize { 13; X86-LABEL: length2: 14; X86: # %bb.0: 15; X86-NEXT: pushl $2 16; X86-NEXT: pushl {{[0-9]+}}(%esp) 17; X86-NEXT: pushl {{[0-9]+}}(%esp) 18; X86-NEXT: calll memcmp 19; X86-NEXT: addl $12, %esp 20; X86-NEXT: retl 21 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 2) nounwind 22 ret i32 %m 23} 24 25define i1 @length2_eq(ptr %X, ptr %Y) nounwind minsize { 26; X86-LABEL: length2_eq: 27; X86: # %bb.0: 28; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 29; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 30; X86-NEXT: movzwl (%ecx), %ecx 31; X86-NEXT: cmpw (%eax), %cx 32; X86-NEXT: sete %al 33; X86-NEXT: retl 34 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 2) nounwind 35 %c = icmp eq i32 %m, 0 36 ret i1 %c 37} 38 39define i1 @length2_eq_const(ptr %X) nounwind minsize { 40; X86-LABEL: length2_eq_const: 41; X86: # %bb.0: 42; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 43; X86-NEXT: cmpw $12849, (%eax) # imm = 0x3231 44; X86-NEXT: setne %al 45; X86-NEXT: retl 46 %m = tail call i32 @memcmp(ptr %X, ptr getelementptr inbounds ([65 x i8], ptr @.str, i32 0, i32 1), i32 2) nounwind 47 %c = icmp ne i32 %m, 0 48 ret i1 %c 49} 50 51define i1 @length2_eq_nobuiltin_attr(ptr %X, ptr %Y) nounwind minsize { 52; X86-LABEL: length2_eq_nobuiltin_attr: 53; X86: # %bb.0: 54; X86-NEXT: pushl $2 55; X86-NEXT: pushl {{[0-9]+}}(%esp) 56; X86-NEXT: pushl {{[0-9]+}}(%esp) 57; X86-NEXT: calll memcmp 58; X86-NEXT: addl $12, %esp 59; X86-NEXT: testl %eax, %eax 60; X86-NEXT: sete %al 61; X86-NEXT: retl 62 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 2) nounwind nobuiltin 63 %c = icmp eq i32 %m, 0 64 ret i1 %c 65} 66 67define i32 @length3(ptr %X, ptr %Y) nounwind minsize { 68; X86-LABEL: length3: 69; X86: # %bb.0: 70; X86-NEXT: pushl $3 71; X86-NEXT: pushl {{[0-9]+}}(%esp) 72; X86-NEXT: pushl {{[0-9]+}}(%esp) 73; X86-NEXT: calll memcmp 74; X86-NEXT: addl $12, %esp 75; X86-NEXT: retl 76 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 3) nounwind 77 ret i32 %m 78} 79 80define i1 @length3_eq(ptr %X, ptr %Y) nounwind minsize { 81; X86-LABEL: length3_eq: 82; X86: # %bb.0: 83; X86-NEXT: pushl $3 84; X86-NEXT: pushl {{[0-9]+}}(%esp) 85; X86-NEXT: pushl {{[0-9]+}}(%esp) 86; X86-NEXT: calll memcmp 87; X86-NEXT: addl $12, %esp 88; X86-NEXT: testl %eax, %eax 89; X86-NEXT: setne %al 90; X86-NEXT: retl 91 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 3) nounwind 92 %c = icmp ne i32 %m, 0 93 ret i1 %c 94} 95 96define i32 @length4(ptr %X, ptr %Y) nounwind minsize { 97; X86-LABEL: length4: 98; X86: # %bb.0: 99; X86-NEXT: pushl $4 100; X86-NEXT: pushl {{[0-9]+}}(%esp) 101; X86-NEXT: pushl {{[0-9]+}}(%esp) 102; X86-NEXT: calll memcmp 103; X86-NEXT: addl $12, %esp 104; X86-NEXT: retl 105 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 4) nounwind 106 ret i32 %m 107} 108 109define i1 @length4_eq(ptr %X, ptr %Y) nounwind minsize { 110; X86-LABEL: length4_eq: 111; X86: # %bb.0: 112; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 113; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 114; X86-NEXT: movl (%ecx), %ecx 115; X86-NEXT: cmpl (%eax), %ecx 116; X86-NEXT: setne %al 117; X86-NEXT: retl 118 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 4) nounwind 119 %c = icmp ne i32 %m, 0 120 ret i1 %c 121} 122 123define i1 @length4_eq_const(ptr %X) nounwind minsize { 124; X86-LABEL: length4_eq_const: 125; X86: # %bb.0: 126; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 127; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231 128; X86-NEXT: sete %al 129; X86-NEXT: retl 130 %m = tail call i32 @memcmp(ptr %X, ptr getelementptr inbounds ([65 x i8], ptr @.str, i32 0, i32 1), i32 4) nounwind 131 %c = icmp eq i32 %m, 0 132 ret i1 %c 133} 134 135define i32 @length5(ptr %X, ptr %Y) nounwind minsize { 136; X86-LABEL: length5: 137; X86: # %bb.0: 138; X86-NEXT: pushl $5 139; X86-NEXT: pushl {{[0-9]+}}(%esp) 140; X86-NEXT: pushl {{[0-9]+}}(%esp) 141; X86-NEXT: calll memcmp 142; X86-NEXT: addl $12, %esp 143; X86-NEXT: retl 144 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 5) nounwind 145 ret i32 %m 146} 147 148define i1 @length5_eq(ptr %X, ptr %Y) nounwind minsize { 149; X86-LABEL: length5_eq: 150; X86: # %bb.0: 151; X86-NEXT: pushl $5 152; X86-NEXT: pushl {{[0-9]+}}(%esp) 153; X86-NEXT: pushl {{[0-9]+}}(%esp) 154; X86-NEXT: calll memcmp 155; X86-NEXT: addl $12, %esp 156; X86-NEXT: testl %eax, %eax 157; X86-NEXT: setne %al 158; X86-NEXT: retl 159 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 5) nounwind 160 %c = icmp ne i32 %m, 0 161 ret i1 %c 162} 163 164define i32 @length8(ptr %X, ptr %Y) nounwind minsize { 165; X86-LABEL: length8: 166; X86: # %bb.0: 167; X86-NEXT: pushl $8 168; X86-NEXT: pushl {{[0-9]+}}(%esp) 169; X86-NEXT: pushl {{[0-9]+}}(%esp) 170; X86-NEXT: calll memcmp 171; X86-NEXT: addl $12, %esp 172; X86-NEXT: retl 173 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 8) nounwind 174 ret i32 %m 175} 176 177define i1 @length8_eq(ptr %X, ptr %Y) nounwind minsize { 178; X86-LABEL: length8_eq: 179; X86: # %bb.0: 180; X86-NEXT: pushl $8 181; X86-NEXT: pushl {{[0-9]+}}(%esp) 182; X86-NEXT: pushl {{[0-9]+}}(%esp) 183; X86-NEXT: calll memcmp 184; X86-NEXT: addl $12, %esp 185; X86-NEXT: testl %eax, %eax 186; X86-NEXT: sete %al 187; X86-NEXT: retl 188 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 8) nounwind 189 %c = icmp eq i32 %m, 0 190 ret i1 %c 191} 192 193define i1 @length8_eq_const(ptr %X) nounwind minsize { 194; X86-LABEL: length8_eq_const: 195; X86: # %bb.0: 196; X86-NEXT: pushl $8 197; X86-NEXT: pushl $.L.str 198; X86-NEXT: pushl {{[0-9]+}}(%esp) 199; X86-NEXT: calll memcmp 200; X86-NEXT: addl $12, %esp 201; X86-NEXT: testl %eax, %eax 202; X86-NEXT: setne %al 203; X86-NEXT: retl 204 %m = tail call i32 @memcmp(ptr %X, ptr @.str, i32 8) nounwind 205 %c = icmp ne i32 %m, 0 206 ret i1 %c 207} 208 209define i1 @length12_eq(ptr %X, ptr %Y) nounwind minsize { 210; X86-LABEL: length12_eq: 211; X86: # %bb.0: 212; X86-NEXT: pushl $12 213; X86-NEXT: pushl {{[0-9]+}}(%esp) 214; X86-NEXT: pushl {{[0-9]+}}(%esp) 215; X86-NEXT: calll memcmp 216; X86-NEXT: addl $12, %esp 217; X86-NEXT: testl %eax, %eax 218; X86-NEXT: setne %al 219; X86-NEXT: retl 220 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 12) nounwind 221 %c = icmp ne i32 %m, 0 222 ret i1 %c 223} 224 225define i32 @length12(ptr %X, ptr %Y) nounwind minsize { 226; X86-LABEL: length12: 227; X86: # %bb.0: 228; X86-NEXT: pushl $12 229; X86-NEXT: pushl {{[0-9]+}}(%esp) 230; X86-NEXT: pushl {{[0-9]+}}(%esp) 231; X86-NEXT: calll memcmp 232; X86-NEXT: addl $12, %esp 233; X86-NEXT: retl 234 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 12) nounwind 235 ret i32 %m 236} 237 238; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329 239 240define i32 @length16(ptr %X, ptr %Y) nounwind minsize { 241; X86-LABEL: length16: 242; X86: # %bb.0: 243; X86-NEXT: pushl $16 244; X86-NEXT: pushl {{[0-9]+}}(%esp) 245; X86-NEXT: pushl {{[0-9]+}}(%esp) 246; X86-NEXT: calll memcmp 247; X86-NEXT: addl $12, %esp 248; X86-NEXT: retl 249 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 16) nounwind 250 ret i32 %m 251} 252 253define i1 @length16_eq(ptr %x, ptr %y) nounwind minsize { 254; X86-NOSSE-LABEL: length16_eq: 255; X86-NOSSE: # %bb.0: 256; X86-NOSSE-NEXT: pushl $16 257; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 258; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 259; X86-NOSSE-NEXT: calll memcmp 260; X86-NOSSE-NEXT: addl $12, %esp 261; X86-NOSSE-NEXT: testl %eax, %eax 262; X86-NOSSE-NEXT: setne %al 263; X86-NOSSE-NEXT: retl 264; 265; X86-SSE2-LABEL: length16_eq: 266; X86-SSE2: # %bb.0: 267; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 268; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx 269; X86-SSE2-NEXT: movdqu (%ecx), %xmm0 270; X86-SSE2-NEXT: movdqu (%eax), %xmm1 271; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1 272; X86-SSE2-NEXT: pmovmskb %xmm1, %eax 273; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 274; X86-SSE2-NEXT: setne %al 275; X86-SSE2-NEXT: retl 276 %call = tail call i32 @memcmp(ptr %x, ptr %y, i32 16) nounwind 277 %cmp = icmp ne i32 %call, 0 278 ret i1 %cmp 279} 280 281define i1 @length16_eq_const(ptr %X) nounwind minsize { 282; X86-NOSSE-LABEL: length16_eq_const: 283; X86-NOSSE: # %bb.0: 284; X86-NOSSE-NEXT: pushl $16 285; X86-NOSSE-NEXT: pushl $.L.str 286; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp) 287; X86-NOSSE-NEXT: calll memcmp 288; X86-NOSSE-NEXT: addl $12, %esp 289; X86-NOSSE-NEXT: testl %eax, %eax 290; X86-NOSSE-NEXT: sete %al 291; X86-NOSSE-NEXT: retl 292; 293; X86-SSE2-LABEL: length16_eq_const: 294; X86-SSE2: # %bb.0: 295; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax 296; X86-SSE2-NEXT: movdqu (%eax), %xmm0 297; X86-SSE2-NEXT: pcmpeqb {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 298; X86-SSE2-NEXT: pmovmskb %xmm0, %eax 299; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF 300; X86-SSE2-NEXT: sete %al 301; X86-SSE2-NEXT: retl 302 %m = tail call i32 @memcmp(ptr %X, ptr @.str, i32 16) nounwind 303 %c = icmp eq i32 %m, 0 304 ret i1 %c 305} 306 307; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914 308 309define i32 @length24(ptr %X, ptr %Y) nounwind minsize { 310; X86-LABEL: length24: 311; X86: # %bb.0: 312; X86-NEXT: pushl $24 313; X86-NEXT: pushl {{[0-9]+}}(%esp) 314; X86-NEXT: pushl {{[0-9]+}}(%esp) 315; X86-NEXT: calll memcmp 316; X86-NEXT: addl $12, %esp 317; X86-NEXT: retl 318 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 24) nounwind 319 ret i32 %m 320} 321 322define i1 @length24_eq(ptr %x, ptr %y) nounwind minsize { 323; X86-LABEL: length24_eq: 324; X86: # %bb.0: 325; X86-NEXT: pushl $24 326; X86-NEXT: pushl {{[0-9]+}}(%esp) 327; X86-NEXT: pushl {{[0-9]+}}(%esp) 328; X86-NEXT: calll memcmp 329; X86-NEXT: addl $12, %esp 330; X86-NEXT: testl %eax, %eax 331; X86-NEXT: sete %al 332; X86-NEXT: retl 333 %call = tail call i32 @memcmp(ptr %x, ptr %y, i32 24) nounwind 334 %cmp = icmp eq i32 %call, 0 335 ret i1 %cmp 336} 337 338define i1 @length24_eq_const(ptr %X) nounwind minsize { 339; X86-LABEL: length24_eq_const: 340; X86: # %bb.0: 341; X86-NEXT: pushl $24 342; X86-NEXT: pushl $.L.str 343; X86-NEXT: pushl {{[0-9]+}}(%esp) 344; X86-NEXT: calll memcmp 345; X86-NEXT: addl $12, %esp 346; X86-NEXT: testl %eax, %eax 347; X86-NEXT: setne %al 348; X86-NEXT: retl 349 %m = tail call i32 @memcmp(ptr %X, ptr @.str, i32 24) nounwind 350 %c = icmp ne i32 %m, 0 351 ret i1 %c 352} 353 354define i32 @length32(ptr %X, ptr %Y) nounwind minsize { 355; X86-LABEL: length32: 356; X86: # %bb.0: 357; X86-NEXT: pushl $32 358; X86-NEXT: pushl {{[0-9]+}}(%esp) 359; X86-NEXT: pushl {{[0-9]+}}(%esp) 360; X86-NEXT: calll memcmp 361; X86-NEXT: addl $12, %esp 362; X86-NEXT: retl 363 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 32) nounwind 364 ret i32 %m 365} 366 367; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325 368 369define i1 @length32_eq(ptr %x, ptr %y) nounwind minsize { 370; X86-LABEL: length32_eq: 371; X86: # %bb.0: 372; X86-NEXT: pushl $32 373; X86-NEXT: pushl {{[0-9]+}}(%esp) 374; X86-NEXT: pushl {{[0-9]+}}(%esp) 375; X86-NEXT: calll memcmp 376; X86-NEXT: addl $12, %esp 377; X86-NEXT: testl %eax, %eax 378; X86-NEXT: sete %al 379; X86-NEXT: retl 380 %call = tail call i32 @memcmp(ptr %x, ptr %y, i32 32) nounwind 381 %cmp = icmp eq i32 %call, 0 382 ret i1 %cmp 383} 384 385define i1 @length32_eq_const(ptr %X) nounwind minsize { 386; X86-LABEL: length32_eq_const: 387; X86: # %bb.0: 388; X86-NEXT: pushl $32 389; X86-NEXT: pushl $.L.str 390; X86-NEXT: pushl {{[0-9]+}}(%esp) 391; X86-NEXT: calll memcmp 392; X86-NEXT: addl $12, %esp 393; X86-NEXT: testl %eax, %eax 394; X86-NEXT: setne %al 395; X86-NEXT: retl 396 %m = tail call i32 @memcmp(ptr %X, ptr @.str, i32 32) nounwind 397 %c = icmp ne i32 %m, 0 398 ret i1 %c 399} 400 401define i32 @length64(ptr %X, ptr %Y) nounwind minsize { 402; X86-LABEL: length64: 403; X86: # %bb.0: 404; X86-NEXT: pushl $64 405; X86-NEXT: pushl {{[0-9]+}}(%esp) 406; X86-NEXT: pushl {{[0-9]+}}(%esp) 407; X86-NEXT: calll memcmp 408; X86-NEXT: addl $12, %esp 409; X86-NEXT: retl 410 %m = tail call i32 @memcmp(ptr %X, ptr %Y, i32 64) nounwind 411 ret i32 %m 412} 413 414define i1 @length64_eq(ptr %x, ptr %y) nounwind minsize { 415; X86-LABEL: length64_eq: 416; X86: # %bb.0: 417; X86-NEXT: pushl $64 418; X86-NEXT: pushl {{[0-9]+}}(%esp) 419; X86-NEXT: pushl {{[0-9]+}}(%esp) 420; X86-NEXT: calll memcmp 421; X86-NEXT: addl $12, %esp 422; X86-NEXT: testl %eax, %eax 423; X86-NEXT: setne %al 424; X86-NEXT: retl 425 %call = tail call i32 @memcmp(ptr %x, ptr %y, i32 64) nounwind 426 %cmp = icmp ne i32 %call, 0 427 ret i1 %cmp 428} 429 430define i1 @length64_eq_const(ptr %X) nounwind minsize { 431; X86-LABEL: length64_eq_const: 432; X86: # %bb.0: 433; X86-NEXT: pushl $64 434; X86-NEXT: pushl $.L.str 435; X86-NEXT: pushl {{[0-9]+}}(%esp) 436; X86-NEXT: calll memcmp 437; X86-NEXT: addl $12, %esp 438; X86-NEXT: testl %eax, %eax 439; X86-NEXT: sete %al 440; X86-NEXT: retl 441 %m = tail call i32 @memcmp(ptr %X, ptr @.str, i32 64) nounwind 442 %c = icmp eq i32 %m, 0 443 ret i1 %c 444} 445 446