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
7 ; This tests codegen time inlining/optimization of memcmp
10 @.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1
12 declare i32 @memcmp(i8*, i8*, i64)
14 define i32 @length2(i8* %X, i8* %Y) nounwind optsize {
17 ; X86-NEXT: pushl %edi
18 ; X86-NEXT: pushl %esi
19 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
20 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
21 ; X86-NEXT: movzwl (%ecx), %ecx
22 ; X86-NEXT: movzwl (%eax), %edx
23 ; X86-NEXT: rolw $8, %cx
24 ; X86-NEXT: rolw $8, %dx
25 ; X86-NEXT: xorl %esi, %esi
26 ; X86-NEXT: xorl %edi, %edi
28 ; X86-NEXT: xorl %eax, %eax
30 ; X86-NEXT: cmpw %dx, %cx
31 ; X86-NEXT: cmovael %edi, %eax
32 ; X86-NEXT: cmovel %esi, %eax
39 ; X64-NEXT: movzwl (%rdi), %eax
40 ; X64-NEXT: movzwl (%rsi), %ecx
41 ; X64-NEXT: rolw $8, %ax
42 ; X64-NEXT: rolw $8, %cx
43 ; X64-NEXT: xorl %edx, %edx
44 ; X64-NEXT: cmpw %cx, %ax
45 ; X64-NEXT: movl $-1, %ecx
46 ; X64-NEXT: movl $1, %eax
47 ; X64-NEXT: cmovbl %ecx, %eax
48 ; X64-NEXT: cmovel %edx, %eax
50 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
54 define i1 @length2_eq(i8* %X, i8* %Y) nounwind optsize {
55 ; X86-LABEL: length2_eq:
57 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
58 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
59 ; X86-NEXT: movzwl (%ecx), %ecx
60 ; X86-NEXT: cmpw (%eax), %cx
64 ; X64-LABEL: length2_eq:
66 ; X64-NEXT: movzwl (%rdi), %eax
67 ; X64-NEXT: cmpw (%rsi), %ax
70 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
71 %c = icmp eq i32 %m, 0
75 define i1 @length2_eq_const(i8* %X) nounwind optsize {
76 ; X86-LABEL: length2_eq_const:
78 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
79 ; X86-NEXT: movzwl (%eax), %eax
80 ; X86-NEXT: cmpl $12849, %eax # imm = 0x3231
84 ; X64-LABEL: length2_eq_const:
86 ; X64-NEXT: movzwl (%rdi), %eax
87 ; X64-NEXT: cmpl $12849, %eax # imm = 0x3231
90 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind
91 %c = icmp ne i32 %m, 0
95 define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind optsize {
96 ; X86-LABEL: length2_eq_nobuiltin_attr:
100 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
101 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
102 ; X86-NEXT: calll memcmp
103 ; X86-NEXT: addl $16, %esp
104 ; X86-NEXT: testl %eax, %eax
108 ; X64-LABEL: length2_eq_nobuiltin_attr:
110 ; X64-NEXT: pushq %rax
111 ; X64-NEXT: movl $2, %edx
112 ; X64-NEXT: callq memcmp
113 ; X64-NEXT: testl %eax, %eax
115 ; X64-NEXT: popq %rcx
117 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin
118 %c = icmp eq i32 %m, 0
122 define i32 @length3(i8* %X, i8* %Y) nounwind optsize {
123 ; X86-LABEL: length3:
124 ; X86: # BB#0: # %loadbb
125 ; X86-NEXT: pushl %esi
126 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
127 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
128 ; X86-NEXT: movzwl (%eax), %edx
129 ; X86-NEXT: movzwl (%ecx), %esi
130 ; X86-NEXT: rolw $8, %dx
131 ; X86-NEXT: rolw $8, %si
132 ; X86-NEXT: movzwl %dx, %edx
133 ; X86-NEXT: movzwl %si, %esi
134 ; X86-NEXT: cmpl %esi, %edx
135 ; X86-NEXT: jne .LBB4_1
136 ; X86-NEXT: # BB#2: # %loadbb1
137 ; X86-NEXT: movzbl 2(%eax), %eax
138 ; X86-NEXT: movzbl 2(%ecx), %ecx
139 ; X86-NEXT: subl %ecx, %eax
140 ; X86-NEXT: jmp .LBB4_3
141 ; X86-NEXT: .LBB4_1: # %res_block
142 ; X86-NEXT: xorl %ecx, %ecx
143 ; X86-NEXT: incl %ecx
144 ; X86-NEXT: xorl %eax, %eax
145 ; X86-NEXT: decl %eax
146 ; X86-NEXT: cmpl %esi, %edx
147 ; X86-NEXT: cmovael %ecx, %eax
148 ; X86-NEXT: .LBB4_3: # %endblock
149 ; X86-NEXT: popl %esi
152 ; X64-LABEL: length3:
153 ; X64: # BB#0: # %loadbb
154 ; X64-NEXT: movzwl (%rdi), %eax
155 ; X64-NEXT: movzwl (%rsi), %ecx
156 ; X64-NEXT: rolw $8, %ax
157 ; X64-NEXT: rolw $8, %cx
158 ; X64-NEXT: movzwl %ax, %eax
159 ; X64-NEXT: movzwl %cx, %ecx
160 ; X64-NEXT: cmpq %rcx, %rax
161 ; X64-NEXT: jne .LBB4_1
162 ; X64-NEXT: # BB#2: # %loadbb1
163 ; X64-NEXT: movzbl 2(%rdi), %eax
164 ; X64-NEXT: movzbl 2(%rsi), %ecx
165 ; X64-NEXT: subl %ecx, %eax
167 ; X64-NEXT: .LBB4_1: # %res_block
168 ; X64-NEXT: movl $-1, %ecx
169 ; X64-NEXT: movl $1, %eax
170 ; X64-NEXT: cmovbl %ecx, %eax
172 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
176 define i1 @length3_eq(i8* %X, i8* %Y) nounwind optsize {
177 ; X86-LABEL: length3_eq:
178 ; X86: # BB#0: # %loadbb
179 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
180 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
181 ; X86-NEXT: movzwl (%eax), %edx
182 ; X86-NEXT: cmpw (%ecx), %dx
183 ; X86-NEXT: jne .LBB5_1
184 ; X86-NEXT: # BB#2: # %loadbb1
185 ; X86-NEXT: movb 2(%eax), %dl
186 ; X86-NEXT: xorl %eax, %eax
187 ; X86-NEXT: cmpb 2(%ecx), %dl
188 ; X86-NEXT: je .LBB5_3
189 ; X86-NEXT: .LBB5_1: # %res_block
190 ; X86-NEXT: xorl %eax, %eax
191 ; X86-NEXT: incl %eax
192 ; X86-NEXT: .LBB5_3: # %endblock
193 ; X86-NEXT: testl %eax, %eax
194 ; X86-NEXT: setne %al
197 ; X64-LABEL: length3_eq:
198 ; X64: # BB#0: # %loadbb
199 ; X64-NEXT: movzwl (%rdi), %eax
200 ; X64-NEXT: cmpw (%rsi), %ax
201 ; X64-NEXT: jne .LBB5_1
202 ; X64-NEXT: # BB#2: # %loadbb1
203 ; X64-NEXT: movb 2(%rdi), %cl
204 ; X64-NEXT: xorl %eax, %eax
205 ; X64-NEXT: cmpb 2(%rsi), %cl
206 ; X64-NEXT: je .LBB5_3
207 ; X64-NEXT: .LBB5_1: # %res_block
208 ; X64-NEXT: movl $1, %eax
209 ; X64-NEXT: .LBB5_3: # %endblock
210 ; X64-NEXT: testl %eax, %eax
211 ; X64-NEXT: setne %al
213 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
214 %c = icmp ne i32 %m, 0
218 define i32 @length4(i8* %X, i8* %Y) nounwind optsize {
219 ; X86-LABEL: length4:
221 ; X86-NEXT: pushl %edi
222 ; X86-NEXT: pushl %esi
223 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
224 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
225 ; X86-NEXT: movl (%ecx), %ecx
226 ; X86-NEXT: movl (%eax), %edx
227 ; X86-NEXT: bswapl %ecx
228 ; X86-NEXT: bswapl %edx
229 ; X86-NEXT: xorl %esi, %esi
230 ; X86-NEXT: xorl %edi, %edi
231 ; X86-NEXT: incl %edi
232 ; X86-NEXT: xorl %eax, %eax
233 ; X86-NEXT: decl %eax
234 ; X86-NEXT: cmpl %edx, %ecx
235 ; X86-NEXT: cmovael %edi, %eax
236 ; X86-NEXT: cmovel %esi, %eax
237 ; X86-NEXT: popl %esi
238 ; X86-NEXT: popl %edi
241 ; X64-LABEL: length4:
243 ; X64-NEXT: movl (%rdi), %eax
244 ; X64-NEXT: movl (%rsi), %ecx
245 ; X64-NEXT: bswapl %eax
246 ; X64-NEXT: bswapl %ecx
247 ; X64-NEXT: xorl %edx, %edx
248 ; X64-NEXT: cmpl %ecx, %eax
249 ; X64-NEXT: movl $-1, %ecx
250 ; X64-NEXT: movl $1, %eax
251 ; X64-NEXT: cmovbl %ecx, %eax
252 ; X64-NEXT: cmovel %edx, %eax
254 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
258 define i1 @length4_eq(i8* %X, i8* %Y) nounwind optsize {
259 ; X86-LABEL: length4_eq:
261 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
262 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
263 ; X86-NEXT: movl (%ecx), %ecx
264 ; X86-NEXT: cmpl (%eax), %ecx
265 ; X86-NEXT: setne %al
268 ; X64-LABEL: length4_eq:
270 ; X64-NEXT: movl (%rdi), %eax
271 ; X64-NEXT: cmpl (%rsi), %eax
272 ; X64-NEXT: setne %al
274 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
275 %c = icmp ne i32 %m, 0
279 define i1 @length4_eq_const(i8* %X) nounwind optsize {
280 ; X86-LABEL: length4_eq_const:
282 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
283 ; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231
287 ; X64-LABEL: length4_eq_const:
289 ; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231
292 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
293 %c = icmp eq i32 %m, 0
297 define i32 @length5(i8* %X, i8* %Y) nounwind optsize {
298 ; X86-LABEL: length5:
299 ; X86: # BB#0: # %loadbb
300 ; X86-NEXT: pushl %esi
301 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
302 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
303 ; X86-NEXT: movl (%eax), %edx
304 ; X86-NEXT: movl (%ecx), %esi
305 ; X86-NEXT: bswapl %edx
306 ; X86-NEXT: bswapl %esi
307 ; X86-NEXT: cmpl %esi, %edx
308 ; X86-NEXT: jne .LBB9_1
309 ; X86-NEXT: # BB#2: # %loadbb1
310 ; X86-NEXT: movzbl 4(%eax), %eax
311 ; X86-NEXT: movzbl 4(%ecx), %ecx
312 ; X86-NEXT: subl %ecx, %eax
313 ; X86-NEXT: jmp .LBB9_3
314 ; X86-NEXT: .LBB9_1: # %res_block
315 ; X86-NEXT: xorl %ecx, %ecx
316 ; X86-NEXT: incl %ecx
317 ; X86-NEXT: xorl %eax, %eax
318 ; X86-NEXT: decl %eax
319 ; X86-NEXT: cmpl %esi, %edx
320 ; X86-NEXT: cmovael %ecx, %eax
321 ; X86-NEXT: .LBB9_3: # %endblock
322 ; X86-NEXT: popl %esi
325 ; X64-LABEL: length5:
326 ; X64: # BB#0: # %loadbb
327 ; X64-NEXT: movl (%rdi), %eax
328 ; X64-NEXT: movl (%rsi), %ecx
329 ; X64-NEXT: bswapl %eax
330 ; X64-NEXT: bswapl %ecx
331 ; X64-NEXT: cmpq %rcx, %rax
332 ; X64-NEXT: jne .LBB9_1
333 ; X64-NEXT: # BB#2: # %loadbb1
334 ; X64-NEXT: movzbl 4(%rdi), %eax
335 ; X64-NEXT: movzbl 4(%rsi), %ecx
336 ; X64-NEXT: subl %ecx, %eax
338 ; X64-NEXT: .LBB9_1: # %res_block
339 ; X64-NEXT: movl $-1, %ecx
340 ; X64-NEXT: movl $1, %eax
341 ; X64-NEXT: cmovbl %ecx, %eax
343 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
347 define i1 @length5_eq(i8* %X, i8* %Y) nounwind optsize {
348 ; X86-LABEL: length5_eq:
349 ; X86: # BB#0: # %loadbb
350 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
351 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
352 ; X86-NEXT: movl (%eax), %edx
353 ; X86-NEXT: cmpl (%ecx), %edx
354 ; X86-NEXT: jne .LBB10_1
355 ; X86-NEXT: # BB#2: # %loadbb1
356 ; X86-NEXT: movb 4(%eax), %dl
357 ; X86-NEXT: xorl %eax, %eax
358 ; X86-NEXT: cmpb 4(%ecx), %dl
359 ; X86-NEXT: je .LBB10_3
360 ; X86-NEXT: .LBB10_1: # %res_block
361 ; X86-NEXT: xorl %eax, %eax
362 ; X86-NEXT: incl %eax
363 ; X86-NEXT: .LBB10_3: # %endblock
364 ; X86-NEXT: testl %eax, %eax
365 ; X86-NEXT: setne %al
368 ; X64-LABEL: length5_eq:
369 ; X64: # BB#0: # %loadbb
370 ; X64-NEXT: movl (%rdi), %eax
371 ; X64-NEXT: cmpl (%rsi), %eax
372 ; X64-NEXT: jne .LBB10_1
373 ; X64-NEXT: # BB#2: # %loadbb1
374 ; X64-NEXT: movb 4(%rdi), %cl
375 ; X64-NEXT: xorl %eax, %eax
376 ; X64-NEXT: cmpb 4(%rsi), %cl
377 ; X64-NEXT: je .LBB10_3
378 ; X64-NEXT: .LBB10_1: # %res_block
379 ; X64-NEXT: movl $1, %eax
380 ; X64-NEXT: .LBB10_3: # %endblock
381 ; X64-NEXT: testl %eax, %eax
382 ; X64-NEXT: setne %al
384 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
385 %c = icmp ne i32 %m, 0
389 define i32 @length8(i8* %X, i8* %Y) nounwind optsize {
390 ; X86-LABEL: length8:
391 ; X86: # BB#0: # %loadbb
392 ; X86-NEXT: pushl %esi
393 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
394 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
395 ; X86-NEXT: movl (%esi), %ecx
396 ; X86-NEXT: movl (%eax), %edx
397 ; X86-NEXT: bswapl %ecx
398 ; X86-NEXT: bswapl %edx
399 ; X86-NEXT: cmpl %edx, %ecx
400 ; X86-NEXT: jne .LBB11_1
401 ; X86-NEXT: # BB#2: # %loadbb1
402 ; X86-NEXT: movl 4(%esi), %ecx
403 ; X86-NEXT: movl 4(%eax), %edx
404 ; X86-NEXT: bswapl %ecx
405 ; X86-NEXT: bswapl %edx
406 ; X86-NEXT: xorl %eax, %eax
407 ; X86-NEXT: cmpl %edx, %ecx
408 ; X86-NEXT: je .LBB11_3
409 ; X86-NEXT: .LBB11_1: # %res_block
410 ; X86-NEXT: xorl %esi, %esi
411 ; X86-NEXT: incl %esi
412 ; X86-NEXT: xorl %eax, %eax
413 ; X86-NEXT: decl %eax
414 ; X86-NEXT: cmpl %edx, %ecx
415 ; X86-NEXT: cmovael %esi, %eax
416 ; X86-NEXT: .LBB11_3: # %endblock
417 ; X86-NEXT: popl %esi
420 ; X64-LABEL: length8:
422 ; X64-NEXT: movq (%rdi), %rax
423 ; X64-NEXT: movq (%rsi), %rcx
424 ; X64-NEXT: bswapq %rax
425 ; X64-NEXT: bswapq %rcx
426 ; X64-NEXT: xorl %edx, %edx
427 ; X64-NEXT: cmpq %rcx, %rax
428 ; X64-NEXT: movl $-1, %ecx
429 ; X64-NEXT: movl $1, %eax
430 ; X64-NEXT: cmovbl %ecx, %eax
431 ; X64-NEXT: cmovel %edx, %eax
433 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
437 define i1 @length8_eq(i8* %X, i8* %Y) nounwind optsize {
438 ; X86-LABEL: length8_eq:
439 ; X86: # BB#0: # %loadbb
440 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
441 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
442 ; X86-NEXT: movl (%eax), %edx
443 ; X86-NEXT: cmpl (%ecx), %edx
444 ; X86-NEXT: jne .LBB12_1
445 ; X86-NEXT: # BB#2: # %loadbb1
446 ; X86-NEXT: movl 4(%eax), %edx
447 ; X86-NEXT: xorl %eax, %eax
448 ; X86-NEXT: cmpl 4(%ecx), %edx
449 ; X86-NEXT: je .LBB12_3
450 ; X86-NEXT: .LBB12_1: # %res_block
451 ; X86-NEXT: xorl %eax, %eax
452 ; X86-NEXT: incl %eax
453 ; X86-NEXT: .LBB12_3: # %endblock
454 ; X86-NEXT: testl %eax, %eax
458 ; X64-LABEL: length8_eq:
460 ; X64-NEXT: movq (%rdi), %rax
461 ; X64-NEXT: cmpq (%rsi), %rax
464 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
465 %c = icmp eq i32 %m, 0
469 define i1 @length8_eq_const(i8* %X) nounwind optsize {
470 ; X86-LABEL: length8_eq_const:
471 ; X86: # BB#0: # %loadbb
472 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
473 ; X86-NEXT: cmpl $858927408, (%ecx) # imm = 0x33323130
474 ; X86-NEXT: jne .LBB13_1
475 ; X86-NEXT: # BB#2: # %loadbb1
476 ; X86-NEXT: xorl %eax, %eax
477 ; X86-NEXT: cmpl $926299444, 4(%ecx) # imm = 0x37363534
478 ; X86-NEXT: je .LBB13_3
479 ; X86-NEXT: .LBB13_1: # %res_block
480 ; X86-NEXT: xorl %eax, %eax
481 ; X86-NEXT: incl %eax
482 ; X86-NEXT: .LBB13_3: # %endblock
483 ; X86-NEXT: testl %eax, %eax
484 ; X86-NEXT: setne %al
487 ; X64-LABEL: length8_eq_const:
489 ; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
490 ; X64-NEXT: cmpq %rax, (%rdi)
491 ; X64-NEXT: setne %al
493 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
494 %c = icmp ne i32 %m, 0
498 define i1 @length12_eq(i8* %X, i8* %Y) nounwind optsize {
499 ; X86-LABEL: length12_eq:
502 ; X86-NEXT: pushl $12
503 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
504 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
505 ; X86-NEXT: calll memcmp
506 ; X86-NEXT: addl $16, %esp
507 ; X86-NEXT: testl %eax, %eax
508 ; X86-NEXT: setne %al
511 ; X64-LABEL: length12_eq:
512 ; X64: # BB#0: # %loadbb
513 ; X64-NEXT: movq (%rdi), %rax
514 ; X64-NEXT: cmpq (%rsi), %rax
515 ; X64-NEXT: jne .LBB14_1
516 ; X64-NEXT: # BB#2: # %loadbb1
517 ; X64-NEXT: movl 8(%rdi), %ecx
518 ; X64-NEXT: xorl %eax, %eax
519 ; X64-NEXT: cmpl 8(%rsi), %ecx
520 ; X64-NEXT: je .LBB14_3
521 ; X64-NEXT: .LBB14_1: # %res_block
522 ; X64-NEXT: movl $1, %eax
523 ; X64-NEXT: .LBB14_3: # %endblock
524 ; X64-NEXT: testl %eax, %eax
525 ; X64-NEXT: setne %al
527 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
528 %c = icmp ne i32 %m, 0
532 define i32 @length12(i8* %X, i8* %Y) nounwind optsize {
533 ; X86-LABEL: length12:
536 ; X86-NEXT: pushl $12
537 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
538 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
539 ; X86-NEXT: calll memcmp
540 ; X86-NEXT: addl $16, %esp
543 ; X64-LABEL: length12:
544 ; X64: # BB#0: # %loadbb
545 ; X64-NEXT: movq (%rdi), %rcx
546 ; X64-NEXT: movq (%rsi), %rdx
547 ; X64-NEXT: bswapq %rcx
548 ; X64-NEXT: bswapq %rdx
549 ; X64-NEXT: cmpq %rdx, %rcx
550 ; X64-NEXT: jne .LBB15_1
551 ; X64-NEXT: # BB#2: # %loadbb1
552 ; X64-NEXT: movl 8(%rdi), %ecx
553 ; X64-NEXT: movl 8(%rsi), %edx
554 ; X64-NEXT: bswapl %ecx
555 ; X64-NEXT: bswapl %edx
556 ; X64-NEXT: xorl %eax, %eax
557 ; X64-NEXT: cmpq %rdx, %rcx
558 ; X64-NEXT: jne .LBB15_1
559 ; X64-NEXT: # BB#3: # %endblock
561 ; X64-NEXT: .LBB15_1: # %res_block
562 ; X64-NEXT: cmpq %rdx, %rcx
563 ; X64-NEXT: movl $-1, %ecx
564 ; X64-NEXT: movl $1, %eax
565 ; X64-NEXT: cmovbl %ecx, %eax
567 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
571 ; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
573 define i32 @length16(i8* %X, i8* %Y) nounwind optsize {
574 ; X86-LABEL: length16:
577 ; X86-NEXT: pushl $16
578 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
579 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
580 ; X86-NEXT: calll memcmp
581 ; X86-NEXT: addl $16, %esp
584 ; X64-LABEL: length16:
585 ; X64: # BB#0: # %loadbb
586 ; X64-NEXT: movq (%rdi), %rcx
587 ; X64-NEXT: movq (%rsi), %rdx
588 ; X64-NEXT: bswapq %rcx
589 ; X64-NEXT: bswapq %rdx
590 ; X64-NEXT: cmpq %rdx, %rcx
591 ; X64-NEXT: jne .LBB16_1
592 ; X64-NEXT: # BB#2: # %loadbb1
593 ; X64-NEXT: movq 8(%rdi), %rcx
594 ; X64-NEXT: movq 8(%rsi), %rdx
595 ; X64-NEXT: bswapq %rcx
596 ; X64-NEXT: bswapq %rdx
597 ; X64-NEXT: xorl %eax, %eax
598 ; X64-NEXT: cmpq %rdx, %rcx
599 ; X64-NEXT: jne .LBB16_1
600 ; X64-NEXT: # BB#3: # %endblock
602 ; X64-NEXT: .LBB16_1: # %res_block
603 ; X64-NEXT: cmpq %rdx, %rcx
604 ; X64-NEXT: movl $-1, %ecx
605 ; X64-NEXT: movl $1, %eax
606 ; X64-NEXT: cmovbl %ecx, %eax
608 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
612 define i1 @length16_eq(i8* %x, i8* %y) nounwind optsize {
613 ; X86-NOSSE-LABEL: length16_eq:
615 ; X86-NOSSE-NEXT: pushl $0
616 ; X86-NOSSE-NEXT: pushl $16
617 ; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
618 ; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
619 ; X86-NOSSE-NEXT: calll memcmp
620 ; X86-NOSSE-NEXT: addl $16, %esp
621 ; X86-NOSSE-NEXT: testl %eax, %eax
622 ; X86-NOSSE-NEXT: setne %al
623 ; X86-NOSSE-NEXT: retl
625 ; X86-SSE2-LABEL: length16_eq:
627 ; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
628 ; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
629 ; X86-SSE2-NEXT: movdqu (%ecx), %xmm0
630 ; X86-SSE2-NEXT: movdqu (%eax), %xmm1
631 ; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1
632 ; X86-SSE2-NEXT: pmovmskb %xmm1, %eax
633 ; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
634 ; X86-SSE2-NEXT: setne %al
635 ; X86-SSE2-NEXT: retl
637 ; X64-LABEL: length16_eq:
638 ; X64: # BB#0: # %loadbb
639 ; X64-NEXT: movq (%rdi), %rax
640 ; X64-NEXT: cmpq (%rsi), %rax
641 ; X64-NEXT: jne .LBB17_1
642 ; X64-NEXT: # BB#2: # %loadbb1
643 ; X64-NEXT: movq 8(%rdi), %rcx
644 ; X64-NEXT: xorl %eax, %eax
645 ; X64-NEXT: cmpq 8(%rsi), %rcx
646 ; X64-NEXT: je .LBB17_3
647 ; X64-NEXT: .LBB17_1: # %res_block
648 ; X64-NEXT: movl $1, %eax
649 ; X64-NEXT: .LBB17_3: # %endblock
650 ; X64-NEXT: testl %eax, %eax
651 ; X64-NEXT: setne %al
653 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
654 %cmp = icmp ne i32 %call, 0
658 define i1 @length16_eq_const(i8* %X) nounwind optsize {
659 ; X86-NOSSE-LABEL: length16_eq_const:
661 ; X86-NOSSE-NEXT: pushl $0
662 ; X86-NOSSE-NEXT: pushl $16
663 ; X86-NOSSE-NEXT: pushl $.L.str
664 ; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
665 ; X86-NOSSE-NEXT: calll memcmp
666 ; X86-NOSSE-NEXT: addl $16, %esp
667 ; X86-NOSSE-NEXT: testl %eax, %eax
668 ; X86-NOSSE-NEXT: sete %al
669 ; X86-NOSSE-NEXT: retl
671 ; X86-SSE2-LABEL: length16_eq_const:
673 ; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
674 ; X86-SSE2-NEXT: movdqu (%eax), %xmm0
675 ; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0
676 ; X86-SSE2-NEXT: pmovmskb %xmm0, %eax
677 ; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
678 ; X86-SSE2-NEXT: sete %al
679 ; X86-SSE2-NEXT: retl
681 ; X64-LABEL: length16_eq_const:
682 ; X64: # BB#0: # %loadbb
683 ; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
684 ; X64-NEXT: cmpq %rax, (%rdi)
685 ; X64-NEXT: jne .LBB18_1
686 ; X64-NEXT: # BB#2: # %loadbb1
687 ; X64-NEXT: xorl %eax, %eax
688 ; X64-NEXT: movabsq $3833745473465760056, %rcx # imm = 0x3534333231303938
689 ; X64-NEXT: cmpq %rcx, 8(%rdi)
690 ; X64-NEXT: je .LBB18_3
691 ; X64-NEXT: .LBB18_1: # %res_block
692 ; X64-NEXT: movl $1, %eax
693 ; X64-NEXT: .LBB18_3: # %endblock
694 ; X64-NEXT: testl %eax, %eax
697 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
698 %c = icmp eq i32 %m, 0
702 ; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
704 define i32 @length24(i8* %X, i8* %Y) nounwind optsize {
705 ; X86-LABEL: length24:
708 ; X86-NEXT: pushl $24
709 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
710 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
711 ; X86-NEXT: calll memcmp
712 ; X86-NEXT: addl $16, %esp
715 ; X64-LABEL: length24:
717 ; X64-NEXT: movl $24, %edx
718 ; X64-NEXT: jmp memcmp # TAILCALL
719 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
723 define i1 @length24_eq(i8* %x, i8* %y) nounwind optsize {
724 ; X86-LABEL: length24_eq:
727 ; X86-NEXT: pushl $24
728 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
729 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
730 ; X86-NEXT: calll memcmp
731 ; X86-NEXT: addl $16, %esp
732 ; X86-NEXT: testl %eax, %eax
736 ; X64-LABEL: length24_eq:
738 ; X64-NEXT: pushq %rax
739 ; X64-NEXT: movl $24, %edx
740 ; X64-NEXT: callq memcmp
741 ; X64-NEXT: testl %eax, %eax
743 ; X64-NEXT: popq %rcx
745 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
746 %cmp = icmp eq i32 %call, 0
750 define i1 @length24_eq_const(i8* %X) nounwind optsize {
751 ; X86-LABEL: length24_eq_const:
754 ; X86-NEXT: pushl $24
755 ; X86-NEXT: pushl $.L.str
756 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
757 ; X86-NEXT: calll memcmp
758 ; X86-NEXT: addl $16, %esp
759 ; X86-NEXT: testl %eax, %eax
760 ; X86-NEXT: setne %al
763 ; X64-LABEL: length24_eq_const:
765 ; X64-NEXT: pushq %rax
766 ; X64-NEXT: movl $.L.str, %esi
767 ; X64-NEXT: movl $24, %edx
768 ; X64-NEXT: callq memcmp
769 ; X64-NEXT: testl %eax, %eax
770 ; X64-NEXT: setne %al
771 ; X64-NEXT: popq %rcx
773 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
774 %c = icmp ne i32 %m, 0
778 define i32 @length32(i8* %X, i8* %Y) nounwind optsize {
779 ; X86-LABEL: length32:
782 ; X86-NEXT: pushl $32
783 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
784 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
785 ; X86-NEXT: calll memcmp
786 ; X86-NEXT: addl $16, %esp
789 ; X64-LABEL: length32:
791 ; X64-NEXT: movl $32, %edx
792 ; X64-NEXT: jmp memcmp # TAILCALL
793 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
797 ; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
799 define i1 @length32_eq(i8* %x, i8* %y) nounwind optsize {
800 ; X86-LABEL: length32_eq:
803 ; X86-NEXT: pushl $32
804 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
805 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
806 ; X86-NEXT: calll memcmp
807 ; X86-NEXT: addl $16, %esp
808 ; X86-NEXT: testl %eax, %eax
812 ; X64-SSE2-LABEL: length32_eq:
814 ; X64-SSE2-NEXT: pushq %rax
815 ; X64-SSE2-NEXT: movl $32, %edx
816 ; X64-SSE2-NEXT: callq memcmp
817 ; X64-SSE2-NEXT: testl %eax, %eax
818 ; X64-SSE2-NEXT: sete %al
819 ; X64-SSE2-NEXT: popq %rcx
820 ; X64-SSE2-NEXT: retq
822 ; X64-AVX2-LABEL: length32_eq:
824 ; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
825 ; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0
826 ; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
827 ; X64-AVX2-NEXT: cmpl $-1, %eax
828 ; X64-AVX2-NEXT: sete %al
829 ; X64-AVX2-NEXT: vzeroupper
830 ; X64-AVX2-NEXT: retq
831 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
832 %cmp = icmp eq i32 %call, 0
836 define i1 @length32_eq_const(i8* %X) nounwind optsize {
837 ; X86-LABEL: length32_eq_const:
840 ; X86-NEXT: pushl $32
841 ; X86-NEXT: pushl $.L.str
842 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
843 ; X86-NEXT: calll memcmp
844 ; X86-NEXT: addl $16, %esp
845 ; X86-NEXT: testl %eax, %eax
846 ; X86-NEXT: setne %al
849 ; X64-SSE2-LABEL: length32_eq_const:
851 ; X64-SSE2-NEXT: pushq %rax
852 ; X64-SSE2-NEXT: movl $.L.str, %esi
853 ; X64-SSE2-NEXT: movl $32, %edx
854 ; X64-SSE2-NEXT: callq memcmp
855 ; X64-SSE2-NEXT: testl %eax, %eax
856 ; X64-SSE2-NEXT: setne %al
857 ; X64-SSE2-NEXT: popq %rcx
858 ; X64-SSE2-NEXT: retq
860 ; X64-AVX2-LABEL: length32_eq_const:
862 ; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
863 ; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
864 ; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
865 ; X64-AVX2-NEXT: cmpl $-1, %eax
866 ; X64-AVX2-NEXT: setne %al
867 ; X64-AVX2-NEXT: vzeroupper
868 ; X64-AVX2-NEXT: retq
869 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
870 %c = icmp ne i32 %m, 0
874 define i32 @length64(i8* %X, i8* %Y) nounwind optsize {
875 ; X86-LABEL: length64:
878 ; X86-NEXT: pushl $64
879 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
880 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
881 ; X86-NEXT: calll memcmp
882 ; X86-NEXT: addl $16, %esp
885 ; X64-LABEL: length64:
887 ; X64-NEXT: movl $64, %edx
888 ; X64-NEXT: jmp memcmp # TAILCALL
889 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
893 define i1 @length64_eq(i8* %x, i8* %y) nounwind optsize {
894 ; X86-LABEL: length64_eq:
897 ; X86-NEXT: pushl $64
898 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
899 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
900 ; X86-NEXT: calll memcmp
901 ; X86-NEXT: addl $16, %esp
902 ; X86-NEXT: testl %eax, %eax
903 ; X86-NEXT: setne %al
906 ; X64-LABEL: length64_eq:
908 ; X64-NEXT: pushq %rax
909 ; X64-NEXT: movl $64, %edx
910 ; X64-NEXT: callq memcmp
911 ; X64-NEXT: testl %eax, %eax
912 ; X64-NEXT: setne %al
913 ; X64-NEXT: popq %rcx
915 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
916 %cmp = icmp ne i32 %call, 0
920 define i1 @length64_eq_const(i8* %X) nounwind optsize {
921 ; X86-LABEL: length64_eq_const:
924 ; X86-NEXT: pushl $64
925 ; X86-NEXT: pushl $.L.str
926 ; X86-NEXT: pushl {{[0-9]+}}(%esp)
927 ; X86-NEXT: calll memcmp
928 ; X86-NEXT: addl $16, %esp
929 ; X86-NEXT: testl %eax, %eax
933 ; X64-LABEL: length64_eq_const:
935 ; X64-NEXT: pushq %rax
936 ; X64-NEXT: movl $.L.str, %esi
937 ; X64-NEXT: movl $64, %edx
938 ; X64-NEXT: callq memcmp
939 ; X64-NEXT: testl %eax, %eax
941 ; X64-NEXT: popq %rcx
943 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
944 %c = icmp eq i32 %m, 0