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