OSDN Git Service

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