Home | History | Annotate | Download | only in X86
      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