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 minsize {
15; X86-LABEL: length2:
16; X86:       # BB#0:
17; X86-NEXT:    pushl $0
18; X86-NEXT:    pushl $2
19; X86-NEXT:    pushl {{[0-9]+}}(%esp)
20; X86-NEXT:    pushl {{[0-9]+}}(%esp)
21; X86-NEXT:    calll memcmp
22; X86-NEXT:    addl $16, %esp
23; X86-NEXT:    retl
24;
25; X64-LABEL: length2:
26; X64:       # BB#0:
27; X64-NEXT:    pushq $2
28; X64-NEXT:    popq %rdx
29; X64-NEXT:    jmp memcmp # TAILCALL
30  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
31  ret i32 %m
32}
33
34define i1 @length2_eq(i8* %X, i8* %Y) nounwind minsize {
35; X86-LABEL: length2_eq:
36; X86:       # BB#0:
37; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
38; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
39; X86-NEXT:    movzwl (%ecx), %ecx
40; X86-NEXT:    cmpw (%eax), %cx
41; X86-NEXT:    sete %al
42; X86-NEXT:    retl
43;
44; X64-LABEL: length2_eq:
45; X64:       # BB#0:
46; X64-NEXT:    movzwl (%rdi), %eax
47; X64-NEXT:    cmpw (%rsi), %ax
48; X64-NEXT:    sete %al
49; X64-NEXT:    retq
50  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
51  %c = icmp eq i32 %m, 0
52  ret i1 %c
53}
54
55define i1 @length2_eq_const(i8* %X) nounwind minsize {
56; X86-LABEL: length2_eq_const:
57; X86:       # BB#0:
58; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
59; X86-NEXT:    cmpw $12849, (%eax) # imm = 0x3231
60; X86-NEXT:    setne %al
61; X86-NEXT:    retl
62;
63; X64-LABEL: length2_eq_const:
64; X64:       # BB#0:
65; X64-NEXT:    cmpw $12849, (%rdi) # imm = 0x3231
66; X64-NEXT:    setne %al
67; X64-NEXT:    retq
68  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind
69  %c = icmp ne i32 %m, 0
70  ret i1 %c
71}
72
73define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind minsize {
74; X86-LABEL: length2_eq_nobuiltin_attr:
75; X86:       # BB#0:
76; X86-NEXT:    pushl $0
77; X86-NEXT:    pushl $2
78; X86-NEXT:    pushl {{[0-9]+}}(%esp)
79; X86-NEXT:    pushl {{[0-9]+}}(%esp)
80; X86-NEXT:    calll memcmp
81; X86-NEXT:    addl $16, %esp
82; X86-NEXT:    testl %eax, %eax
83; X86-NEXT:    sete %al
84; X86-NEXT:    retl
85;
86; X64-LABEL: length2_eq_nobuiltin_attr:
87; X64:       # BB#0:
88; X64-NEXT:    pushq %rax
89; X64-NEXT:    pushq $2
90; X64-NEXT:    popq %rdx
91; X64-NEXT:    callq memcmp
92; X64-NEXT:    testl %eax, %eax
93; X64-NEXT:    sete %al
94; X64-NEXT:    popq %rcx
95; X64-NEXT:    retq
96  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin
97  %c = icmp eq i32 %m, 0
98  ret i1 %c
99}
100
101define i32 @length3(i8* %X, i8* %Y) nounwind minsize {
102; X86-LABEL: length3:
103; X86:       # BB#0:
104; X86-NEXT:    pushl $0
105; X86-NEXT:    pushl $3
106; X86-NEXT:    pushl {{[0-9]+}}(%esp)
107; X86-NEXT:    pushl {{[0-9]+}}(%esp)
108; X86-NEXT:    calll memcmp
109; X86-NEXT:    addl $16, %esp
110; X86-NEXT:    retl
111;
112; X64-LABEL: length3:
113; X64:       # BB#0:
114; X64-NEXT:    pushq $3
115; X64-NEXT:    popq %rdx
116; X64-NEXT:    jmp memcmp # TAILCALL
117  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
118  ret i32 %m
119}
120
121define i1 @length3_eq(i8* %X, i8* %Y) nounwind minsize {
122; X86-LABEL: length3_eq:
123; X86:       # BB#0:
124; X86-NEXT:    pushl $0
125; X86-NEXT:    pushl $3
126; X86-NEXT:    pushl {{[0-9]+}}(%esp)
127; X86-NEXT:    pushl {{[0-9]+}}(%esp)
128; X86-NEXT:    calll memcmp
129; X86-NEXT:    addl $16, %esp
130; X86-NEXT:    testl %eax, %eax
131; X86-NEXT:    setne %al
132; X86-NEXT:    retl
133;
134; X64-LABEL: length3_eq:
135; X64:       # BB#0:
136; X64-NEXT:    pushq %rax
137; X64-NEXT:    pushq $3
138; X64-NEXT:    popq %rdx
139; X64-NEXT:    callq memcmp
140; X64-NEXT:    testl %eax, %eax
141; X64-NEXT:    setne %al
142; X64-NEXT:    popq %rcx
143; X64-NEXT:    retq
144  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
145  %c = icmp ne i32 %m, 0
146  ret i1 %c
147}
148
149define i32 @length4(i8* %X, i8* %Y) nounwind minsize {
150; X86-LABEL: length4:
151; X86:       # BB#0:
152; X86-NEXT:    pushl $0
153; X86-NEXT:    pushl $4
154; X86-NEXT:    pushl {{[0-9]+}}(%esp)
155; X86-NEXT:    pushl {{[0-9]+}}(%esp)
156; X86-NEXT:    calll memcmp
157; X86-NEXT:    addl $16, %esp
158; X86-NEXT:    retl
159;
160; X64-LABEL: length4:
161; X64:       # BB#0:
162; X64-NEXT:    pushq $4
163; X64-NEXT:    popq %rdx
164; X64-NEXT:    jmp memcmp # TAILCALL
165  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
166  ret i32 %m
167}
168
169define i1 @length4_eq(i8* %X, i8* %Y) nounwind minsize {
170; X86-LABEL: length4_eq:
171; X86:       # BB#0:
172; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
173; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
174; X86-NEXT:    movl (%ecx), %ecx
175; X86-NEXT:    cmpl (%eax), %ecx
176; X86-NEXT:    setne %al
177; X86-NEXT:    retl
178;
179; X64-LABEL: length4_eq:
180; X64:       # BB#0:
181; X64-NEXT:    movl (%rdi), %eax
182; X64-NEXT:    cmpl (%rsi), %eax
183; X64-NEXT:    setne %al
184; X64-NEXT:    retq
185  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
186  %c = icmp ne i32 %m, 0
187  ret i1 %c
188}
189
190define i1 @length4_eq_const(i8* %X) nounwind minsize {
191; X86-LABEL: length4_eq_const:
192; X86:       # BB#0:
193; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
194; X86-NEXT:    cmpl $875770417, (%eax) # imm = 0x34333231
195; X86-NEXT:    sete %al
196; X86-NEXT:    retl
197;
198; X64-LABEL: length4_eq_const:
199; X64:       # BB#0:
200; X64-NEXT:    cmpl $875770417, (%rdi) # imm = 0x34333231
201; X64-NEXT:    sete %al
202; X64-NEXT:    retq
203  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
204  %c = icmp eq i32 %m, 0
205  ret i1 %c
206}
207
208define i32 @length5(i8* %X, i8* %Y) nounwind minsize {
209; X86-LABEL: length5:
210; X86:       # BB#0:
211; X86-NEXT:    pushl $0
212; X86-NEXT:    pushl $5
213; X86-NEXT:    pushl {{[0-9]+}}(%esp)
214; X86-NEXT:    pushl {{[0-9]+}}(%esp)
215; X86-NEXT:    calll memcmp
216; X86-NEXT:    addl $16, %esp
217; X86-NEXT:    retl
218;
219; X64-LABEL: length5:
220; X64:       # BB#0:
221; X64-NEXT:    pushq $5
222; X64-NEXT:    popq %rdx
223; X64-NEXT:    jmp memcmp # TAILCALL
224  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
225  ret i32 %m
226}
227
228define i1 @length5_eq(i8* %X, i8* %Y) nounwind minsize {
229; X86-LABEL: length5_eq:
230; X86:       # BB#0:
231; X86-NEXT:    pushl $0
232; X86-NEXT:    pushl $5
233; X86-NEXT:    pushl {{[0-9]+}}(%esp)
234; X86-NEXT:    pushl {{[0-9]+}}(%esp)
235; X86-NEXT:    calll memcmp
236; X86-NEXT:    addl $16, %esp
237; X86-NEXT:    testl %eax, %eax
238; X86-NEXT:    setne %al
239; X86-NEXT:    retl
240;
241; X64-LABEL: length5_eq:
242; X64:       # BB#0:
243; X64-NEXT:    pushq %rax
244; X64-NEXT:    pushq $5
245; X64-NEXT:    popq %rdx
246; X64-NEXT:    callq memcmp
247; X64-NEXT:    testl %eax, %eax
248; X64-NEXT:    setne %al
249; X64-NEXT:    popq %rcx
250; X64-NEXT:    retq
251  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
252  %c = icmp ne i32 %m, 0
253  ret i1 %c
254}
255
256define i32 @length8(i8* %X, i8* %Y) nounwind minsize {
257; X86-LABEL: length8:
258; X86:       # BB#0:
259; X86-NEXT:    pushl $0
260; X86-NEXT:    pushl $8
261; X86-NEXT:    pushl {{[0-9]+}}(%esp)
262; X86-NEXT:    pushl {{[0-9]+}}(%esp)
263; X86-NEXT:    calll memcmp
264; X86-NEXT:    addl $16, %esp
265; X86-NEXT:    retl
266;
267; X64-LABEL: length8:
268; X64:       # BB#0:
269; X64-NEXT:    pushq $8
270; X64-NEXT:    popq %rdx
271; X64-NEXT:    jmp memcmp # TAILCALL
272  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
273  ret i32 %m
274}
275
276define i1 @length8_eq(i8* %X, i8* %Y) nounwind minsize {
277; X86-LABEL: length8_eq:
278; X86:       # BB#0:
279; X86-NEXT:    pushl $0
280; X86-NEXT:    pushl $8
281; X86-NEXT:    pushl {{[0-9]+}}(%esp)
282; X86-NEXT:    pushl {{[0-9]+}}(%esp)
283; X86-NEXT:    calll memcmp
284; X86-NEXT:    addl $16, %esp
285; X86-NEXT:    testl %eax, %eax
286; X86-NEXT:    sete %al
287; X86-NEXT:    retl
288;
289; X64-LABEL: length8_eq:
290; X64:       # BB#0:
291; X64-NEXT:    movq (%rdi), %rax
292; X64-NEXT:    cmpq (%rsi), %rax
293; X64-NEXT:    sete %al
294; X64-NEXT:    retq
295  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
296  %c = icmp eq i32 %m, 0
297  ret i1 %c
298}
299
300define i1 @length8_eq_const(i8* %X) nounwind minsize {
301; X86-LABEL: length8_eq_const:
302; X86:       # BB#0:
303; X86-NEXT:    pushl $0
304; X86-NEXT:    pushl $8
305; X86-NEXT:    pushl $.L.str
306; X86-NEXT:    pushl {{[0-9]+}}(%esp)
307; X86-NEXT:    calll memcmp
308; X86-NEXT:    addl $16, %esp
309; X86-NEXT:    testl %eax, %eax
310; X86-NEXT:    setne %al
311; X86-NEXT:    retl
312;
313; X64-LABEL: length8_eq_const:
314; X64:       # BB#0:
315; X64-NEXT:    movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
316; X64-NEXT:    cmpq %rax, (%rdi)
317; X64-NEXT:    setne %al
318; X64-NEXT:    retq
319  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
320  %c = icmp ne i32 %m, 0
321  ret i1 %c
322}
323
324define i1 @length12_eq(i8* %X, i8* %Y) nounwind minsize {
325; X86-LABEL: length12_eq:
326; X86:       # BB#0:
327; X86-NEXT:    pushl $0
328; X86-NEXT:    pushl $12
329; X86-NEXT:    pushl {{[0-9]+}}(%esp)
330; X86-NEXT:    pushl {{[0-9]+}}(%esp)
331; X86-NEXT:    calll memcmp
332; X86-NEXT:    addl $16, %esp
333; X86-NEXT:    testl %eax, %eax
334; X86-NEXT:    setne %al
335; X86-NEXT:    retl
336;
337; X64-LABEL: length12_eq:
338; X64:       # BB#0:
339; X64-NEXT:    pushq %rax
340; X64-NEXT:    pushq $12
341; X64-NEXT:    popq %rdx
342; X64-NEXT:    callq memcmp
343; X64-NEXT:    testl %eax, %eax
344; X64-NEXT:    setne %al
345; X64-NEXT:    popq %rcx
346; X64-NEXT:    retq
347  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
348  %c = icmp ne i32 %m, 0
349  ret i1 %c
350}
351
352define i32 @length12(i8* %X, i8* %Y) nounwind minsize {
353; X86-LABEL: length12:
354; X86:       # BB#0:
355; X86-NEXT:    pushl $0
356; X86-NEXT:    pushl $12
357; X86-NEXT:    pushl {{[0-9]+}}(%esp)
358; X86-NEXT:    pushl {{[0-9]+}}(%esp)
359; X86-NEXT:    calll memcmp
360; X86-NEXT:    addl $16, %esp
361; X86-NEXT:    retl
362;
363; X64-LABEL: length12:
364; X64:       # BB#0:
365; X64-NEXT:    pushq $12
366; X64-NEXT:    popq %rdx
367; X64-NEXT:    jmp memcmp # TAILCALL
368  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
369  ret i32 %m
370}
371
372; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
373
374define i32 @length16(i8* %X, i8* %Y) nounwind minsize {
375; X86-LABEL: length16:
376; X86:       # BB#0:
377; X86-NEXT:    pushl $0
378; X86-NEXT:    pushl $16
379; X86-NEXT:    pushl {{[0-9]+}}(%esp)
380; X86-NEXT:    pushl {{[0-9]+}}(%esp)
381; X86-NEXT:    calll memcmp
382; X86-NEXT:    addl $16, %esp
383; X86-NEXT:    retl
384;
385; X64-LABEL: length16:
386; X64:       # BB#0:
387; X64-NEXT:    pushq $16
388; X64-NEXT:    popq %rdx
389; X64-NEXT:    jmp memcmp # TAILCALL
390  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
391  ret i32 %m
392}
393
394define i1 @length16_eq(i8* %x, i8* %y) nounwind minsize {
395; X86-NOSSE-LABEL: length16_eq:
396; X86-NOSSE:       # BB#0:
397; X86-NOSSE-NEXT:    pushl $0
398; X86-NOSSE-NEXT:    pushl $16
399; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
400; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
401; X86-NOSSE-NEXT:    calll memcmp
402; X86-NOSSE-NEXT:    addl $16, %esp
403; X86-NOSSE-NEXT:    testl %eax, %eax
404; X86-NOSSE-NEXT:    setne %al
405; X86-NOSSE-NEXT:    retl
406;
407; X86-SSE2-LABEL: length16_eq:
408; X86-SSE2:       # BB#0:
409; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
410; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
411; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
412; X86-SSE2-NEXT:    movdqu (%eax), %xmm1
413; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
414; X86-SSE2-NEXT:    pmovmskb %xmm1, %eax
415; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
416; X86-SSE2-NEXT:    setne %al
417; X86-SSE2-NEXT:    retl
418;
419; X64-SSE2-LABEL: length16_eq:
420; X64-SSE2:       # BB#0:
421; X64-SSE2-NEXT:    movdqu (%rsi), %xmm0
422; X64-SSE2-NEXT:    movdqu (%rdi), %xmm1
423; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
424; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
425; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
426; X64-SSE2-NEXT:    setne %al
427; X64-SSE2-NEXT:    retq
428;
429; X64-AVX2-LABEL: length16_eq:
430; X64-AVX2:       # BB#0:
431; X64-AVX2-NEXT:    vmovdqu (%rdi), %xmm0
432; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
433; X64-AVX2-NEXT:    vpmovmskb %xmm0, %eax
434; X64-AVX2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
435; X64-AVX2-NEXT:    setne %al
436; X64-AVX2-NEXT:    retq
437  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
438  %cmp = icmp ne i32 %call, 0
439  ret i1 %cmp
440}
441
442define i1 @length16_eq_const(i8* %X) nounwind minsize {
443; X86-NOSSE-LABEL: length16_eq_const:
444; X86-NOSSE:       # BB#0:
445; X86-NOSSE-NEXT:    pushl $0
446; X86-NOSSE-NEXT:    pushl $16
447; X86-NOSSE-NEXT:    pushl $.L.str
448; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
449; X86-NOSSE-NEXT:    calll memcmp
450; X86-NOSSE-NEXT:    addl $16, %esp
451; X86-NOSSE-NEXT:    testl %eax, %eax
452; X86-NOSSE-NEXT:    sete %al
453; X86-NOSSE-NEXT:    retl
454;
455; X86-SSE2-LABEL: length16_eq_const:
456; X86-SSE2:       # BB#0:
457; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
458; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
459; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
460; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
461; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
462; X86-SSE2-NEXT:    sete %al
463; X86-SSE2-NEXT:    retl
464;
465; X64-SSE2-LABEL: length16_eq_const:
466; X64-SSE2:       # BB#0:
467; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
468; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
469; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
470; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
471; X64-SSE2-NEXT:    sete %al
472; X64-SSE2-NEXT:    retq
473;
474; X64-AVX2-LABEL: length16_eq_const:
475; X64-AVX2:       # BB#0:
476; X64-AVX2-NEXT:    vmovdqu (%rdi), %xmm0
477; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
478; X64-AVX2-NEXT:    vpmovmskb %xmm0, %eax
479; X64-AVX2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
480; X64-AVX2-NEXT:    sete %al
481; X64-AVX2-NEXT:    retq
482  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
483  %c = icmp eq i32 %m, 0
484  ret i1 %c
485}
486
487; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
488
489define i32 @length24(i8* %X, i8* %Y) nounwind minsize {
490; X86-LABEL: length24:
491; X86:       # BB#0:
492; X86-NEXT:    pushl $0
493; X86-NEXT:    pushl $24
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: length24:
501; X64:       # BB#0:
502; X64-NEXT:    pushq $24
503; X64-NEXT:    popq %rdx
504; X64-NEXT:    jmp memcmp # TAILCALL
505  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
506  ret i32 %m
507}
508
509define i1 @length24_eq(i8* %x, i8* %y) nounwind minsize {
510; X86-LABEL: length24_eq:
511; X86:       # BB#0:
512; X86-NEXT:    pushl $0
513; X86-NEXT:    pushl $24
514; X86-NEXT:    pushl {{[0-9]+}}(%esp)
515; X86-NEXT:    pushl {{[0-9]+}}(%esp)
516; X86-NEXT:    calll memcmp
517; X86-NEXT:    addl $16, %esp
518; X86-NEXT:    testl %eax, %eax
519; X86-NEXT:    sete %al
520; X86-NEXT:    retl
521;
522; X64-LABEL: length24_eq:
523; X64:       # BB#0:
524; X64-NEXT:    pushq %rax
525; X64-NEXT:    pushq $24
526; X64-NEXT:    popq %rdx
527; X64-NEXT:    callq memcmp
528; X64-NEXT:    testl %eax, %eax
529; X64-NEXT:    sete %al
530; X64-NEXT:    popq %rcx
531; X64-NEXT:    retq
532  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
533  %cmp = icmp eq i32 %call, 0
534  ret i1 %cmp
535}
536
537define i1 @length24_eq_const(i8* %X) nounwind minsize {
538; X86-LABEL: length24_eq_const:
539; X86:       # BB#0:
540; X86-NEXT:    pushl $0
541; X86-NEXT:    pushl $24
542; X86-NEXT:    pushl $.L.str
543; X86-NEXT:    pushl {{[0-9]+}}(%esp)
544; X86-NEXT:    calll memcmp
545; X86-NEXT:    addl $16, %esp
546; X86-NEXT:    testl %eax, %eax
547; X86-NEXT:    setne %al
548; X86-NEXT:    retl
549;
550; X64-LABEL: length24_eq_const:
551; X64:       # BB#0:
552; X64-NEXT:    pushq %rax
553; X64-NEXT:    pushq $24
554; X64-NEXT:    popq %rdx
555; X64-NEXT:    movl $.L.str, %esi
556; X64-NEXT:    callq memcmp
557; X64-NEXT:    testl %eax, %eax
558; X64-NEXT:    setne %al
559; X64-NEXT:    popq %rcx
560; X64-NEXT:    retq
561  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
562  %c = icmp ne i32 %m, 0
563  ret i1 %c
564}
565
566define i32 @length32(i8* %X, i8* %Y) nounwind minsize {
567; X86-LABEL: length32:
568; X86:       # BB#0:
569; X86-NEXT:    pushl $0
570; X86-NEXT:    pushl $32
571; X86-NEXT:    pushl {{[0-9]+}}(%esp)
572; X86-NEXT:    pushl {{[0-9]+}}(%esp)
573; X86-NEXT:    calll memcmp
574; X86-NEXT:    addl $16, %esp
575; X86-NEXT:    retl
576;
577; X64-LABEL: length32:
578; X64:       # BB#0:
579; X64-NEXT:    pushq $32
580; X64-NEXT:    popq %rdx
581; X64-NEXT:    jmp memcmp # TAILCALL
582  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
583  ret i32 %m
584}
585
586; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
587
588define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize {
589; X86-LABEL: length32_eq:
590; X86:       # BB#0:
591; X86-NEXT:    pushl $0
592; X86-NEXT:    pushl $32
593; X86-NEXT:    pushl {{[0-9]+}}(%esp)
594; X86-NEXT:    pushl {{[0-9]+}}(%esp)
595; X86-NEXT:    calll memcmp
596; X86-NEXT:    addl $16, %esp
597; X86-NEXT:    testl %eax, %eax
598; X86-NEXT:    sete %al
599; X86-NEXT:    retl
600;
601; X64-SSE2-LABEL: length32_eq:
602; X64-SSE2:       # BB#0:
603; X64-SSE2-NEXT:    pushq %rax
604; X64-SSE2-NEXT:    pushq $32
605; X64-SSE2-NEXT:    popq %rdx
606; X64-SSE2-NEXT:    callq memcmp
607; X64-SSE2-NEXT:    testl %eax, %eax
608; X64-SSE2-NEXT:    sete %al
609; X64-SSE2-NEXT:    popq %rcx
610; X64-SSE2-NEXT:    retq
611;
612; X64-AVX2-LABEL: length32_eq:
613; X64-AVX2:       # BB#0:
614; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
615; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
616; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
617; X64-AVX2-NEXT:    cmpl $-1, %eax
618; X64-AVX2-NEXT:    sete %al
619; X64-AVX2-NEXT:    vzeroupper
620; X64-AVX2-NEXT:    retq
621  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
622  %cmp = icmp eq i32 %call, 0
623  ret i1 %cmp
624}
625
626define i1 @length32_eq_const(i8* %X) nounwind minsize {
627; X86-LABEL: length32_eq_const:
628; X86:       # BB#0:
629; X86-NEXT:    pushl $0
630; X86-NEXT:    pushl $32
631; X86-NEXT:    pushl $.L.str
632; X86-NEXT:    pushl {{[0-9]+}}(%esp)
633; X86-NEXT:    calll memcmp
634; X86-NEXT:    addl $16, %esp
635; X86-NEXT:    testl %eax, %eax
636; X86-NEXT:    setne %al
637; X86-NEXT:    retl
638;
639; X64-SSE2-LABEL: length32_eq_const:
640; X64-SSE2:       # BB#0:
641; X64-SSE2-NEXT:    pushq %rax
642; X64-SSE2-NEXT:    pushq $32
643; X64-SSE2-NEXT:    popq %rdx
644; X64-SSE2-NEXT:    movl $.L.str, %esi
645; X64-SSE2-NEXT:    callq memcmp
646; X64-SSE2-NEXT:    testl %eax, %eax
647; X64-SSE2-NEXT:    setne %al
648; X64-SSE2-NEXT:    popq %rcx
649; X64-SSE2-NEXT:    retq
650;
651; X64-AVX2-LABEL: length32_eq_const:
652; X64-AVX2:       # BB#0:
653; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
654; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
655; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
656; X64-AVX2-NEXT:    cmpl $-1, %eax
657; X64-AVX2-NEXT:    setne %al
658; X64-AVX2-NEXT:    vzeroupper
659; X64-AVX2-NEXT:    retq
660  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
661  %c = icmp ne i32 %m, 0
662  ret i1 %c
663}
664
665define i32 @length64(i8* %X, i8* %Y) nounwind minsize {
666; X86-LABEL: length64:
667; X86:       # BB#0:
668; X86-NEXT:    pushl $0
669; X86-NEXT:    pushl $64
670; X86-NEXT:    pushl {{[0-9]+}}(%esp)
671; X86-NEXT:    pushl {{[0-9]+}}(%esp)
672; X86-NEXT:    calll memcmp
673; X86-NEXT:    addl $16, %esp
674; X86-NEXT:    retl
675;
676; X64-LABEL: length64:
677; X64:       # BB#0:
678; X64-NEXT:    pushq $64
679; X64-NEXT:    popq %rdx
680; X64-NEXT:    jmp memcmp # TAILCALL
681  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
682  ret i32 %m
683}
684
685define i1 @length64_eq(i8* %x, i8* %y) nounwind minsize {
686; X86-LABEL: length64_eq:
687; X86:       # BB#0:
688; X86-NEXT:    pushl $0
689; X86-NEXT:    pushl $64
690; X86-NEXT:    pushl {{[0-9]+}}(%esp)
691; X86-NEXT:    pushl {{[0-9]+}}(%esp)
692; X86-NEXT:    calll memcmp
693; X86-NEXT:    addl $16, %esp
694; X86-NEXT:    testl %eax, %eax
695; X86-NEXT:    setne %al
696; X86-NEXT:    retl
697;
698; X64-LABEL: length64_eq:
699; X64:       # BB#0:
700; X64-NEXT:    pushq %rax
701; X64-NEXT:    pushq $64
702; X64-NEXT:    popq %rdx
703; X64-NEXT:    callq memcmp
704; X64-NEXT:    testl %eax, %eax
705; X64-NEXT:    setne %al
706; X64-NEXT:    popq %rcx
707; X64-NEXT:    retq
708  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
709  %cmp = icmp ne i32 %call, 0
710  ret i1 %cmp
711}
712
713define i1 @length64_eq_const(i8* %X) nounwind minsize {
714; X86-LABEL: length64_eq_const:
715; X86:       # BB#0:
716; X86-NEXT:    pushl $0
717; X86-NEXT:    pushl $64
718; X86-NEXT:    pushl $.L.str
719; X86-NEXT:    pushl {{[0-9]+}}(%esp)
720; X86-NEXT:    calll memcmp
721; X86-NEXT:    addl $16, %esp
722; X86-NEXT:    testl %eax, %eax
723; X86-NEXT:    sete %al
724; X86-NEXT:    retl
725;
726; X64-LABEL: length64_eq_const:
727; X64:       # BB#0:
728; X64-NEXT:    pushq %rax
729; X64-NEXT:    pushq $64
730; X64-NEXT:    popq %rdx
731; X64-NEXT:    movl $.L.str, %esi
732; X64-NEXT:    callq memcmp
733; X64-NEXT:    testl %eax, %eax
734; X64-NEXT:    sete %al
735; X64-NEXT:    popq %rcx
736; X64-NEXT:    retq
737  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
738  %c = icmp eq i32 %m, 0
739  ret i1 %c
740}
741
742