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:    cmpw (%eax), %dx
195; X86-NEXT:    jne .LBB7_2
196; X86-NEXT:  # BB#1: # %loadbb1
197; X86-NEXT:    movb 2(%ecx), %dl
198; X86-NEXT:    xorl %ecx, %ecx
199; X86-NEXT:    cmpb 2(%eax), %dl
200; X86-NEXT:    je .LBB7_3
201; X86-NEXT:  .LBB7_2: # %res_block
202; X86-NEXT:    movl $1, %ecx
203; X86-NEXT:  .LBB7_3: # %endblock
204; X86-NEXT:    testl %ecx, %ecx
205; X86-NEXT:    setne %al
206; X86-NEXT:    retl
207;
208; X64-LABEL: length3_eq:
209; X64:       # BB#0:
210; X64-NEXT:    movzwl (%rdi), %eax
211; X64-NEXT:    cmpw (%rsi), %ax
212; X64-NEXT:    jne .LBB7_2
213; X64-NEXT:  # BB#1: # %loadbb1
214; X64-NEXT:    movb 2(%rdi), %cl
215; X64-NEXT:    xorl %eax, %eax
216; X64-NEXT:    cmpb 2(%rsi), %cl
217; X64-NEXT:    je .LBB7_3
218; X64-NEXT:  .LBB7_2: # %res_block
219; X64-NEXT:    movl $1, %eax
220; X64-NEXT:  .LBB7_3: # %endblock
221; X64-NEXT:    testl %eax, %eax
222; X64-NEXT:    setne %al
223; X64-NEXT:    retq
224  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
225  %c = icmp ne i32 %m, 0
226  ret i1 %c
227}
228
229define i32 @length4(i8* %X, i8* %Y) nounwind {
230; X86-LABEL: length4:
231; X86:       # BB#0:
232; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
233; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
234; X86-NEXT:    movl (%ecx), %ecx
235; X86-NEXT:    movl (%eax), %edx
236; X86-NEXT:    bswapl %ecx
237; X86-NEXT:    bswapl %edx
238; X86-NEXT:    xorl %eax, %eax
239; X86-NEXT:    cmpl %edx, %ecx
240; X86-NEXT:    seta %al
241; X86-NEXT:    sbbl $0, %eax
242; X86-NEXT:    retl
243;
244; X64-LABEL: length4:
245; X64:       # BB#0:
246; X64-NEXT:    movl (%rdi), %ecx
247; X64-NEXT:    movl (%rsi), %edx
248; X64-NEXT:    bswapl %ecx
249; X64-NEXT:    bswapl %edx
250; X64-NEXT:    xorl %eax, %eax
251; X64-NEXT:    cmpl %edx, %ecx
252; X64-NEXT:    seta %al
253; X64-NEXT:    sbbl $0, %eax
254; X64-NEXT:    retq
255  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
256  ret i32 %m
257}
258
259define i1 @length4_eq(i8* %X, i8* %Y) nounwind {
260; X86-LABEL: length4_eq:
261; X86:       # BB#0:
262; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
263; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
264; X86-NEXT:    movl (%ecx), %ecx
265; X86-NEXT:    cmpl (%eax), %ecx
266; X86-NEXT:    setne %al
267; X86-NEXT:    retl
268;
269; X64-LABEL: length4_eq:
270; X64:       # BB#0:
271; X64-NEXT:    movl (%rdi), %eax
272; X64-NEXT:    cmpl (%rsi), %eax
273; X64-NEXT:    setne %al
274; X64-NEXT:    retq
275  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
276  %c = icmp ne i32 %m, 0
277  ret i1 %c
278}
279
280define i1 @length4_eq_const(i8* %X) nounwind {
281; X86-LABEL: length4_eq_const:
282; X86:       # BB#0:
283; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
284; X86-NEXT:    cmpl $875770417, (%eax) # imm = 0x34333231
285; X86-NEXT:    sete %al
286; X86-NEXT:    retl
287;
288; X64-LABEL: length4_eq_const:
289; X64:       # BB#0:
290; X64-NEXT:    cmpl $875770417, (%rdi) # imm = 0x34333231
291; X64-NEXT:    sete %al
292; X64-NEXT:    retq
293  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
294  %c = icmp eq i32 %m, 0
295  ret i1 %c
296}
297
298define i32 @length5(i8* %X, i8* %Y) nounwind {
299; X86-LABEL: length5:
300; X86:       # BB#0: # %loadbb
301; X86-NEXT:    pushl %esi
302; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
303; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
304; X86-NEXT:    movl (%eax), %edx
305; X86-NEXT:    movl (%ecx), %esi
306; X86-NEXT:    bswapl %edx
307; X86-NEXT:    bswapl %esi
308; X86-NEXT:    cmpl %esi, %edx
309; X86-NEXT:    jne .LBB11_1
310; X86-NEXT:  # BB#2: # %loadbb1
311; X86-NEXT:    movzbl 4(%eax), %eax
312; X86-NEXT:    movzbl 4(%ecx), %ecx
313; X86-NEXT:    subl %ecx, %eax
314; X86-NEXT:    popl %esi
315; X86-NEXT:    retl
316; X86-NEXT:  .LBB11_1: # %res_block
317; X86-NEXT:    setae %al
318; X86-NEXT:    movzbl %al, %eax
319; X86-NEXT:    leal -1(%eax,%eax), %eax
320; X86-NEXT:    popl %esi
321; X86-NEXT:    retl
322;
323; X64-LABEL: length5:
324; X64:       # BB#0: # %loadbb
325; X64-NEXT:    movl (%rdi), %eax
326; X64-NEXT:    movl (%rsi), %ecx
327; X64-NEXT:    bswapl %eax
328; X64-NEXT:    bswapl %ecx
329; X64-NEXT:    cmpl %ecx, %eax
330; X64-NEXT:    jne .LBB11_1
331; X64-NEXT:  # BB#2: # %loadbb1
332; X64-NEXT:    movzbl 4(%rdi), %eax
333; X64-NEXT:    movzbl 4(%rsi), %ecx
334; X64-NEXT:    subl %ecx, %eax
335; X64-NEXT:    retq
336; X64-NEXT:  .LBB11_1: # %res_block
337; X64-NEXT:    setae %al
338; X64-NEXT:    movzbl %al, %eax
339; X64-NEXT:    leal -1(%rax,%rax), %eax
340; X64-NEXT:    retq
341  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
342  ret i32 %m
343}
344
345define i1 @length5_eq(i8* %X, i8* %Y) nounwind {
346; X86-LABEL: length5_eq:
347; X86:       # BB#0:
348; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
349; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
350; X86-NEXT:    movl (%ecx), %edx
351; X86-NEXT:    cmpl (%eax), %edx
352; X86-NEXT:    jne .LBB12_2
353; X86-NEXT:  # BB#1: # %loadbb1
354; X86-NEXT:    movb 4(%ecx), %dl
355; X86-NEXT:    xorl %ecx, %ecx
356; X86-NEXT:    cmpb 4(%eax), %dl
357; X86-NEXT:    je .LBB12_3
358; X86-NEXT:  .LBB12_2: # %res_block
359; X86-NEXT:    movl $1, %ecx
360; X86-NEXT:  .LBB12_3: # %endblock
361; X86-NEXT:    testl %ecx, %ecx
362; X86-NEXT:    setne %al
363; X86-NEXT:    retl
364;
365; X64-LABEL: length5_eq:
366; X64:       # BB#0:
367; X64-NEXT:    movl (%rdi), %eax
368; X64-NEXT:    cmpl (%rsi), %eax
369; X64-NEXT:    jne .LBB12_2
370; X64-NEXT:  # BB#1: # %loadbb1
371; X64-NEXT:    movb 4(%rdi), %cl
372; X64-NEXT:    xorl %eax, %eax
373; X64-NEXT:    cmpb 4(%rsi), %cl
374; X64-NEXT:    je .LBB12_3
375; X64-NEXT:  .LBB12_2: # %res_block
376; X64-NEXT:    movl $1, %eax
377; X64-NEXT:  .LBB12_3: # %endblock
378; X64-NEXT:    testl %eax, %eax
379; X64-NEXT:    setne %al
380; X64-NEXT:    retq
381  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
382  %c = icmp ne i32 %m, 0
383  ret i1 %c
384}
385
386define i32 @length8(i8* %X, i8* %Y) nounwind {
387; X86-LABEL: length8:
388; X86:       # BB#0:
389; X86-NEXT:    pushl %esi
390; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
391; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
392; X86-NEXT:    movl (%esi), %ecx
393; X86-NEXT:    movl (%eax), %edx
394; X86-NEXT:    bswapl %ecx
395; X86-NEXT:    bswapl %edx
396; X86-NEXT:    cmpl %edx, %ecx
397; X86-NEXT:    jne .LBB13_2
398; X86-NEXT:  # BB#1: # %loadbb1
399; X86-NEXT:    movl 4(%esi), %ecx
400; X86-NEXT:    movl 4(%eax), %edx
401; X86-NEXT:    bswapl %ecx
402; X86-NEXT:    bswapl %edx
403; X86-NEXT:    xorl %eax, %eax
404; X86-NEXT:    cmpl %edx, %ecx
405; X86-NEXT:    je .LBB13_3
406; X86-NEXT:  .LBB13_2: # %res_block
407; X86-NEXT:    xorl %eax, %eax
408; X86-NEXT:    cmpl %edx, %ecx
409; X86-NEXT:    setae %al
410; X86-NEXT:    leal -1(%eax,%eax), %eax
411; X86-NEXT:  .LBB13_3: # %endblock
412; X86-NEXT:    popl %esi
413; X86-NEXT:    retl
414;
415; X64-LABEL: length8:
416; X64:       # BB#0:
417; X64-NEXT:    movq (%rdi), %rcx
418; X64-NEXT:    movq (%rsi), %rdx
419; X64-NEXT:    bswapq %rcx
420; X64-NEXT:    bswapq %rdx
421; X64-NEXT:    xorl %eax, %eax
422; X64-NEXT:    cmpq %rdx, %rcx
423; X64-NEXT:    seta %al
424; X64-NEXT:    sbbl $0, %eax
425; X64-NEXT:    retq
426  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
427  ret i32 %m
428}
429
430define i1 @length8_eq(i8* %X, i8* %Y) nounwind {
431; X86-LABEL: length8_eq:
432; X86:       # BB#0:
433; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
434; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
435; X86-NEXT:    movl (%ecx), %edx
436; X86-NEXT:    cmpl (%eax), %edx
437; X86-NEXT:    jne .LBB14_2
438; X86-NEXT:  # BB#1: # %loadbb1
439; X86-NEXT:    movl 4(%ecx), %edx
440; X86-NEXT:    xorl %ecx, %ecx
441; X86-NEXT:    cmpl 4(%eax), %edx
442; X86-NEXT:    je .LBB14_3
443; X86-NEXT:  .LBB14_2: # %res_block
444; X86-NEXT:    movl $1, %ecx
445; X86-NEXT:  .LBB14_3: # %endblock
446; X86-NEXT:    testl %ecx, %ecx
447; X86-NEXT:    sete %al
448; X86-NEXT:    retl
449;
450; X64-LABEL: length8_eq:
451; X64:       # BB#0:
452; X64-NEXT:    movq (%rdi), %rax
453; X64-NEXT:    cmpq (%rsi), %rax
454; X64-NEXT:    sete %al
455; X64-NEXT:    retq
456  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
457  %c = icmp eq i32 %m, 0
458  ret i1 %c
459}
460
461define i1 @length8_eq_const(i8* %X) nounwind {
462; X86-LABEL: length8_eq_const:
463; X86:       # BB#0:
464; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
465; X86-NEXT:    cmpl $858927408, (%ecx) # imm = 0x33323130
466; X86-NEXT:    jne .LBB15_2
467; X86-NEXT:  # BB#1: # %loadbb1
468; X86-NEXT:    xorl %eax, %eax
469; X86-NEXT:    cmpl $926299444, 4(%ecx) # imm = 0x37363534
470; X86-NEXT:    je .LBB15_3
471; X86-NEXT:  .LBB15_2: # %res_block
472; X86-NEXT:    movl $1, %eax
473; X86-NEXT:  .LBB15_3: # %endblock
474; X86-NEXT:    testl %eax, %eax
475; X86-NEXT:    setne %al
476; X86-NEXT:    retl
477;
478; X64-LABEL: length8_eq_const:
479; X64:       # BB#0:
480; X64-NEXT:    movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
481; X64-NEXT:    cmpq %rax, (%rdi)
482; X64-NEXT:    setne %al
483; X64-NEXT:    retq
484  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
485  %c = icmp ne i32 %m, 0
486  ret i1 %c
487}
488
489define i1 @length12_eq(i8* %X, i8* %Y) nounwind {
490; X86-LABEL: length12_eq:
491; X86:       # BB#0:
492; X86-NEXT:    pushl $0
493; X86-NEXT:    pushl $12
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:    testl %eax, %eax
499; X86-NEXT:    setne %al
500; X86-NEXT:    retl
501;
502; X64-LABEL: length12_eq:
503; X64:       # BB#0:
504; X64-NEXT:    movq (%rdi), %rax
505; X64-NEXT:    cmpq (%rsi), %rax
506; X64-NEXT:    jne .LBB16_2
507; X64-NEXT:  # BB#1: # %loadbb1
508; X64-NEXT:    movl 8(%rdi), %ecx
509; X64-NEXT:    xorl %eax, %eax
510; X64-NEXT:    cmpl 8(%rsi), %ecx
511; X64-NEXT:    je .LBB16_3
512; X64-NEXT:  .LBB16_2: # %res_block
513; X64-NEXT:    movl $1, %eax
514; X64-NEXT:  .LBB16_3: # %endblock
515; X64-NEXT:    testl %eax, %eax
516; X64-NEXT:    setne %al
517; X64-NEXT:    retq
518  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
519  %c = icmp ne i32 %m, 0
520  ret i1 %c
521}
522
523define i32 @length12(i8* %X, i8* %Y) nounwind {
524; X86-LABEL: length12:
525; X86:       # BB#0:
526; X86-NEXT:    pushl $0
527; X86-NEXT:    pushl $12
528; X86-NEXT:    pushl {{[0-9]+}}(%esp)
529; X86-NEXT:    pushl {{[0-9]+}}(%esp)
530; X86-NEXT:    calll memcmp
531; X86-NEXT:    addl $16, %esp
532; X86-NEXT:    retl
533;
534; X64-LABEL: length12:
535; X64:       # BB#0:
536; X64-NEXT:    movq (%rdi), %rcx
537; X64-NEXT:    movq (%rsi), %rdx
538; X64-NEXT:    bswapq %rcx
539; X64-NEXT:    bswapq %rdx
540; X64-NEXT:    cmpq %rdx, %rcx
541; X64-NEXT:    jne .LBB17_2
542; X64-NEXT:  # BB#1: # %loadbb1
543; X64-NEXT:    movl 8(%rdi), %ecx
544; X64-NEXT:    movl 8(%rsi), %edx
545; X64-NEXT:    bswapl %ecx
546; X64-NEXT:    bswapl %edx
547; X64-NEXT:    xorl %eax, %eax
548; X64-NEXT:    cmpq %rdx, %rcx
549; X64-NEXT:    je .LBB17_3
550; X64-NEXT:  .LBB17_2: # %res_block
551; X64-NEXT:    xorl %eax, %eax
552; X64-NEXT:    cmpq %rdx, %rcx
553; X64-NEXT:    setae %al
554; X64-NEXT:    leal -1(%rax,%rax), %eax
555; X64-NEXT:  .LBB17_3: # %endblock
556; X64-NEXT:    retq
557  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
558  ret i32 %m
559}
560
561; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
562
563define i32 @length16(i8* %X, i8* %Y) nounwind {
564; X86-LABEL: length16:
565; X86:       # BB#0:
566; X86-NEXT:    pushl $0
567; X86-NEXT:    pushl $16
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:    retl
573;
574; X64-LABEL: length16:
575; X64:       # BB#0:
576; X64-NEXT:    movq (%rdi), %rcx
577; X64-NEXT:    movq (%rsi), %rdx
578; X64-NEXT:    bswapq %rcx
579; X64-NEXT:    bswapq %rdx
580; X64-NEXT:    cmpq %rdx, %rcx
581; X64-NEXT:    jne .LBB18_2
582; X64-NEXT:  # BB#1: # %loadbb1
583; X64-NEXT:    movq 8(%rdi), %rcx
584; X64-NEXT:    movq 8(%rsi), %rdx
585; X64-NEXT:    bswapq %rcx
586; X64-NEXT:    bswapq %rdx
587; X64-NEXT:    xorl %eax, %eax
588; X64-NEXT:    cmpq %rdx, %rcx
589; X64-NEXT:    je .LBB18_3
590; X64-NEXT:  .LBB18_2: # %res_block
591; X64-NEXT:    xorl %eax, %eax
592; X64-NEXT:    cmpq %rdx, %rcx
593; X64-NEXT:    setae %al
594; X64-NEXT:    leal -1(%rax,%rax), %eax
595; X64-NEXT:  .LBB18_3: # %endblock
596; X64-NEXT:    retq
597  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
598  ret i32 %m
599}
600
601define i1 @length16_eq(i8* %x, i8* %y) nounwind {
602; X86-NOSSE-LABEL: length16_eq:
603; X86-NOSSE:       # BB#0:
604; X86-NOSSE-NEXT:    pushl $0
605; X86-NOSSE-NEXT:    pushl $16
606; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
607; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
608; X86-NOSSE-NEXT:    calll memcmp
609; X86-NOSSE-NEXT:    addl $16, %esp
610; X86-NOSSE-NEXT:    testl %eax, %eax
611; X86-NOSSE-NEXT:    setne %al
612; X86-NOSSE-NEXT:    retl
613;
614; X86-SSE1-LABEL: length16_eq:
615; X86-SSE1:       # BB#0:
616; X86-SSE1-NEXT:    pushl $0
617; X86-SSE1-NEXT:    pushl $16
618; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
619; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
620; X86-SSE1-NEXT:    calll memcmp
621; X86-SSE1-NEXT:    addl $16, %esp
622; X86-SSE1-NEXT:    testl %eax, %eax
623; X86-SSE1-NEXT:    setne %al
624; X86-SSE1-NEXT:    retl
625;
626; X86-SSE2-LABEL: length16_eq:
627; X86-SSE2:       # BB#0:
628; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
629; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
630; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
631; X86-SSE2-NEXT:    movdqu (%eax), %xmm1
632; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
633; X86-SSE2-NEXT:    pmovmskb %xmm1, %eax
634; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
635; X86-SSE2-NEXT:    setne %al
636; X86-SSE2-NEXT:    retl
637;
638; X64-SSE2-LABEL: length16_eq:
639; X64-SSE2:       # BB#0:
640; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
641; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
642; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
643; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
644; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
645; X64-SSE2-NEXT:    setne %al
646; X64-SSE2-NEXT:    retq
647;
648; X64-AVX-LABEL: length16_eq:
649; X64-AVX:       # BB#0:
650; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
651; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
652; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
653; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
654; X64-AVX-NEXT:    setne %al
655; X64-AVX-NEXT:    retq
656  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
657  %cmp = icmp ne i32 %call, 0
658  ret i1 %cmp
659}
660
661define i1 @length16_eq_const(i8* %X) nounwind {
662; X86-NOSSE-LABEL: length16_eq_const:
663; X86-NOSSE:       # BB#0:
664; X86-NOSSE-NEXT:    pushl $0
665; X86-NOSSE-NEXT:    pushl $16
666; X86-NOSSE-NEXT:    pushl $.L.str
667; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
668; X86-NOSSE-NEXT:    calll memcmp
669; X86-NOSSE-NEXT:    addl $16, %esp
670; X86-NOSSE-NEXT:    testl %eax, %eax
671; X86-NOSSE-NEXT:    sete %al
672; X86-NOSSE-NEXT:    retl
673;
674; X86-SSE1-LABEL: length16_eq_const:
675; X86-SSE1:       # BB#0:
676; X86-SSE1-NEXT:    pushl $0
677; X86-SSE1-NEXT:    pushl $16
678; X86-SSE1-NEXT:    pushl $.L.str
679; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
680; X86-SSE1-NEXT:    calll memcmp
681; X86-SSE1-NEXT:    addl $16, %esp
682; X86-SSE1-NEXT:    testl %eax, %eax
683; X86-SSE1-NEXT:    sete %al
684; X86-SSE1-NEXT:    retl
685;
686; X86-SSE2-LABEL: length16_eq_const:
687; X86-SSE2:       # BB#0:
688; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
689; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
690; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
691; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
692; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
693; X86-SSE2-NEXT:    sete %al
694; X86-SSE2-NEXT:    retl
695;
696; X64-SSE2-LABEL: length16_eq_const:
697; X64-SSE2:       # BB#0:
698; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
699; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
700; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
701; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
702; X64-SSE2-NEXT:    sete %al
703; X64-SSE2-NEXT:    retq
704;
705; X64-AVX-LABEL: length16_eq_const:
706; X64-AVX:       # BB#0:
707; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
708; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
709; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
710; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
711; X64-AVX-NEXT:    sete %al
712; X64-AVX-NEXT:    retq
713  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
714  %c = icmp eq i32 %m, 0
715  ret i1 %c
716}
717
718; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
719
720define i32 @length24(i8* %X, i8* %Y) nounwind {
721; X86-LABEL: length24:
722; X86:       # BB#0:
723; X86-NEXT:    pushl $0
724; X86-NEXT:    pushl $24
725; X86-NEXT:    pushl {{[0-9]+}}(%esp)
726; X86-NEXT:    pushl {{[0-9]+}}(%esp)
727; X86-NEXT:    calll memcmp
728; X86-NEXT:    addl $16, %esp
729; X86-NEXT:    retl
730;
731; X64-LABEL: length24:
732; X64:       # BB#0:
733; X64-NEXT:    movl $24, %edx
734; X64-NEXT:    jmp memcmp # TAILCALL
735  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
736  ret i32 %m
737}
738
739define i1 @length24_eq(i8* %x, i8* %y) nounwind {
740; X86-LABEL: length24_eq:
741; X86:       # BB#0:
742; X86-NEXT:    pushl $0
743; X86-NEXT:    pushl $24
744; X86-NEXT:    pushl {{[0-9]+}}(%esp)
745; X86-NEXT:    pushl {{[0-9]+}}(%esp)
746; X86-NEXT:    calll memcmp
747; X86-NEXT:    addl $16, %esp
748; X86-NEXT:    testl %eax, %eax
749; X86-NEXT:    sete %al
750; X86-NEXT:    retl
751;
752; X64-SSE2-LABEL: length24_eq:
753; X64-SSE2:       # BB#0:
754; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
755; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
756; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
757; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
758; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
759; X64-SSE2-NEXT:    jne .LBB22_2
760; X64-SSE2-NEXT:  # BB#1: # %loadbb1
761; X64-SSE2-NEXT:    movq 16(%rdi), %rcx
762; X64-SSE2-NEXT:    xorl %eax, %eax
763; X64-SSE2-NEXT:    cmpq 16(%rsi), %rcx
764; X64-SSE2-NEXT:    je .LBB22_3
765; X64-SSE2-NEXT:  .LBB22_2: # %res_block
766; X64-SSE2-NEXT:    movl $1, %eax
767; X64-SSE2-NEXT:  .LBB22_3: # %endblock
768; X64-SSE2-NEXT:    testl %eax, %eax
769; X64-SSE2-NEXT:    sete %al
770; X64-SSE2-NEXT:    retq
771;
772; X64-AVX-LABEL: length24_eq:
773; X64-AVX:       # BB#0:
774; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
775; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
776; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
777; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
778; X64-AVX-NEXT:    jne .LBB22_2
779; X64-AVX-NEXT:  # BB#1: # %loadbb1
780; X64-AVX-NEXT:    movq 16(%rdi), %rcx
781; X64-AVX-NEXT:    xorl %eax, %eax
782; X64-AVX-NEXT:    cmpq 16(%rsi), %rcx
783; X64-AVX-NEXT:    je .LBB22_3
784; X64-AVX-NEXT:  .LBB22_2: # %res_block
785; X64-AVX-NEXT:    movl $1, %eax
786; X64-AVX-NEXT:  .LBB22_3: # %endblock
787; X64-AVX-NEXT:    testl %eax, %eax
788; X64-AVX-NEXT:    sete %al
789; X64-AVX-NEXT:    retq
790  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
791  %cmp = icmp eq i32 %call, 0
792  ret i1 %cmp
793}
794
795define i1 @length24_eq_const(i8* %X) nounwind {
796; X86-LABEL: length24_eq_const:
797; X86:       # BB#0:
798; X86-NEXT:    pushl $0
799; X86-NEXT:    pushl $24
800; X86-NEXT:    pushl $.L.str
801; X86-NEXT:    pushl {{[0-9]+}}(%esp)
802; X86-NEXT:    calll memcmp
803; X86-NEXT:    addl $16, %esp
804; X86-NEXT:    testl %eax, %eax
805; X86-NEXT:    setne %al
806; X86-NEXT:    retl
807;
808; X64-SSE2-LABEL: length24_eq_const:
809; X64-SSE2:       # BB#0:
810; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
811; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
812; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
813; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
814; X64-SSE2-NEXT:    jne .LBB23_2
815; X64-SSE2-NEXT:  # BB#1: # %loadbb1
816; X64-SSE2-NEXT:    xorl %eax, %eax
817; X64-SSE2-NEXT:    movabsq $3689065127958034230, %rcx # imm = 0x3332313039383736
818; X64-SSE2-NEXT:    cmpq %rcx, 16(%rdi)
819; X64-SSE2-NEXT:    je .LBB23_3
820; X64-SSE2-NEXT:  .LBB23_2: # %res_block
821; X64-SSE2-NEXT:    movl $1, %eax
822; X64-SSE2-NEXT:  .LBB23_3: # %endblock
823; X64-SSE2-NEXT:    testl %eax, %eax
824; X64-SSE2-NEXT:    setne %al
825; X64-SSE2-NEXT:    retq
826;
827; X64-AVX-LABEL: length24_eq_const:
828; X64-AVX:       # BB#0:
829; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
830; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
831; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
832; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
833; X64-AVX-NEXT:    jne .LBB23_2
834; X64-AVX-NEXT:  # BB#1: # %loadbb1
835; X64-AVX-NEXT:    xorl %eax, %eax
836; X64-AVX-NEXT:    movabsq $3689065127958034230, %rcx # imm = 0x3332313039383736
837; X64-AVX-NEXT:    cmpq %rcx, 16(%rdi)
838; X64-AVX-NEXT:    je .LBB23_3
839; X64-AVX-NEXT:  .LBB23_2: # %res_block
840; X64-AVX-NEXT:    movl $1, %eax
841; X64-AVX-NEXT:  .LBB23_3: # %endblock
842; X64-AVX-NEXT:    testl %eax, %eax
843; X64-AVX-NEXT:    setne %al
844; X64-AVX-NEXT:    retq
845  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
846  %c = icmp ne i32 %m, 0
847  ret i1 %c
848}
849
850define i32 @length32(i8* %X, i8* %Y) nounwind {
851; X86-LABEL: length32:
852; X86:       # BB#0:
853; X86-NEXT:    pushl $0
854; X86-NEXT:    pushl $32
855; X86-NEXT:    pushl {{[0-9]+}}(%esp)
856; X86-NEXT:    pushl {{[0-9]+}}(%esp)
857; X86-NEXT:    calll memcmp
858; X86-NEXT:    addl $16, %esp
859; X86-NEXT:    retl
860;
861; X64-LABEL: length32:
862; X64:       # BB#0:
863; X64-NEXT:    movl $32, %edx
864; X64-NEXT:    jmp memcmp # TAILCALL
865  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
866  ret i32 %m
867}
868
869; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
870
871define i1 @length32_eq(i8* %x, i8* %y) nounwind {
872; X86-NOSSE-LABEL: length32_eq:
873; X86-NOSSE:       # BB#0:
874; X86-NOSSE-NEXT:    pushl $0
875; X86-NOSSE-NEXT:    pushl $32
876; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
877; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
878; X86-NOSSE-NEXT:    calll memcmp
879; X86-NOSSE-NEXT:    addl $16, %esp
880; X86-NOSSE-NEXT:    testl %eax, %eax
881; X86-NOSSE-NEXT:    sete %al
882; X86-NOSSE-NEXT:    retl
883;
884; X86-SSE1-LABEL: length32_eq:
885; X86-SSE1:       # BB#0:
886; X86-SSE1-NEXT:    pushl $0
887; X86-SSE1-NEXT:    pushl $32
888; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
889; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
890; X86-SSE1-NEXT:    calll memcmp
891; X86-SSE1-NEXT:    addl $16, %esp
892; X86-SSE1-NEXT:    testl %eax, %eax
893; X86-SSE1-NEXT:    sete %al
894; X86-SSE1-NEXT:    retl
895;
896; X86-SSE2-LABEL: length32_eq:
897; X86-SSE2:       # BB#0:
898; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
899; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
900; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
901; X86-SSE2-NEXT:    movdqu (%eax), %xmm1
902; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
903; X86-SSE2-NEXT:    pmovmskb %xmm1, %edx
904; X86-SSE2-NEXT:    cmpl $65535, %edx # imm = 0xFFFF
905; X86-SSE2-NEXT:    jne .LBB25_2
906; X86-SSE2-NEXT:  # BB#1: # %loadbb1
907; X86-SSE2-NEXT:    movdqu 16(%ecx), %xmm0
908; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm1
909; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
910; X86-SSE2-NEXT:    pmovmskb %xmm1, %ecx
911; X86-SSE2-NEXT:    xorl %eax, %eax
912; X86-SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
913; X86-SSE2-NEXT:    je .LBB25_3
914; X86-SSE2-NEXT:  .LBB25_2: # %res_block
915; X86-SSE2-NEXT:    movl $1, %eax
916; X86-SSE2-NEXT:  .LBB25_3: # %endblock
917; X86-SSE2-NEXT:    testl %eax, %eax
918; X86-SSE2-NEXT:    sete %al
919; X86-SSE2-NEXT:    retl
920;
921; X64-SSE2-LABEL: length32_eq:
922; X64-SSE2:       # BB#0:
923; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
924; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
925; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
926; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
927; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
928; X64-SSE2-NEXT:    jne .LBB25_2
929; X64-SSE2-NEXT:  # BB#1: # %loadbb1
930; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm0
931; X64-SSE2-NEXT:    movdqu 16(%rsi), %xmm1
932; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
933; X64-SSE2-NEXT:    pmovmskb %xmm1, %ecx
934; X64-SSE2-NEXT:    xorl %eax, %eax
935; X64-SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
936; X64-SSE2-NEXT:    je .LBB25_3
937; X64-SSE2-NEXT:  .LBB25_2: # %res_block
938; X64-SSE2-NEXT:    movl $1, %eax
939; X64-SSE2-NEXT:  .LBB25_3: # %endblock
940; X64-SSE2-NEXT:    testl %eax, %eax
941; X64-SSE2-NEXT:    sete %al
942; X64-SSE2-NEXT:    retq
943;
944; X64-AVX1-LABEL: length32_eq:
945; X64-AVX1:       # BB#0:
946; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
947; X64-AVX1-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
948; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
949; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
950; X64-AVX1-NEXT:    jne .LBB25_2
951; X64-AVX1-NEXT:  # BB#1: # %loadbb1
952; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm0
953; X64-AVX1-NEXT:    vpcmpeqb 16(%rsi), %xmm0, %xmm0
954; X64-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
955; X64-AVX1-NEXT:    xorl %eax, %eax
956; X64-AVX1-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
957; X64-AVX1-NEXT:    je .LBB25_3
958; X64-AVX1-NEXT:  .LBB25_2: # %res_block
959; X64-AVX1-NEXT:    movl $1, %eax
960; X64-AVX1-NEXT:  .LBB25_3: # %endblock
961; X64-AVX1-NEXT:    testl %eax, %eax
962; X64-AVX1-NEXT:    sete %al
963; X64-AVX1-NEXT:    retq
964;
965; X64-AVX2-LABEL: length32_eq:
966; X64-AVX2:       # BB#0:
967; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
968; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
969; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
970; X64-AVX2-NEXT:    cmpl $-1, %eax
971; X64-AVX2-NEXT:    sete %al
972; X64-AVX2-NEXT:    vzeroupper
973; X64-AVX2-NEXT:    retq
974  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
975  %cmp = icmp eq i32 %call, 0
976  ret i1 %cmp
977}
978
979define i1 @length32_eq_const(i8* %X) nounwind {
980; X86-NOSSE-LABEL: length32_eq_const:
981; X86-NOSSE:       # BB#0:
982; X86-NOSSE-NEXT:    pushl $0
983; X86-NOSSE-NEXT:    pushl $32
984; X86-NOSSE-NEXT:    pushl $.L.str
985; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
986; X86-NOSSE-NEXT:    calll memcmp
987; X86-NOSSE-NEXT:    addl $16, %esp
988; X86-NOSSE-NEXT:    testl %eax, %eax
989; X86-NOSSE-NEXT:    setne %al
990; X86-NOSSE-NEXT:    retl
991;
992; X86-SSE1-LABEL: length32_eq_const:
993; X86-SSE1:       # BB#0:
994; X86-SSE1-NEXT:    pushl $0
995; X86-SSE1-NEXT:    pushl $32
996; X86-SSE1-NEXT:    pushl $.L.str
997; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
998; X86-SSE1-NEXT:    calll memcmp
999; X86-SSE1-NEXT:    addl $16, %esp
1000; X86-SSE1-NEXT:    testl %eax, %eax
1001; X86-SSE1-NEXT:    setne %al
1002; X86-SSE1-NEXT:    retl
1003;
1004; X86-SSE2-LABEL: length32_eq_const:
1005; X86-SSE2:       # BB#0:
1006; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1007; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
1008; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
1009; X86-SSE2-NEXT:    pmovmskb %xmm0, %ecx
1010; X86-SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
1011; X86-SSE2-NEXT:    jne .LBB26_2
1012; X86-SSE2-NEXT:  # BB#1: # %loadbb1
1013; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm0
1014; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
1015; X86-SSE2-NEXT:    pmovmskb %xmm0, %ecx
1016; X86-SSE2-NEXT:    xorl %eax, %eax
1017; X86-SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
1018; X86-SSE2-NEXT:    je .LBB26_3
1019; X86-SSE2-NEXT:  .LBB26_2: # %res_block
1020; X86-SSE2-NEXT:    movl $1, %eax
1021; X86-SSE2-NEXT:  .LBB26_3: # %endblock
1022; X86-SSE2-NEXT:    testl %eax, %eax
1023; X86-SSE2-NEXT:    setne %al
1024; X86-SSE2-NEXT:    retl
1025;
1026; X64-SSE2-LABEL: length32_eq_const:
1027; X64-SSE2:       # BB#0:
1028; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
1029; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
1030; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
1031; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1032; X64-SSE2-NEXT:    jne .LBB26_2
1033; X64-SSE2-NEXT:  # BB#1: # %loadbb1
1034; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm0
1035; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
1036; X64-SSE2-NEXT:    pmovmskb %xmm0, %ecx
1037; X64-SSE2-NEXT:    xorl %eax, %eax
1038; X64-SSE2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
1039; X64-SSE2-NEXT:    je .LBB26_3
1040; X64-SSE2-NEXT:  .LBB26_2: # %res_block
1041; X64-SSE2-NEXT:    movl $1, %eax
1042; X64-SSE2-NEXT:  .LBB26_3: # %endblock
1043; X64-SSE2-NEXT:    testl %eax, %eax
1044; X64-SSE2-NEXT:    setne %al
1045; X64-SSE2-NEXT:    retq
1046;
1047; X64-AVX1-LABEL: length32_eq_const:
1048; X64-AVX1:       # BB#0:
1049; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
1050; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
1051; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
1052; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
1053; X64-AVX1-NEXT:    jne .LBB26_2
1054; X64-AVX1-NEXT:  # BB#1: # %loadbb1
1055; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm0
1056; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
1057; X64-AVX1-NEXT:    vpmovmskb %xmm0, %ecx
1058; X64-AVX1-NEXT:    xorl %eax, %eax
1059; X64-AVX1-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
1060; X64-AVX1-NEXT:    je .LBB26_3
1061; X64-AVX1-NEXT:  .LBB26_2: # %res_block
1062; X64-AVX1-NEXT:    movl $1, %eax
1063; X64-AVX1-NEXT:  .LBB26_3: # %endblock
1064; X64-AVX1-NEXT:    testl %eax, %eax
1065; X64-AVX1-NEXT:    setne %al
1066; X64-AVX1-NEXT:    retq
1067;
1068; X64-AVX2-LABEL: length32_eq_const:
1069; X64-AVX2:       # BB#0:
1070; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1071; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1072; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1073; X64-AVX2-NEXT:    cmpl $-1, %eax
1074; X64-AVX2-NEXT:    setne %al
1075; X64-AVX2-NEXT:    vzeroupper
1076; X64-AVX2-NEXT:    retq
1077  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
1078  %c = icmp ne i32 %m, 0
1079  ret i1 %c
1080}
1081
1082define i32 @length64(i8* %X, i8* %Y) nounwind {
1083; X86-LABEL: length64:
1084; X86:       # BB#0:
1085; X86-NEXT:    pushl $0
1086; X86-NEXT:    pushl $64
1087; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1088; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1089; X86-NEXT:    calll memcmp
1090; X86-NEXT:    addl $16, %esp
1091; X86-NEXT:    retl
1092;
1093; X64-LABEL: length64:
1094; X64:       # BB#0:
1095; X64-NEXT:    movl $64, %edx
1096; X64-NEXT:    jmp memcmp # TAILCALL
1097  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
1098  ret i32 %m
1099}
1100
1101define i1 @length64_eq(i8* %x, i8* %y) nounwind {
1102; X86-LABEL: length64_eq:
1103; X86:       # BB#0:
1104; X86-NEXT:    pushl $0
1105; X86-NEXT:    pushl $64
1106; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1107; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1108; X86-NEXT:    calll memcmp
1109; X86-NEXT:    addl $16, %esp
1110; X86-NEXT:    testl %eax, %eax
1111; X86-NEXT:    setne %al
1112; X86-NEXT:    retl
1113;
1114; X64-SSE2-LABEL: length64_eq:
1115; X64-SSE2:       # BB#0:
1116; X64-SSE2-NEXT:    pushq %rax
1117; X64-SSE2-NEXT:    movl $64, %edx
1118; X64-SSE2-NEXT:    callq memcmp
1119; X64-SSE2-NEXT:    testl %eax, %eax
1120; X64-SSE2-NEXT:    setne %al
1121; X64-SSE2-NEXT:    popq %rcx
1122; X64-SSE2-NEXT:    retq
1123;
1124; X64-AVX1-LABEL: length64_eq:
1125; X64-AVX1:       # BB#0:
1126; X64-AVX1-NEXT:    pushq %rax
1127; X64-AVX1-NEXT:    movl $64, %edx
1128; X64-AVX1-NEXT:    callq memcmp
1129; X64-AVX1-NEXT:    testl %eax, %eax
1130; X64-AVX1-NEXT:    setne %al
1131; X64-AVX1-NEXT:    popq %rcx
1132; X64-AVX1-NEXT:    retq
1133;
1134; X64-AVX2-LABEL: length64_eq:
1135; X64-AVX2:       # BB#0:
1136; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1137; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
1138; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1139; X64-AVX2-NEXT:    cmpl $-1, %eax
1140; X64-AVX2-NEXT:    jne .LBB28_2
1141; X64-AVX2-NEXT:  # BB#1: # %loadbb1
1142; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm0
1143; X64-AVX2-NEXT:    vpcmpeqb 32(%rsi), %ymm0, %ymm0
1144; X64-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
1145; X64-AVX2-NEXT:    xorl %eax, %eax
1146; X64-AVX2-NEXT:    cmpl $-1, %ecx
1147; X64-AVX2-NEXT:    je .LBB28_3
1148; X64-AVX2-NEXT:  .LBB28_2: # %res_block
1149; X64-AVX2-NEXT:    movl $1, %eax
1150; X64-AVX2-NEXT:  .LBB28_3: # %endblock
1151; X64-AVX2-NEXT:    testl %eax, %eax
1152; X64-AVX2-NEXT:    setne %al
1153; X64-AVX2-NEXT:    vzeroupper
1154; X64-AVX2-NEXT:    retq
1155  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
1156  %cmp = icmp ne i32 %call, 0
1157  ret i1 %cmp
1158}
1159
1160define i1 @length64_eq_const(i8* %X) nounwind {
1161; X86-LABEL: length64_eq_const:
1162; X86:       # BB#0:
1163; X86-NEXT:    pushl $0
1164; X86-NEXT:    pushl $64
1165; X86-NEXT:    pushl $.L.str
1166; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1167; X86-NEXT:    calll memcmp
1168; X86-NEXT:    addl $16, %esp
1169; X86-NEXT:    testl %eax, %eax
1170; X86-NEXT:    sete %al
1171; X86-NEXT:    retl
1172;
1173; X64-SSE2-LABEL: length64_eq_const:
1174; X64-SSE2:       # BB#0:
1175; X64-SSE2-NEXT:    pushq %rax
1176; X64-SSE2-NEXT:    movl $.L.str, %esi
1177; X64-SSE2-NEXT:    movl $64, %edx
1178; X64-SSE2-NEXT:    callq memcmp
1179; X64-SSE2-NEXT:    testl %eax, %eax
1180; X64-SSE2-NEXT:    sete %al
1181; X64-SSE2-NEXT:    popq %rcx
1182; X64-SSE2-NEXT:    retq
1183;
1184; X64-AVX1-LABEL: length64_eq_const:
1185; X64-AVX1:       # BB#0:
1186; X64-AVX1-NEXT:    pushq %rax
1187; X64-AVX1-NEXT:    movl $.L.str, %esi
1188; X64-AVX1-NEXT:    movl $64, %edx
1189; X64-AVX1-NEXT:    callq memcmp
1190; X64-AVX1-NEXT:    testl %eax, %eax
1191; X64-AVX1-NEXT:    sete %al
1192; X64-AVX1-NEXT:    popq %rcx
1193; X64-AVX1-NEXT:    retq
1194;
1195; X64-AVX2-LABEL: length64_eq_const:
1196; X64-AVX2:       # BB#0:
1197; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1198; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1199; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1200; X64-AVX2-NEXT:    cmpl $-1, %eax
1201; X64-AVX2-NEXT:    jne .LBB29_2
1202; X64-AVX2-NEXT:  # BB#1: # %loadbb1
1203; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm0
1204; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1205; X64-AVX2-NEXT:    vpmovmskb %ymm0, %ecx
1206; X64-AVX2-NEXT:    xorl %eax, %eax
1207; X64-AVX2-NEXT:    cmpl $-1, %ecx
1208; X64-AVX2-NEXT:    je .LBB29_3
1209; X64-AVX2-NEXT:  .LBB29_2: # %res_block
1210; X64-AVX2-NEXT:    movl $1, %eax
1211; X64-AVX2-NEXT:  .LBB29_3: # %endblock
1212; X64-AVX2-NEXT:    testl %eax, %eax
1213; X64-AVX2-NEXT:    sete %al
1214; X64-AVX2-NEXT:    vzeroupper
1215; X64-AVX2-NEXT:    retq
1216  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
1217  %c = icmp eq i32 %m, 0
1218  ret i1 %c
1219}
1220
1221; This checks that we do not do stupid things with huge sizes.
1222define i32 @huge_length(i8* %X, i8* %Y) nounwind {
1223; X86-LABEL: huge_length:
1224; X86:       # BB#0:
1225; X86-NEXT:    pushl $2147483647 # imm = 0x7FFFFFFF
1226; X86-NEXT:    pushl $-1
1227; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1228; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1229; X86-NEXT:    calll memcmp
1230; X86-NEXT:    addl $16, %esp
1231; X86-NEXT:    retl
1232;
1233; X64-LABEL: huge_length:
1234; X64:       # BB#0:
1235; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
1236; X64-NEXT:    jmp memcmp # TAILCALL
1237  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind
1238  ret i32 %m
1239}
1240
1241
1242