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=+sse   | FileCheck %s --check-prefix=X86 --check-prefix=SSE --check-prefix=X86-SSE1
4; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2  | FileCheck %s --check-prefix=X86 --check-prefix=SSE --check-prefix=X86-SSE2
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown             | FileCheck %s --check-prefix=X64 --check-prefix=X64-SSE2
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx  | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX1
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx2 | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX --check-prefix=X64-AVX2
8
9; This tests codegen time inlining/optimization of memcmp
10; rdar://6480398
11
12@.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1
13
14declare i32 @memcmp(i8*, i8*, i64)
15
16define i32 @length0(i8* %X, i8* %Y) nounwind {
17; X86-LABEL: length0:
18; X86:       # %bb.0:
19; X86-NEXT:    xorl %eax, %eax
20; X86-NEXT:    retl
21;
22; X64-LABEL: length0:
23; X64:       # %bb.0:
24; X64-NEXT:    xorl %eax, %eax
25; X64-NEXT:    retq
26   %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 0) nounwind
27   ret i32 %m
28 }
29
30define i1 @length0_eq(i8* %X, i8* %Y) nounwind {
31; X86-LABEL: length0_eq:
32; X86:       # %bb.0:
33; X86-NEXT:    movb $1, %al
34; X86-NEXT:    retl
35;
36; X64-LABEL: length0_eq:
37; X64:       # %bb.0:
38; X64-NEXT:    movb $1, %al
39; X64-NEXT:    retq
40  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 0) nounwind
41  %c = icmp eq i32 %m, 0
42  ret i1 %c
43}
44
45define i32 @length2(i8* %X, i8* %Y) nounwind {
46; X86-LABEL: length2:
47; X86:       # %bb.0:
48; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
49; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
50; X86-NEXT:    movzwl (%ecx), %ecx
51; X86-NEXT:    movzwl (%eax), %edx
52; X86-NEXT:    rolw $8, %cx
53; X86-NEXT:    rolw $8, %dx
54; X86-NEXT:    movzwl %cx, %eax
55; X86-NEXT:    movzwl %dx, %ecx
56; X86-NEXT:    subl %ecx, %eax
57; X86-NEXT:    retl
58;
59; X64-LABEL: length2:
60; X64:       # %bb.0:
61; X64-NEXT:    movzwl (%rdi), %eax
62; X64-NEXT:    movzwl (%rsi), %ecx
63; X64-NEXT:    rolw $8, %ax
64; X64-NEXT:    rolw $8, %cx
65; X64-NEXT:    movzwl %ax, %eax
66; X64-NEXT:    movzwl %cx, %ecx
67; X64-NEXT:    subl %ecx, %eax
68; X64-NEXT:    retq
69  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
70  ret i32 %m
71}
72
73define i1 @length2_eq(i8* %X, i8* %Y) nounwind {
74; X86-LABEL: length2_eq:
75; X86:       # %bb.0:
76; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
77; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
78; X86-NEXT:    movzwl (%ecx), %ecx
79; X86-NEXT:    cmpw (%eax), %cx
80; X86-NEXT:    sete %al
81; X86-NEXT:    retl
82;
83; X64-LABEL: length2_eq:
84; X64:       # %bb.0:
85; X64-NEXT:    movzwl (%rdi), %eax
86; X64-NEXT:    cmpw (%rsi), %ax
87; X64-NEXT:    sete %al
88; X64-NEXT:    retq
89  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
90  %c = icmp eq i32 %m, 0
91  ret i1 %c
92}
93
94define i1 @length2_eq_const(i8* %X) nounwind {
95; X86-LABEL: length2_eq_const:
96; X86:       # %bb.0:
97; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
98; X86-NEXT:    movzwl (%eax), %eax
99; X86-NEXT:    cmpl $12849, %eax # imm = 0x3231
100; X86-NEXT:    setne %al
101; X86-NEXT:    retl
102;
103; X64-LABEL: length2_eq_const:
104; X64:       # %bb.0:
105; X64-NEXT:    movzwl (%rdi), %eax
106; X64-NEXT:    cmpl $12849, %eax # imm = 0x3231
107; X64-NEXT:    setne %al
108; X64-NEXT:    retq
109  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind
110  %c = icmp ne i32 %m, 0
111  ret i1 %c
112}
113
114define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind {
115; X86-LABEL: length2_eq_nobuiltin_attr:
116; X86:       # %bb.0:
117; X86-NEXT:    pushl $0
118; X86-NEXT:    pushl $2
119; X86-NEXT:    pushl {{[0-9]+}}(%esp)
120; X86-NEXT:    pushl {{[0-9]+}}(%esp)
121; X86-NEXT:    calll memcmp
122; X86-NEXT:    addl $16, %esp
123; X86-NEXT:    testl %eax, %eax
124; X86-NEXT:    sete %al
125; X86-NEXT:    retl
126;
127; X64-LABEL: length2_eq_nobuiltin_attr:
128; X64:       # %bb.0:
129; X64-NEXT:    pushq %rax
130; X64-NEXT:    movl $2, %edx
131; X64-NEXT:    callq memcmp
132; X64-NEXT:    testl %eax, %eax
133; X64-NEXT:    sete %al
134; X64-NEXT:    popq %rcx
135; X64-NEXT:    retq
136  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin
137  %c = icmp eq i32 %m, 0
138  ret i1 %c
139}
140
141define i32 @length3(i8* %X, i8* %Y) nounwind {
142; X86-LABEL: length3:
143; X86:       # %bb.0: # %loadbb
144; X86-NEXT:    pushl %esi
145; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
146; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
147; X86-NEXT:    movzwl (%eax), %edx
148; X86-NEXT:    movzwl (%ecx), %esi
149; X86-NEXT:    rolw $8, %dx
150; X86-NEXT:    rolw $8, %si
151; X86-NEXT:    cmpw %si, %dx
152; X86-NEXT:    jne .LBB6_1
153; X86-NEXT:  # %bb.2: # %loadbb1
154; X86-NEXT:    movzbl 2(%eax), %eax
155; X86-NEXT:    movzbl 2(%ecx), %ecx
156; X86-NEXT:    subl %ecx, %eax
157; X86-NEXT:    popl %esi
158; X86-NEXT:    retl
159; X86-NEXT:  .LBB6_1: # %res_block
160; X86-NEXT:    setae %al
161; X86-NEXT:    movzbl %al, %eax
162; X86-NEXT:    leal -1(%eax,%eax), %eax
163; X86-NEXT:    popl %esi
164; X86-NEXT:    retl
165;
166; X64-LABEL: length3:
167; X64:       # %bb.0: # %loadbb
168; X64-NEXT:    movzwl (%rdi), %eax
169; X64-NEXT:    movzwl (%rsi), %ecx
170; X64-NEXT:    rolw $8, %ax
171; X64-NEXT:    rolw $8, %cx
172; X64-NEXT:    cmpw %cx, %ax
173; X64-NEXT:    jne .LBB6_1
174; X64-NEXT:  # %bb.2: # %loadbb1
175; X64-NEXT:    movzbl 2(%rdi), %eax
176; X64-NEXT:    movzbl 2(%rsi), %ecx
177; X64-NEXT:    subl %ecx, %eax
178; X64-NEXT:    retq
179; X64-NEXT:  .LBB6_1: # %res_block
180; X64-NEXT:    setae %al
181; X64-NEXT:    movzbl %al, %eax
182; X64-NEXT:    leal -1(%rax,%rax), %eax
183; X64-NEXT:    retq
184  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
185  ret i32 %m
186}
187
188define i1 @length3_eq(i8* %X, i8* %Y) nounwind {
189; X86-LABEL: length3_eq:
190; X86:       # %bb.0:
191; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
192; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
193; X86-NEXT:    movzwl (%ecx), %edx
194; X86-NEXT:    xorw (%eax), %dx
195; X86-NEXT:    movb 2(%ecx), %cl
196; X86-NEXT:    xorb 2(%eax), %cl
197; X86-NEXT:    movzbl %cl, %eax
198; X86-NEXT:    orw %dx, %ax
199; X86-NEXT:    setne %al
200; X86-NEXT:    retl
201;
202; X64-LABEL: length3_eq:
203; X64:       # %bb.0:
204; X64-NEXT:    movzwl (%rdi), %eax
205; X64-NEXT:    xorw (%rsi), %ax
206; X64-NEXT:    movb 2(%rdi), %cl
207; X64-NEXT:    xorb 2(%rsi), %cl
208; X64-NEXT:    movzbl %cl, %ecx
209; X64-NEXT:    orw %ax, %cx
210; X64-NEXT:    setne %al
211; X64-NEXT:    retq
212  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
213  %c = icmp ne i32 %m, 0
214  ret i1 %c
215}
216
217define i32 @length4(i8* %X, i8* %Y) nounwind {
218; X86-LABEL: length4:
219; X86:       # %bb.0:
220; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
221; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
222; X86-NEXT:    movl (%ecx), %ecx
223; X86-NEXT:    movl (%eax), %edx
224; X86-NEXT:    bswapl %ecx
225; X86-NEXT:    bswapl %edx
226; X86-NEXT:    xorl %eax, %eax
227; X86-NEXT:    cmpl %edx, %ecx
228; X86-NEXT:    seta %al
229; X86-NEXT:    sbbl $0, %eax
230; X86-NEXT:    retl
231;
232; X64-LABEL: length4:
233; X64:       # %bb.0:
234; X64-NEXT:    movl (%rdi), %ecx
235; X64-NEXT:    movl (%rsi), %edx
236; X64-NEXT:    bswapl %ecx
237; X64-NEXT:    bswapl %edx
238; X64-NEXT:    xorl %eax, %eax
239; X64-NEXT:    cmpl %edx, %ecx
240; X64-NEXT:    seta %al
241; X64-NEXT:    sbbl $0, %eax
242; X64-NEXT:    retq
243  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
244  ret i32 %m
245}
246
247define i1 @length4_eq(i8* %X, i8* %Y) nounwind {
248; X86-LABEL: length4_eq:
249; X86:       # %bb.0:
250; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
251; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
252; X86-NEXT:    movl (%ecx), %ecx
253; X86-NEXT:    cmpl (%eax), %ecx
254; X86-NEXT:    setne %al
255; X86-NEXT:    retl
256;
257; X64-LABEL: length4_eq:
258; X64:       # %bb.0:
259; X64-NEXT:    movl (%rdi), %eax
260; X64-NEXT:    cmpl (%rsi), %eax
261; X64-NEXT:    setne %al
262; X64-NEXT:    retq
263  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
264  %c = icmp ne i32 %m, 0
265  ret i1 %c
266}
267
268define i1 @length4_eq_const(i8* %X) nounwind {
269; X86-LABEL: length4_eq_const:
270; X86:       # %bb.0:
271; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
272; X86-NEXT:    cmpl $875770417, (%eax) # imm = 0x34333231
273; X86-NEXT:    sete %al
274; X86-NEXT:    retl
275;
276; X64-LABEL: length4_eq_const:
277; X64:       # %bb.0:
278; X64-NEXT:    cmpl $875770417, (%rdi) # imm = 0x34333231
279; X64-NEXT:    sete %al
280; X64-NEXT:    retq
281  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
282  %c = icmp eq i32 %m, 0
283  ret i1 %c
284}
285
286define i32 @length5(i8* %X, i8* %Y) nounwind {
287; X86-LABEL: length5:
288; X86:       # %bb.0: # %loadbb
289; X86-NEXT:    pushl %esi
290; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
291; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
292; X86-NEXT:    movl (%eax), %edx
293; X86-NEXT:    movl (%ecx), %esi
294; X86-NEXT:    bswapl %edx
295; X86-NEXT:    bswapl %esi
296; X86-NEXT:    cmpl %esi, %edx
297; X86-NEXT:    jne .LBB11_1
298; X86-NEXT:  # %bb.2: # %loadbb1
299; X86-NEXT:    movzbl 4(%eax), %eax
300; X86-NEXT:    movzbl 4(%ecx), %ecx
301; X86-NEXT:    subl %ecx, %eax
302; X86-NEXT:    popl %esi
303; X86-NEXT:    retl
304; X86-NEXT:  .LBB11_1: # %res_block
305; X86-NEXT:    setae %al
306; X86-NEXT:    movzbl %al, %eax
307; X86-NEXT:    leal -1(%eax,%eax), %eax
308; X86-NEXT:    popl %esi
309; X86-NEXT:    retl
310;
311; X64-LABEL: length5:
312; X64:       # %bb.0: # %loadbb
313; X64-NEXT:    movl (%rdi), %eax
314; X64-NEXT:    movl (%rsi), %ecx
315; X64-NEXT:    bswapl %eax
316; X64-NEXT:    bswapl %ecx
317; X64-NEXT:    cmpl %ecx, %eax
318; X64-NEXT:    jne .LBB11_1
319; X64-NEXT:  # %bb.2: # %loadbb1
320; X64-NEXT:    movzbl 4(%rdi), %eax
321; X64-NEXT:    movzbl 4(%rsi), %ecx
322; X64-NEXT:    subl %ecx, %eax
323; X64-NEXT:    retq
324; X64-NEXT:  .LBB11_1: # %res_block
325; X64-NEXT:    setae %al
326; X64-NEXT:    movzbl %al, %eax
327; X64-NEXT:    leal -1(%rax,%rax), %eax
328; X64-NEXT:    retq
329  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
330  ret i32 %m
331}
332
333define i1 @length5_eq(i8* %X, i8* %Y) nounwind {
334; X86-LABEL: length5_eq:
335; X86:       # %bb.0:
336; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
337; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
338; X86-NEXT:    movl (%ecx), %edx
339; X86-NEXT:    xorl (%eax), %edx
340; X86-NEXT:    movb 4(%ecx), %cl
341; X86-NEXT:    xorb 4(%eax), %cl
342; X86-NEXT:    movzbl %cl, %eax
343; X86-NEXT:    orl %edx, %eax
344; X86-NEXT:    setne %al
345; X86-NEXT:    retl
346;
347; X64-LABEL: length5_eq:
348; X64:       # %bb.0:
349; X64-NEXT:    movl (%rdi), %eax
350; X64-NEXT:    xorl (%rsi), %eax
351; X64-NEXT:    movb 4(%rdi), %cl
352; X64-NEXT:    xorb 4(%rsi), %cl
353; X64-NEXT:    movzbl %cl, %ecx
354; X64-NEXT:    orl %eax, %ecx
355; X64-NEXT:    setne %al
356; X64-NEXT:    retq
357  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
358  %c = icmp ne i32 %m, 0
359  ret i1 %c
360}
361
362define i1 @length7_eq(i8* %X, i8* %Y) nounwind {
363; X86-LABEL: length7_eq:
364; X86:       # %bb.0:
365; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
366; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
367; X86-NEXT:    movl (%ecx), %edx
368; X86-NEXT:    movl 3(%ecx), %ecx
369; X86-NEXT:    xorl (%eax), %edx
370; X86-NEXT:    xorl 3(%eax), %ecx
371; X86-NEXT:    orl %edx, %ecx
372; X86-NEXT:    setne %al
373; X86-NEXT:    retl
374;
375; X64-LABEL: length7_eq:
376; X64:       # %bb.0:
377; X64-NEXT:    movl (%rdi), %eax
378; X64-NEXT:    movl 3(%rdi), %ecx
379; X64-NEXT:    xorl (%rsi), %eax
380; X64-NEXT:    xorl 3(%rsi), %ecx
381; X64-NEXT:    orl %eax, %ecx
382; X64-NEXT:    setne %al
383; X64-NEXT:    retq
384  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 7) nounwind
385  %c = icmp ne i32 %m, 0
386  ret i1 %c
387}
388
389define i32 @length8(i8* %X, i8* %Y) nounwind {
390; X86-LABEL: length8:
391; X86:       # %bb.0:
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 .LBB14_2
401; X86-NEXT:  # %bb.1: # %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 .LBB14_3
409; X86-NEXT:  .LBB14_2: # %res_block
410; X86-NEXT:    xorl %eax, %eax
411; X86-NEXT:    cmpl %edx, %ecx
412; X86-NEXT:    setae %al
413; X86-NEXT:    leal -1(%eax,%eax), %eax
414; X86-NEXT:  .LBB14_3: # %endblock
415; X86-NEXT:    popl %esi
416; X86-NEXT:    retl
417;
418; X64-LABEL: length8:
419; X64:       # %bb.0:
420; X64-NEXT:    movq (%rdi), %rcx
421; X64-NEXT:    movq (%rsi), %rdx
422; X64-NEXT:    bswapq %rcx
423; X64-NEXT:    bswapq %rdx
424; X64-NEXT:    xorl %eax, %eax
425; X64-NEXT:    cmpq %rdx, %rcx
426; X64-NEXT:    seta %al
427; X64-NEXT:    sbbl $0, %eax
428; X64-NEXT:    retq
429  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
430  ret i32 %m
431}
432
433define i1 @length8_eq(i8* %X, i8* %Y) nounwind {
434; X86-LABEL: length8_eq:
435; X86:       # %bb.0:
436; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
437; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
438; X86-NEXT:    movl (%ecx), %edx
439; X86-NEXT:    movl 4(%ecx), %ecx
440; X86-NEXT:    xorl (%eax), %edx
441; X86-NEXT:    xorl 4(%eax), %ecx
442; X86-NEXT:    orl %edx, %ecx
443; X86-NEXT:    sete %al
444; X86-NEXT:    retl
445;
446; X64-LABEL: length8_eq:
447; X64:       # %bb.0:
448; X64-NEXT:    movq (%rdi), %rax
449; X64-NEXT:    cmpq (%rsi), %rax
450; X64-NEXT:    sete %al
451; X64-NEXT:    retq
452  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
453  %c = icmp eq i32 %m, 0
454  ret i1 %c
455}
456
457define i1 @length8_eq_const(i8* %X) nounwind {
458; X86-LABEL: length8_eq_const:
459; X86:       # %bb.0:
460; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
461; X86-NEXT:    movl $858927408, %ecx # imm = 0x33323130
462; X86-NEXT:    xorl (%eax), %ecx
463; X86-NEXT:    movl $926299444, %edx # imm = 0x37363534
464; X86-NEXT:    xorl 4(%eax), %edx
465; X86-NEXT:    orl %ecx, %edx
466; X86-NEXT:    setne %al
467; X86-NEXT:    retl
468;
469; X64-LABEL: length8_eq_const:
470; X64:       # %bb.0:
471; X64-NEXT:    movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
472; X64-NEXT:    cmpq %rax, (%rdi)
473; X64-NEXT:    setne %al
474; X64-NEXT:    retq
475  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
476  %c = icmp ne i32 %m, 0
477  ret i1 %c
478}
479
480define i1 @length9_eq(i8* %X, i8* %Y) nounwind {
481; X86-LABEL: length9_eq:
482; X86:       # %bb.0:
483; X86-NEXT:    pushl $0
484; X86-NEXT:    pushl $9
485; X86-NEXT:    pushl {{[0-9]+}}(%esp)
486; X86-NEXT:    pushl {{[0-9]+}}(%esp)
487; X86-NEXT:    calll memcmp
488; X86-NEXT:    addl $16, %esp
489; X86-NEXT:    testl %eax, %eax
490; X86-NEXT:    sete %al
491; X86-NEXT:    retl
492;
493; X64-LABEL: length9_eq:
494; X64:       # %bb.0:
495; X64-NEXT:    movq (%rdi), %rax
496; X64-NEXT:    xorq (%rsi), %rax
497; X64-NEXT:    movb 8(%rdi), %cl
498; X64-NEXT:    xorb 8(%rsi), %cl
499; X64-NEXT:    movzbl %cl, %ecx
500; X64-NEXT:    orq %rax, %rcx
501; X64-NEXT:    sete %al
502; X64-NEXT:    retq
503  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9) nounwind
504  %c = icmp eq i32 %m, 0
505  ret i1 %c
506}
507
508define i1 @length10_eq(i8* %X, i8* %Y) nounwind {
509; X86-LABEL: length10_eq:
510; X86:       # %bb.0:
511; X86-NEXT:    pushl $0
512; X86-NEXT:    pushl $10
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: length10_eq:
522; X64:       # %bb.0:
523; X64-NEXT:    movq (%rdi), %rax
524; X64-NEXT:    xorq (%rsi), %rax
525; X64-NEXT:    movzwl 8(%rdi), %ecx
526; X64-NEXT:    xorw 8(%rsi), %cx
527; X64-NEXT:    movzwl %cx, %ecx
528; X64-NEXT:    orq %rax, %rcx
529; X64-NEXT:    sete %al
530; X64-NEXT:    retq
531  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 10) nounwind
532  %c = icmp eq i32 %m, 0
533  ret i1 %c
534}
535
536define i1 @length11_eq(i8* %X, i8* %Y) nounwind {
537; X86-LABEL: length11_eq:
538; X86:       # %bb.0:
539; X86-NEXT:    pushl $0
540; X86-NEXT:    pushl $11
541; X86-NEXT:    pushl {{[0-9]+}}(%esp)
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:    sete %al
547; X86-NEXT:    retl
548;
549; X64-LABEL: length11_eq:
550; X64:       # %bb.0:
551; X64-NEXT:    movq (%rdi), %rax
552; X64-NEXT:    movq 3(%rdi), %rcx
553; X64-NEXT:    xorq (%rsi), %rax
554; X64-NEXT:    xorq 3(%rsi), %rcx
555; X64-NEXT:    orq %rax, %rcx
556; X64-NEXT:    sete %al
557; X64-NEXT:    retq
558  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 11) nounwind
559  %c = icmp eq i32 %m, 0
560  ret i1 %c
561}
562
563define i1 @length12_eq(i8* %X, i8* %Y) nounwind {
564; X86-LABEL: length12_eq:
565; X86:       # %bb.0:
566; X86-NEXT:    pushl $0
567; X86-NEXT:    pushl $12
568; X86-NEXT:    pushl {{[0-9]+}}(%esp)
569; X86-NEXT:    pushl {{[0-9]+}}(%esp)
570; X86-NEXT:    calll memcmp
571; X86-NEXT:    addl $16, %esp
572; X86-NEXT:    testl %eax, %eax
573; X86-NEXT:    setne %al
574; X86-NEXT:    retl
575;
576; X64-LABEL: length12_eq:
577; X64:       # %bb.0:
578; X64-NEXT:    movq (%rdi), %rax
579; X64-NEXT:    xorq (%rsi), %rax
580; X64-NEXT:    movl 8(%rdi), %ecx
581; X64-NEXT:    xorl 8(%rsi), %ecx
582; X64-NEXT:    orq %rax, %rcx
583; X64-NEXT:    setne %al
584; X64-NEXT:    retq
585  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
586  %c = icmp ne i32 %m, 0
587  ret i1 %c
588}
589
590define i32 @length12(i8* %X, i8* %Y) nounwind {
591; X86-LABEL: length12:
592; X86:       # %bb.0:
593; X86-NEXT:    pushl $0
594; X86-NEXT:    pushl $12
595; X86-NEXT:    pushl {{[0-9]+}}(%esp)
596; X86-NEXT:    pushl {{[0-9]+}}(%esp)
597; X86-NEXT:    calll memcmp
598; X86-NEXT:    addl $16, %esp
599; X86-NEXT:    retl
600;
601; X64-LABEL: length12:
602; X64:       # %bb.0:
603; X64-NEXT:    movq (%rdi), %rcx
604; X64-NEXT:    movq (%rsi), %rdx
605; X64-NEXT:    bswapq %rcx
606; X64-NEXT:    bswapq %rdx
607; X64-NEXT:    cmpq %rdx, %rcx
608; X64-NEXT:    jne .LBB21_2
609; X64-NEXT:  # %bb.1: # %loadbb1
610; X64-NEXT:    movl 8(%rdi), %ecx
611; X64-NEXT:    movl 8(%rsi), %edx
612; X64-NEXT:    bswapl %ecx
613; X64-NEXT:    bswapl %edx
614; X64-NEXT:    xorl %eax, %eax
615; X64-NEXT:    cmpq %rdx, %rcx
616; X64-NEXT:    je .LBB21_3
617; X64-NEXT:  .LBB21_2: # %res_block
618; X64-NEXT:    xorl %eax, %eax
619; X64-NEXT:    cmpq %rdx, %rcx
620; X64-NEXT:    setae %al
621; X64-NEXT:    leal -1(%rax,%rax), %eax
622; X64-NEXT:  .LBB21_3: # %endblock
623; X64-NEXT:    retq
624  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
625  ret i32 %m
626}
627
628define i1 @length13_eq(i8* %X, i8* %Y) nounwind {
629; X86-LABEL: length13_eq:
630; X86:       # %bb.0:
631; X86-NEXT:    pushl $0
632; X86-NEXT:    pushl $13
633; X86-NEXT:    pushl {{[0-9]+}}(%esp)
634; X86-NEXT:    pushl {{[0-9]+}}(%esp)
635; X86-NEXT:    calll memcmp
636; X86-NEXT:    addl $16, %esp
637; X86-NEXT:    testl %eax, %eax
638; X86-NEXT:    sete %al
639; X86-NEXT:    retl
640;
641; X64-LABEL: length13_eq:
642; X64:       # %bb.0:
643; X64-NEXT:    movq (%rdi), %rax
644; X64-NEXT:    movq 5(%rdi), %rcx
645; X64-NEXT:    xorq (%rsi), %rax
646; X64-NEXT:    xorq 5(%rsi), %rcx
647; X64-NEXT:    orq %rax, %rcx
648; X64-NEXT:    sete %al
649; X64-NEXT:    retq
650  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 13) nounwind
651  %c = icmp eq i32 %m, 0
652  ret i1 %c
653}
654
655define i1 @length14_eq(i8* %X, i8* %Y) nounwind {
656; X86-LABEL: length14_eq:
657; X86:       # %bb.0:
658; X86-NEXT:    pushl $0
659; X86-NEXT:    pushl $14
660; X86-NEXT:    pushl {{[0-9]+}}(%esp)
661; X86-NEXT:    pushl {{[0-9]+}}(%esp)
662; X86-NEXT:    calll memcmp
663; X86-NEXT:    addl $16, %esp
664; X86-NEXT:    testl %eax, %eax
665; X86-NEXT:    sete %al
666; X86-NEXT:    retl
667;
668; X64-LABEL: length14_eq:
669; X64:       # %bb.0:
670; X64-NEXT:    movq (%rdi), %rax
671; X64-NEXT:    movq 6(%rdi), %rcx
672; X64-NEXT:    xorq (%rsi), %rax
673; X64-NEXT:    xorq 6(%rsi), %rcx
674; X64-NEXT:    orq %rax, %rcx
675; X64-NEXT:    sete %al
676; X64-NEXT:    retq
677  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 14) nounwind
678  %c = icmp eq i32 %m, 0
679  ret i1 %c
680}
681
682define i1 @length15_eq(i8* %X, i8* %Y) nounwind {
683; X86-LABEL: length15_eq:
684; X86:       # %bb.0:
685; X86-NEXT:    pushl $0
686; X86-NEXT:    pushl $15
687; X86-NEXT:    pushl {{[0-9]+}}(%esp)
688; X86-NEXT:    pushl {{[0-9]+}}(%esp)
689; X86-NEXT:    calll memcmp
690; X86-NEXT:    addl $16, %esp
691; X86-NEXT:    testl %eax, %eax
692; X86-NEXT:    sete %al
693; X86-NEXT:    retl
694;
695; X64-LABEL: length15_eq:
696; X64:       # %bb.0:
697; X64-NEXT:    movq (%rdi), %rax
698; X64-NEXT:    movq 7(%rdi), %rcx
699; X64-NEXT:    xorq (%rsi), %rax
700; X64-NEXT:    xorq 7(%rsi), %rcx
701; X64-NEXT:    orq %rax, %rcx
702; X64-NEXT:    sete %al
703; X64-NEXT:    retq
704  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 15) nounwind
705  %c = icmp eq i32 %m, 0
706  ret i1 %c
707}
708
709; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
710
711define i32 @length16(i8* %X, i8* %Y) nounwind {
712; X86-LABEL: length16:
713; X86:       # %bb.0:
714; X86-NEXT:    pushl $0
715; X86-NEXT:    pushl $16
716; X86-NEXT:    pushl {{[0-9]+}}(%esp)
717; X86-NEXT:    pushl {{[0-9]+}}(%esp)
718; X86-NEXT:    calll memcmp
719; X86-NEXT:    addl $16, %esp
720; X86-NEXT:    retl
721;
722; X64-LABEL: length16:
723; X64:       # %bb.0:
724; X64-NEXT:    movq (%rdi), %rcx
725; X64-NEXT:    movq (%rsi), %rdx
726; X64-NEXT:    bswapq %rcx
727; X64-NEXT:    bswapq %rdx
728; X64-NEXT:    cmpq %rdx, %rcx
729; X64-NEXT:    jne .LBB25_2
730; X64-NEXT:  # %bb.1: # %loadbb1
731; X64-NEXT:    movq 8(%rdi), %rcx
732; X64-NEXT:    movq 8(%rsi), %rdx
733; X64-NEXT:    bswapq %rcx
734; X64-NEXT:    bswapq %rdx
735; X64-NEXT:    xorl %eax, %eax
736; X64-NEXT:    cmpq %rdx, %rcx
737; X64-NEXT:    je .LBB25_3
738; X64-NEXT:  .LBB25_2: # %res_block
739; X64-NEXT:    xorl %eax, %eax
740; X64-NEXT:    cmpq %rdx, %rcx
741; X64-NEXT:    setae %al
742; X64-NEXT:    leal -1(%rax,%rax), %eax
743; X64-NEXT:  .LBB25_3: # %endblock
744; X64-NEXT:    retq
745  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
746  ret i32 %m
747}
748
749define i1 @length16_eq(i8* %x, i8* %y) nounwind {
750; X86-NOSSE-LABEL: length16_eq:
751; X86-NOSSE:       # %bb.0:
752; X86-NOSSE-NEXT:    pushl $0
753; X86-NOSSE-NEXT:    pushl $16
754; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
755; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
756; X86-NOSSE-NEXT:    calll memcmp
757; X86-NOSSE-NEXT:    addl $16, %esp
758; X86-NOSSE-NEXT:    testl %eax, %eax
759; X86-NOSSE-NEXT:    setne %al
760; X86-NOSSE-NEXT:    retl
761;
762; X86-SSE1-LABEL: length16_eq:
763; X86-SSE1:       # %bb.0:
764; X86-SSE1-NEXT:    pushl $0
765; X86-SSE1-NEXT:    pushl $16
766; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
767; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
768; X86-SSE1-NEXT:    calll memcmp
769; X86-SSE1-NEXT:    addl $16, %esp
770; X86-SSE1-NEXT:    testl %eax, %eax
771; X86-SSE1-NEXT:    setne %al
772; X86-SSE1-NEXT:    retl
773;
774; X86-SSE2-LABEL: length16_eq:
775; X86-SSE2:       # %bb.0:
776; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
777; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
778; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
779; X86-SSE2-NEXT:    movdqu (%eax), %xmm1
780; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
781; X86-SSE2-NEXT:    pmovmskb %xmm1, %eax
782; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
783; X86-SSE2-NEXT:    setne %al
784; X86-SSE2-NEXT:    retl
785;
786; X64-SSE2-LABEL: length16_eq:
787; X64-SSE2:       # %bb.0:
788; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
789; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
790; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
791; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
792; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
793; X64-SSE2-NEXT:    setne %al
794; X64-SSE2-NEXT:    retq
795;
796; X64-AVX-LABEL: length16_eq:
797; X64-AVX:       # %bb.0:
798; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
799; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
800; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
801; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
802; X64-AVX-NEXT:    setne %al
803; X64-AVX-NEXT:    retq
804  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
805  %cmp = icmp ne i32 %call, 0
806  ret i1 %cmp
807}
808
809define i1 @length16_eq_const(i8* %X) nounwind {
810; X86-NOSSE-LABEL: length16_eq_const:
811; X86-NOSSE:       # %bb.0:
812; X86-NOSSE-NEXT:    pushl $0
813; X86-NOSSE-NEXT:    pushl $16
814; X86-NOSSE-NEXT:    pushl $.L.str
815; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
816; X86-NOSSE-NEXT:    calll memcmp
817; X86-NOSSE-NEXT:    addl $16, %esp
818; X86-NOSSE-NEXT:    testl %eax, %eax
819; X86-NOSSE-NEXT:    sete %al
820; X86-NOSSE-NEXT:    retl
821;
822; X86-SSE1-LABEL: length16_eq_const:
823; X86-SSE1:       # %bb.0:
824; X86-SSE1-NEXT:    pushl $0
825; X86-SSE1-NEXT:    pushl $16
826; X86-SSE1-NEXT:    pushl $.L.str
827; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
828; X86-SSE1-NEXT:    calll memcmp
829; X86-SSE1-NEXT:    addl $16, %esp
830; X86-SSE1-NEXT:    testl %eax, %eax
831; X86-SSE1-NEXT:    sete %al
832; X86-SSE1-NEXT:    retl
833;
834; X86-SSE2-LABEL: length16_eq_const:
835; X86-SSE2:       # %bb.0:
836; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
837; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
838; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
839; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
840; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
841; X86-SSE2-NEXT:    sete %al
842; X86-SSE2-NEXT:    retl
843;
844; X64-SSE2-LABEL: length16_eq_const:
845; X64-SSE2:       # %bb.0:
846; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
847; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
848; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
849; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
850; X64-SSE2-NEXT:    sete %al
851; X64-SSE2-NEXT:    retq
852;
853; X64-AVX-LABEL: length16_eq_const:
854; X64-AVX:       # %bb.0:
855; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
856; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
857; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
858; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
859; X64-AVX-NEXT:    sete %al
860; X64-AVX-NEXT:    retq
861  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
862  %c = icmp eq i32 %m, 0
863  ret i1 %c
864}
865
866; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
867
868define i32 @length24(i8* %X, i8* %Y) nounwind {
869; X86-LABEL: length24:
870; X86:       # %bb.0:
871; X86-NEXT:    pushl $0
872; X86-NEXT:    pushl $24
873; X86-NEXT:    pushl {{[0-9]+}}(%esp)
874; X86-NEXT:    pushl {{[0-9]+}}(%esp)
875; X86-NEXT:    calll memcmp
876; X86-NEXT:    addl $16, %esp
877; X86-NEXT:    retl
878;
879; X64-LABEL: length24:
880; X64:       # %bb.0:
881; X64-NEXT:    movl $24, %edx
882; X64-NEXT:    jmp memcmp # TAILCALL
883  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
884  ret i32 %m
885}
886
887define i1 @length24_eq(i8* %x, i8* %y) nounwind {
888; X86-NOSSE-LABEL: length24_eq:
889; X86-NOSSE:       # %bb.0:
890; X86-NOSSE-NEXT:    pushl $0
891; X86-NOSSE-NEXT:    pushl $24
892; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
893; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
894; X86-NOSSE-NEXT:    calll memcmp
895; X86-NOSSE-NEXT:    addl $16, %esp
896; X86-NOSSE-NEXT:    testl %eax, %eax
897; X86-NOSSE-NEXT:    sete %al
898; X86-NOSSE-NEXT:    retl
899;
900; X86-SSE1-LABEL: length24_eq:
901; X86-SSE1:       # %bb.0:
902; X86-SSE1-NEXT:    pushl $0
903; X86-SSE1-NEXT:    pushl $24
904; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
905; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
906; X86-SSE1-NEXT:    calll memcmp
907; X86-SSE1-NEXT:    addl $16, %esp
908; X86-SSE1-NEXT:    testl %eax, %eax
909; X86-SSE1-NEXT:    sete %al
910; X86-SSE1-NEXT:    retl
911;
912; X86-SSE2-LABEL: length24_eq:
913; X86-SSE2:       # %bb.0:
914; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
915; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
916; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
917; X86-SSE2-NEXT:    movdqu 8(%ecx), %xmm1
918; X86-SSE2-NEXT:    movdqu (%eax), %xmm2
919; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
920; X86-SSE2-NEXT:    movdqu 8(%eax), %xmm0
921; X86-SSE2-NEXT:    pcmpeqb %xmm1, %xmm0
922; X86-SSE2-NEXT:    pand %xmm2, %xmm0
923; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
924; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
925; X86-SSE2-NEXT:    sete %al
926; X86-SSE2-NEXT:    retl
927;
928; X64-SSE2-LABEL: length24_eq:
929; X64-SSE2:       # %bb.0:
930; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
931; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
932; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
933; X64-SSE2-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
934; X64-SSE2-NEXT:    movq {{.*#+}} xmm2 = mem[0],zero
935; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
936; X64-SSE2-NEXT:    pand %xmm1, %xmm2
937; X64-SSE2-NEXT:    pmovmskb %xmm2, %eax
938; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
939; X64-SSE2-NEXT:    sete %al
940; X64-SSE2-NEXT:    retq
941;
942; X64-AVX-LABEL: length24_eq:
943; X64-AVX:       # %bb.0:
944; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
945; X64-AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
946; X64-AVX-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
947; X64-AVX-NEXT:    vpcmpeqb %xmm2, %xmm1, %xmm1
948; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
949; X64-AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
950; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
951; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
952; X64-AVX-NEXT:    sete %al
953; X64-AVX-NEXT:    retq
954  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
955  %cmp = icmp eq i32 %call, 0
956  ret i1 %cmp
957}
958
959define i1 @length24_eq_const(i8* %X) nounwind {
960; X86-NOSSE-LABEL: length24_eq_const:
961; X86-NOSSE:       # %bb.0:
962; X86-NOSSE-NEXT:    pushl $0
963; X86-NOSSE-NEXT:    pushl $24
964; X86-NOSSE-NEXT:    pushl $.L.str
965; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
966; X86-NOSSE-NEXT:    calll memcmp
967; X86-NOSSE-NEXT:    addl $16, %esp
968; X86-NOSSE-NEXT:    testl %eax, %eax
969; X86-NOSSE-NEXT:    setne %al
970; X86-NOSSE-NEXT:    retl
971;
972; X86-SSE1-LABEL: length24_eq_const:
973; X86-SSE1:       # %bb.0:
974; X86-SSE1-NEXT:    pushl $0
975; X86-SSE1-NEXT:    pushl $24
976; X86-SSE1-NEXT:    pushl $.L.str
977; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
978; X86-SSE1-NEXT:    calll memcmp
979; X86-SSE1-NEXT:    addl $16, %esp
980; X86-SSE1-NEXT:    testl %eax, %eax
981; X86-SSE1-NEXT:    setne %al
982; X86-SSE1-NEXT:    retl
983;
984; X86-SSE2-LABEL: length24_eq_const:
985; X86-SSE2:       # %bb.0:
986; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
987; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
988; X86-SSE2-NEXT:    movdqu 8(%eax), %xmm1
989; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm1
990; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
991; X86-SSE2-NEXT:    pand %xmm1, %xmm0
992; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
993; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
994; X86-SSE2-NEXT:    setne %al
995; X86-SSE2-NEXT:    retl
996;
997; X64-SSE2-LABEL: length24_eq_const:
998; X64-SSE2:       # %bb.0:
999; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
1000; X64-SSE2-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
1001; X64-SSE2-NEXT:    movabsq $3689065127958034230, %rax # imm = 0x3332313039383736
1002; X64-SSE2-NEXT:    movq %rax, %xmm2
1003; X64-SSE2-NEXT:    pcmpeqb %xmm1, %xmm2
1004; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
1005; X64-SSE2-NEXT:    pand %xmm2, %xmm0
1006; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
1007; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1008; X64-SSE2-NEXT:    setne %al
1009; X64-SSE2-NEXT:    retq
1010;
1011; X64-AVX-LABEL: length24_eq_const:
1012; X64-AVX:       # %bb.0:
1013; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
1014; X64-AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
1015; X64-AVX-NEXT:    movabsq $3689065127958034230, %rax # imm = 0x3332313039383736
1016; X64-AVX-NEXT:    vmovq %rax, %xmm2
1017; X64-AVX-NEXT:    vpcmpeqb %xmm2, %xmm1, %xmm1
1018; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
1019; X64-AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
1020; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
1021; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1022; X64-AVX-NEXT:    setne %al
1023; X64-AVX-NEXT:    retq
1024  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
1025  %c = icmp ne i32 %m, 0
1026  ret i1 %c
1027}
1028
1029define i32 @length32(i8* %X, i8* %Y) nounwind {
1030; X86-LABEL: length32:
1031; X86:       # %bb.0:
1032; X86-NEXT:    pushl $0
1033; X86-NEXT:    pushl $32
1034; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1035; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1036; X86-NEXT:    calll memcmp
1037; X86-NEXT:    addl $16, %esp
1038; X86-NEXT:    retl
1039;
1040; X64-LABEL: length32:
1041; X64:       # %bb.0:
1042; X64-NEXT:    movl $32, %edx
1043; X64-NEXT:    jmp memcmp # TAILCALL
1044  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
1045  ret i32 %m
1046}
1047
1048; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
1049
1050define i1 @length32_eq(i8* %x, i8* %y) nounwind {
1051; X86-NOSSE-LABEL: length32_eq:
1052; X86-NOSSE:       # %bb.0:
1053; X86-NOSSE-NEXT:    pushl $0
1054; X86-NOSSE-NEXT:    pushl $32
1055; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
1056; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
1057; X86-NOSSE-NEXT:    calll memcmp
1058; X86-NOSSE-NEXT:    addl $16, %esp
1059; X86-NOSSE-NEXT:    testl %eax, %eax
1060; X86-NOSSE-NEXT:    sete %al
1061; X86-NOSSE-NEXT:    retl
1062;
1063; X86-SSE1-LABEL: length32_eq:
1064; X86-SSE1:       # %bb.0:
1065; X86-SSE1-NEXT:    pushl $0
1066; X86-SSE1-NEXT:    pushl $32
1067; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
1068; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
1069; X86-SSE1-NEXT:    calll memcmp
1070; X86-SSE1-NEXT:    addl $16, %esp
1071; X86-SSE1-NEXT:    testl %eax, %eax
1072; X86-SSE1-NEXT:    sete %al
1073; X86-SSE1-NEXT:    retl
1074;
1075; X86-SSE2-LABEL: length32_eq:
1076; X86-SSE2:       # %bb.0:
1077; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1078; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1079; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
1080; X86-SSE2-NEXT:    movdqu 16(%ecx), %xmm1
1081; X86-SSE2-NEXT:    movdqu (%eax), %xmm2
1082; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
1083; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm0
1084; X86-SSE2-NEXT:    pcmpeqb %xmm1, %xmm0
1085; X86-SSE2-NEXT:    pand %xmm2, %xmm0
1086; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
1087; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1088; X86-SSE2-NEXT:    sete %al
1089; X86-SSE2-NEXT:    retl
1090;
1091; X64-SSE2-LABEL: length32_eq:
1092; X64-SSE2:       # %bb.0:
1093; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
1094; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm1
1095; X64-SSE2-NEXT:    movdqu (%rsi), %xmm2
1096; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
1097; X64-SSE2-NEXT:    movdqu 16(%rsi), %xmm0
1098; X64-SSE2-NEXT:    pcmpeqb %xmm1, %xmm0
1099; X64-SSE2-NEXT:    pand %xmm2, %xmm0
1100; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
1101; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1102; X64-SSE2-NEXT:    sete %al
1103; X64-SSE2-NEXT:    retq
1104;
1105; X64-AVX1-LABEL: length32_eq:
1106; X64-AVX1:       # %bb.0:
1107; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
1108; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm1
1109; X64-AVX1-NEXT:    vpcmpeqb 16(%rsi), %xmm1, %xmm1
1110; X64-AVX1-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
1111; X64-AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
1112; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
1113; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1114; X64-AVX1-NEXT:    sete %al
1115; X64-AVX1-NEXT:    retq
1116;
1117; X64-AVX2-LABEL: length32_eq:
1118; X64-AVX2:       # %bb.0:
1119; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1120; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
1121; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1122; X64-AVX2-NEXT:    cmpl $-1, %eax
1123; X64-AVX2-NEXT:    sete %al
1124; X64-AVX2-NEXT:    vzeroupper
1125; X64-AVX2-NEXT:    retq
1126  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
1127  %cmp = icmp eq i32 %call, 0
1128  ret i1 %cmp
1129}
1130
1131define i1 @length32_eq_const(i8* %X) nounwind {
1132; X86-NOSSE-LABEL: length32_eq_const:
1133; X86-NOSSE:       # %bb.0:
1134; X86-NOSSE-NEXT:    pushl $0
1135; X86-NOSSE-NEXT:    pushl $32
1136; X86-NOSSE-NEXT:    pushl $.L.str
1137; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
1138; X86-NOSSE-NEXT:    calll memcmp
1139; X86-NOSSE-NEXT:    addl $16, %esp
1140; X86-NOSSE-NEXT:    testl %eax, %eax
1141; X86-NOSSE-NEXT:    setne %al
1142; X86-NOSSE-NEXT:    retl
1143;
1144; X86-SSE1-LABEL: length32_eq_const:
1145; X86-SSE1:       # %bb.0:
1146; X86-SSE1-NEXT:    pushl $0
1147; X86-SSE1-NEXT:    pushl $32
1148; X86-SSE1-NEXT:    pushl $.L.str
1149; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
1150; X86-SSE1-NEXT:    calll memcmp
1151; X86-SSE1-NEXT:    addl $16, %esp
1152; X86-SSE1-NEXT:    testl %eax, %eax
1153; X86-SSE1-NEXT:    setne %al
1154; X86-SSE1-NEXT:    retl
1155;
1156; X86-SSE2-LABEL: length32_eq_const:
1157; X86-SSE2:       # %bb.0:
1158; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1159; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
1160; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm1
1161; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm1
1162; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
1163; X86-SSE2-NEXT:    pand %xmm1, %xmm0
1164; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
1165; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1166; X86-SSE2-NEXT:    setne %al
1167; X86-SSE2-NEXT:    retl
1168;
1169; X64-SSE2-LABEL: length32_eq_const:
1170; X64-SSE2:       # %bb.0:
1171; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
1172; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm1
1173; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm1
1174; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
1175; X64-SSE2-NEXT:    pand %xmm1, %xmm0
1176; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
1177; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1178; X64-SSE2-NEXT:    setne %al
1179; X64-SSE2-NEXT:    retq
1180;
1181; X64-AVX1-LABEL: length32_eq_const:
1182; X64-AVX1:       # %bb.0:
1183; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
1184; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm1
1185; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm1, %xmm1
1186; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
1187; X64-AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
1188; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
1189; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1190; X64-AVX1-NEXT:    setne %al
1191; X64-AVX1-NEXT:    retq
1192;
1193; X64-AVX2-LABEL: length32_eq_const:
1194; X64-AVX2:       # %bb.0:
1195; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1196; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1197; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1198; X64-AVX2-NEXT:    cmpl $-1, %eax
1199; X64-AVX2-NEXT:    setne %al
1200; X64-AVX2-NEXT:    vzeroupper
1201; X64-AVX2-NEXT:    retq
1202  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
1203  %c = icmp ne i32 %m, 0
1204  ret i1 %c
1205}
1206
1207define i32 @length64(i8* %X, i8* %Y) nounwind {
1208; X86-LABEL: length64:
1209; X86:       # %bb.0:
1210; X86-NEXT:    pushl $0
1211; X86-NEXT:    pushl $64
1212; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1213; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1214; X86-NEXT:    calll memcmp
1215; X86-NEXT:    addl $16, %esp
1216; X86-NEXT:    retl
1217;
1218; X64-LABEL: length64:
1219; X64:       # %bb.0:
1220; X64-NEXT:    movl $64, %edx
1221; X64-NEXT:    jmp memcmp # TAILCALL
1222  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
1223  ret i32 %m
1224}
1225
1226define i1 @length64_eq(i8* %x, i8* %y) nounwind {
1227; X86-LABEL: length64_eq:
1228; X86:       # %bb.0:
1229; X86-NEXT:    pushl $0
1230; X86-NEXT:    pushl $64
1231; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1232; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1233; X86-NEXT:    calll memcmp
1234; X86-NEXT:    addl $16, %esp
1235; X86-NEXT:    testl %eax, %eax
1236; X86-NEXT:    setne %al
1237; X86-NEXT:    retl
1238;
1239; X64-SSE2-LABEL: length64_eq:
1240; X64-SSE2:       # %bb.0:
1241; X64-SSE2-NEXT:    pushq %rax
1242; X64-SSE2-NEXT:    movl $64, %edx
1243; X64-SSE2-NEXT:    callq memcmp
1244; X64-SSE2-NEXT:    testl %eax, %eax
1245; X64-SSE2-NEXT:    setne %al
1246; X64-SSE2-NEXT:    popq %rcx
1247; X64-SSE2-NEXT:    retq
1248;
1249; X64-AVX1-LABEL: length64_eq:
1250; X64-AVX1:       # %bb.0:
1251; X64-AVX1-NEXT:    pushq %rax
1252; X64-AVX1-NEXT:    movl $64, %edx
1253; X64-AVX1-NEXT:    callq memcmp
1254; X64-AVX1-NEXT:    testl %eax, %eax
1255; X64-AVX1-NEXT:    setne %al
1256; X64-AVX1-NEXT:    popq %rcx
1257; X64-AVX1-NEXT:    retq
1258;
1259; X64-AVX2-LABEL: length64_eq:
1260; X64-AVX2:       # %bb.0:
1261; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1262; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm1
1263; X64-AVX2-NEXT:    vpcmpeqb 32(%rsi), %ymm1, %ymm1
1264; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
1265; X64-AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
1266; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1267; X64-AVX2-NEXT:    cmpl $-1, %eax
1268; X64-AVX2-NEXT:    setne %al
1269; X64-AVX2-NEXT:    vzeroupper
1270; X64-AVX2-NEXT:    retq
1271  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
1272  %cmp = icmp ne i32 %call, 0
1273  ret i1 %cmp
1274}
1275
1276define i1 @length64_eq_const(i8* %X) nounwind {
1277; X86-LABEL: length64_eq_const:
1278; X86:       # %bb.0:
1279; X86-NEXT:    pushl $0
1280; X86-NEXT:    pushl $64
1281; X86-NEXT:    pushl $.L.str
1282; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1283; X86-NEXT:    calll memcmp
1284; X86-NEXT:    addl $16, %esp
1285; X86-NEXT:    testl %eax, %eax
1286; X86-NEXT:    sete %al
1287; X86-NEXT:    retl
1288;
1289; X64-SSE2-LABEL: length64_eq_const:
1290; X64-SSE2:       # %bb.0:
1291; X64-SSE2-NEXT:    pushq %rax
1292; X64-SSE2-NEXT:    movl $.L.str, %esi
1293; X64-SSE2-NEXT:    movl $64, %edx
1294; X64-SSE2-NEXT:    callq memcmp
1295; X64-SSE2-NEXT:    testl %eax, %eax
1296; X64-SSE2-NEXT:    sete %al
1297; X64-SSE2-NEXT:    popq %rcx
1298; X64-SSE2-NEXT:    retq
1299;
1300; X64-AVX1-LABEL: length64_eq_const:
1301; X64-AVX1:       # %bb.0:
1302; X64-AVX1-NEXT:    pushq %rax
1303; X64-AVX1-NEXT:    movl $.L.str, %esi
1304; X64-AVX1-NEXT:    movl $64, %edx
1305; X64-AVX1-NEXT:    callq memcmp
1306; X64-AVX1-NEXT:    testl %eax, %eax
1307; X64-AVX1-NEXT:    sete %al
1308; X64-AVX1-NEXT:    popq %rcx
1309; X64-AVX1-NEXT:    retq
1310;
1311; X64-AVX2-LABEL: length64_eq_const:
1312; X64-AVX2:       # %bb.0:
1313; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1314; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm1
1315; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm1, %ymm1
1316; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1317; X64-AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
1318; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1319; X64-AVX2-NEXT:    cmpl $-1, %eax
1320; X64-AVX2-NEXT:    sete %al
1321; X64-AVX2-NEXT:    vzeroupper
1322; X64-AVX2-NEXT:    retq
1323  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
1324  %c = icmp eq i32 %m, 0
1325  ret i1 %c
1326}
1327
1328; This checks that we do not do stupid things with huge sizes.
1329define i32 @huge_length(i8* %X, i8* %Y) nounwind {
1330; X86-LABEL: huge_length:
1331; X86:       # %bb.0:
1332; X86-NEXT:    pushl $2147483647 # imm = 0x7FFFFFFF
1333; X86-NEXT:    pushl $-1
1334; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1335; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1336; X86-NEXT:    calll memcmp
1337; X86-NEXT:    addl $16, %esp
1338; X86-NEXT:    retl
1339;
1340; X64-LABEL: huge_length:
1341; X64:       # %bb.0:
1342; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
1343; X64-NEXT:    jmp memcmp # TAILCALL
1344  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind
1345  ret i32 %m
1346}
1347