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 14 declare i32 @memcmp(i8*, i8*, i64) 15 16 define 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 30 define 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 45 define 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 73 define 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 94 define 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 114 define 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 141 define 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 188 define 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 217 define 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 247 define 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 268 define 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 286 define 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 333 define 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 362 define 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 406 define 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 430 define 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 453 define 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 480 define 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 520 define 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 558 define 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 618 define 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 677 define 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 696 define 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 740 define 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 785 define 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 806 define 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 887 define 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 963 define 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 982 define 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 1032 define 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. 1085 define 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