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