• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 i32 @length8(i8* %X, i8* %Y) nounwind {
363; X86-LABEL: length8:
364; X86:       # %bb.0:
365; X86-NEXT:    pushl %esi
366; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
367; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
368; X86-NEXT:    movl (%esi), %ecx
369; X86-NEXT:    movl (%eax), %edx
370; X86-NEXT:    bswapl %ecx
371; X86-NEXT:    bswapl %edx
372; X86-NEXT:    cmpl %edx, %ecx
373; X86-NEXT:    jne .LBB13_2
374; X86-NEXT:  # %bb.1: # %loadbb1
375; X86-NEXT:    movl 4(%esi), %ecx
376; X86-NEXT:    movl 4(%eax), %edx
377; X86-NEXT:    bswapl %ecx
378; X86-NEXT:    bswapl %edx
379; X86-NEXT:    xorl %eax, %eax
380; X86-NEXT:    cmpl %edx, %ecx
381; X86-NEXT:    je .LBB13_3
382; X86-NEXT:  .LBB13_2: # %res_block
383; X86-NEXT:    xorl %eax, %eax
384; X86-NEXT:    cmpl %edx, %ecx
385; X86-NEXT:    setae %al
386; X86-NEXT:    leal -1(%eax,%eax), %eax
387; X86-NEXT:  .LBB13_3: # %endblock
388; X86-NEXT:    popl %esi
389; X86-NEXT:    retl
390;
391; X64-LABEL: length8:
392; X64:       # %bb.0:
393; X64-NEXT:    movq (%rdi), %rcx
394; X64-NEXT:    movq (%rsi), %rdx
395; X64-NEXT:    bswapq %rcx
396; X64-NEXT:    bswapq %rdx
397; X64-NEXT:    xorl %eax, %eax
398; X64-NEXT:    cmpq %rdx, %rcx
399; X64-NEXT:    seta %al
400; X64-NEXT:    sbbl $0, %eax
401; X64-NEXT:    retq
402  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
403  ret i32 %m
404}
405
406define i1 @length8_eq(i8* %X, i8* %Y) nounwind {
407; X86-LABEL: length8_eq:
408; X86:       # %bb.0:
409; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
410; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
411; X86-NEXT:    movl (%ecx), %edx
412; X86-NEXT:    movl 4(%ecx), %ecx
413; X86-NEXT:    xorl (%eax), %edx
414; X86-NEXT:    xorl 4(%eax), %ecx
415; X86-NEXT:    orl %edx, %ecx
416; X86-NEXT:    sete %al
417; X86-NEXT:    retl
418;
419; X64-LABEL: length8_eq:
420; X64:       # %bb.0:
421; X64-NEXT:    movq (%rdi), %rax
422; X64-NEXT:    cmpq (%rsi), %rax
423; X64-NEXT:    sete %al
424; X64-NEXT:    retq
425  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
426  %c = icmp eq i32 %m, 0
427  ret i1 %c
428}
429
430define i1 @length8_eq_const(i8* %X) nounwind {
431; X86-LABEL: length8_eq_const:
432; X86:       # %bb.0:
433; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
434; X86-NEXT:    movl $858927408, %ecx # imm = 0x33323130
435; X86-NEXT:    xorl (%eax), %ecx
436; X86-NEXT:    movl $926299444, %edx # imm = 0x37363534
437; X86-NEXT:    xorl 4(%eax), %edx
438; X86-NEXT:    orl %ecx, %edx
439; X86-NEXT:    setne %al
440; X86-NEXT:    retl
441;
442; X64-LABEL: length8_eq_const:
443; X64:       # %bb.0:
444; X64-NEXT:    movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
445; X64-NEXT:    cmpq %rax, (%rdi)
446; X64-NEXT:    setne %al
447; X64-NEXT:    retq
448  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
449  %c = icmp ne i32 %m, 0
450  ret i1 %c
451}
452
453define i1 @length12_eq(i8* %X, i8* %Y) nounwind {
454; X86-LABEL: length12_eq:
455; X86:       # %bb.0:
456; X86-NEXT:    pushl $0
457; X86-NEXT:    pushl $12
458; X86-NEXT:    pushl {{[0-9]+}}(%esp)
459; X86-NEXT:    pushl {{[0-9]+}}(%esp)
460; X86-NEXT:    calll memcmp
461; X86-NEXT:    addl $16, %esp
462; X86-NEXT:    testl %eax, %eax
463; X86-NEXT:    setne %al
464; X86-NEXT:    retl
465;
466; X64-LABEL: length12_eq:
467; X64:       # %bb.0:
468; X64-NEXT:    movq (%rdi), %rax
469; X64-NEXT:    xorq (%rsi), %rax
470; X64-NEXT:    movl 8(%rdi), %ecx
471; X64-NEXT:    xorl 8(%rsi), %ecx
472; X64-NEXT:    orq %rax, %rcx
473; X64-NEXT:    setne %al
474; X64-NEXT:    retq
475  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
476  %c = icmp ne i32 %m, 0
477  ret i1 %c
478}
479
480define i32 @length12(i8* %X, i8* %Y) nounwind {
481; X86-LABEL: length12:
482; X86:       # %bb.0:
483; X86-NEXT:    pushl $0
484; X86-NEXT:    pushl $12
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:    retl
490;
491; X64-LABEL: length12:
492; X64:       # %bb.0:
493; X64-NEXT:    movq (%rdi), %rcx
494; X64-NEXT:    movq (%rsi), %rdx
495; X64-NEXT:    bswapq %rcx
496; X64-NEXT:    bswapq %rdx
497; X64-NEXT:    cmpq %rdx, %rcx
498; X64-NEXT:    jne .LBB17_2
499; X64-NEXT:  # %bb.1: # %loadbb1
500; X64-NEXT:    movl 8(%rdi), %ecx
501; X64-NEXT:    movl 8(%rsi), %edx
502; X64-NEXT:    bswapl %ecx
503; X64-NEXT:    bswapl %edx
504; X64-NEXT:    xorl %eax, %eax
505; X64-NEXT:    cmpq %rdx, %rcx
506; X64-NEXT:    je .LBB17_3
507; X64-NEXT:  .LBB17_2: # %res_block
508; X64-NEXT:    xorl %eax, %eax
509; X64-NEXT:    cmpq %rdx, %rcx
510; X64-NEXT:    setae %al
511; X64-NEXT:    leal -1(%rax,%rax), %eax
512; X64-NEXT:  .LBB17_3: # %endblock
513; X64-NEXT:    retq
514  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
515  ret i32 %m
516}
517
518; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
519
520define i32 @length16(i8* %X, i8* %Y) nounwind {
521; X86-LABEL: length16:
522; X86:       # %bb.0:
523; X86-NEXT:    pushl $0
524; X86-NEXT:    pushl $16
525; X86-NEXT:    pushl {{[0-9]+}}(%esp)
526; X86-NEXT:    pushl {{[0-9]+}}(%esp)
527; X86-NEXT:    calll memcmp
528; X86-NEXT:    addl $16, %esp
529; X86-NEXT:    retl
530;
531; X64-LABEL: length16:
532; X64:       # %bb.0:
533; X64-NEXT:    movq (%rdi), %rcx
534; X64-NEXT:    movq (%rsi), %rdx
535; X64-NEXT:    bswapq %rcx
536; X64-NEXT:    bswapq %rdx
537; X64-NEXT:    cmpq %rdx, %rcx
538; X64-NEXT:    jne .LBB18_2
539; X64-NEXT:  # %bb.1: # %loadbb1
540; X64-NEXT:    movq 8(%rdi), %rcx
541; X64-NEXT:    movq 8(%rsi), %rdx
542; X64-NEXT:    bswapq %rcx
543; X64-NEXT:    bswapq %rdx
544; X64-NEXT:    xorl %eax, %eax
545; X64-NEXT:    cmpq %rdx, %rcx
546; X64-NEXT:    je .LBB18_3
547; X64-NEXT:  .LBB18_2: # %res_block
548; X64-NEXT:    xorl %eax, %eax
549; X64-NEXT:    cmpq %rdx, %rcx
550; X64-NEXT:    setae %al
551; X64-NEXT:    leal -1(%rax,%rax), %eax
552; X64-NEXT:  .LBB18_3: # %endblock
553; X64-NEXT:    retq
554  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
555  ret i32 %m
556}
557
558define i1 @length16_eq(i8* %x, i8* %y) nounwind {
559; X86-NOSSE-LABEL: length16_eq:
560; X86-NOSSE:       # %bb.0:
561; X86-NOSSE-NEXT:    pushl $0
562; X86-NOSSE-NEXT:    pushl $16
563; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
564; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
565; X86-NOSSE-NEXT:    calll memcmp
566; X86-NOSSE-NEXT:    addl $16, %esp
567; X86-NOSSE-NEXT:    testl %eax, %eax
568; X86-NOSSE-NEXT:    setne %al
569; X86-NOSSE-NEXT:    retl
570;
571; X86-SSE1-LABEL: length16_eq:
572; X86-SSE1:       # %bb.0:
573; X86-SSE1-NEXT:    pushl $0
574; X86-SSE1-NEXT:    pushl $16
575; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
576; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
577; X86-SSE1-NEXT:    calll memcmp
578; X86-SSE1-NEXT:    addl $16, %esp
579; X86-SSE1-NEXT:    testl %eax, %eax
580; X86-SSE1-NEXT:    setne %al
581; X86-SSE1-NEXT:    retl
582;
583; X86-SSE2-LABEL: length16_eq:
584; X86-SSE2:       # %bb.0:
585; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
586; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
587; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
588; X86-SSE2-NEXT:    movdqu (%eax), %xmm1
589; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
590; X86-SSE2-NEXT:    pmovmskb %xmm1, %eax
591; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
592; X86-SSE2-NEXT:    setne %al
593; X86-SSE2-NEXT:    retl
594;
595; X64-SSE2-LABEL: length16_eq:
596; X64-SSE2:       # %bb.0:
597; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
598; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
599; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
600; X64-SSE2-NEXT:    pmovmskb %xmm1, %eax
601; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
602; X64-SSE2-NEXT:    setne %al
603; X64-SSE2-NEXT:    retq
604;
605; X64-AVX-LABEL: length16_eq:
606; X64-AVX:       # %bb.0:
607; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
608; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
609; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
610; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
611; X64-AVX-NEXT:    setne %al
612; X64-AVX-NEXT:    retq
613  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
614  %cmp = icmp ne i32 %call, 0
615  ret i1 %cmp
616}
617
618define i1 @length16_eq_const(i8* %X) nounwind {
619; X86-NOSSE-LABEL: length16_eq_const:
620; X86-NOSSE:       # %bb.0:
621; X86-NOSSE-NEXT:    pushl $0
622; X86-NOSSE-NEXT:    pushl $16
623; X86-NOSSE-NEXT:    pushl $.L.str
624; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
625; X86-NOSSE-NEXT:    calll memcmp
626; X86-NOSSE-NEXT:    addl $16, %esp
627; X86-NOSSE-NEXT:    testl %eax, %eax
628; X86-NOSSE-NEXT:    sete %al
629; X86-NOSSE-NEXT:    retl
630;
631; X86-SSE1-LABEL: length16_eq_const:
632; X86-SSE1:       # %bb.0:
633; X86-SSE1-NEXT:    pushl $0
634; X86-SSE1-NEXT:    pushl $16
635; X86-SSE1-NEXT:    pushl $.L.str
636; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
637; X86-SSE1-NEXT:    calll memcmp
638; X86-SSE1-NEXT:    addl $16, %esp
639; X86-SSE1-NEXT:    testl %eax, %eax
640; X86-SSE1-NEXT:    sete %al
641; X86-SSE1-NEXT:    retl
642;
643; X86-SSE2-LABEL: length16_eq_const:
644; X86-SSE2:       # %bb.0:
645; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
646; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
647; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
648; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
649; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
650; X86-SSE2-NEXT:    sete %al
651; X86-SSE2-NEXT:    retl
652;
653; X64-SSE2-LABEL: length16_eq_const:
654; X64-SSE2:       # %bb.0:
655; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
656; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
657; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
658; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
659; X64-SSE2-NEXT:    sete %al
660; X64-SSE2-NEXT:    retq
661;
662; X64-AVX-LABEL: length16_eq_const:
663; X64-AVX:       # %bb.0:
664; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
665; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
666; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
667; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
668; X64-AVX-NEXT:    sete %al
669; X64-AVX-NEXT:    retq
670  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
671  %c = icmp eq i32 %m, 0
672  ret i1 %c
673}
674
675; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
676
677define i32 @length24(i8* %X, i8* %Y) nounwind {
678; X86-LABEL: length24:
679; X86:       # %bb.0:
680; X86-NEXT:    pushl $0
681; X86-NEXT:    pushl $24
682; X86-NEXT:    pushl {{[0-9]+}}(%esp)
683; X86-NEXT:    pushl {{[0-9]+}}(%esp)
684; X86-NEXT:    calll memcmp
685; X86-NEXT:    addl $16, %esp
686; X86-NEXT:    retl
687;
688; X64-LABEL: length24:
689; X64:       # %bb.0:
690; X64-NEXT:    movl $24, %edx
691; X64-NEXT:    jmp memcmp # TAILCALL
692  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
693  ret i32 %m
694}
695
696define i1 @length24_eq(i8* %x, i8* %y) nounwind {
697; X86-LABEL: length24_eq:
698; X86:       # %bb.0:
699; X86-NEXT:    pushl $0
700; X86-NEXT:    pushl $24
701; X86-NEXT:    pushl {{[0-9]+}}(%esp)
702; X86-NEXT:    pushl {{[0-9]+}}(%esp)
703; X86-NEXT:    calll memcmp
704; X86-NEXT:    addl $16, %esp
705; X86-NEXT:    testl %eax, %eax
706; X86-NEXT:    sete %al
707; X86-NEXT:    retl
708;
709; X64-SSE2-LABEL: length24_eq:
710; X64-SSE2:       # %bb.0:
711; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
712; X64-SSE2-NEXT:    movdqu (%rsi), %xmm1
713; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm1
714; X64-SSE2-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
715; X64-SSE2-NEXT:    movq {{.*#+}} xmm2 = mem[0],zero
716; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
717; X64-SSE2-NEXT:    pand %xmm1, %xmm2
718; X64-SSE2-NEXT:    pmovmskb %xmm2, %eax
719; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
720; X64-SSE2-NEXT:    sete %al
721; X64-SSE2-NEXT:    retq
722;
723; X64-AVX-LABEL: length24_eq:
724; X64-AVX:       # %bb.0:
725; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
726; X64-AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
727; X64-AVX-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
728; X64-AVX-NEXT:    vpcmpeqb %xmm2, %xmm1, %xmm1
729; X64-AVX-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
730; X64-AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
731; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
732; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
733; X64-AVX-NEXT:    sete %al
734; X64-AVX-NEXT:    retq
735  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
736  %cmp = icmp eq i32 %call, 0
737  ret i1 %cmp
738}
739
740define i1 @length24_eq_const(i8* %X) nounwind {
741; X86-LABEL: length24_eq_const:
742; X86:       # %bb.0:
743; X86-NEXT:    pushl $0
744; X86-NEXT:    pushl $24
745; X86-NEXT:    pushl $.L.str
746; X86-NEXT:    pushl {{[0-9]+}}(%esp)
747; X86-NEXT:    calll memcmp
748; X86-NEXT:    addl $16, %esp
749; X86-NEXT:    testl %eax, %eax
750; X86-NEXT:    setne %al
751; X86-NEXT:    retl
752;
753; X64-SSE2-LABEL: length24_eq_const:
754; X64-SSE2:       # %bb.0:
755; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
756; X64-SSE2-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
757; X64-SSE2-NEXT:    movabsq $3689065127958034230, %rax # imm = 0x3332313039383736
758; X64-SSE2-NEXT:    movq %rax, %xmm2
759; X64-SSE2-NEXT:    pcmpeqb %xmm1, %xmm2
760; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
761; X64-SSE2-NEXT:    pand %xmm2, %xmm0
762; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
763; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
764; X64-SSE2-NEXT:    setne %al
765; X64-SSE2-NEXT:    retq
766;
767; X64-AVX-LABEL: length24_eq_const:
768; X64-AVX:       # %bb.0:
769; X64-AVX-NEXT:    vmovdqu (%rdi), %xmm0
770; X64-AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
771; X64-AVX-NEXT:    movabsq $3689065127958034230, %rax # imm = 0x3332313039383736
772; X64-AVX-NEXT:    vmovq %rax, %xmm2
773; X64-AVX-NEXT:    vpcmpeqb %xmm2, %xmm1, %xmm1
774; X64-AVX-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
775; X64-AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
776; X64-AVX-NEXT:    vpmovmskb %xmm0, %eax
777; X64-AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
778; X64-AVX-NEXT:    setne %al
779; X64-AVX-NEXT:    retq
780  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
781  %c = icmp ne i32 %m, 0
782  ret i1 %c
783}
784
785define i32 @length32(i8* %X, i8* %Y) nounwind {
786; X86-LABEL: length32:
787; X86:       # %bb.0:
788; X86-NEXT:    pushl $0
789; X86-NEXT:    pushl $32
790; X86-NEXT:    pushl {{[0-9]+}}(%esp)
791; X86-NEXT:    pushl {{[0-9]+}}(%esp)
792; X86-NEXT:    calll memcmp
793; X86-NEXT:    addl $16, %esp
794; X86-NEXT:    retl
795;
796; X64-LABEL: length32:
797; X64:       # %bb.0:
798; X64-NEXT:    movl $32, %edx
799; X64-NEXT:    jmp memcmp # TAILCALL
800  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
801  ret i32 %m
802}
803
804; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
805
806define i1 @length32_eq(i8* %x, i8* %y) nounwind {
807; X86-NOSSE-LABEL: length32_eq:
808; X86-NOSSE:       # %bb.0:
809; X86-NOSSE-NEXT:    pushl $0
810; X86-NOSSE-NEXT:    pushl $32
811; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
812; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
813; X86-NOSSE-NEXT:    calll memcmp
814; X86-NOSSE-NEXT:    addl $16, %esp
815; X86-NOSSE-NEXT:    testl %eax, %eax
816; X86-NOSSE-NEXT:    sete %al
817; X86-NOSSE-NEXT:    retl
818;
819; X86-SSE1-LABEL: length32_eq:
820; X86-SSE1:       # %bb.0:
821; X86-SSE1-NEXT:    pushl $0
822; X86-SSE1-NEXT:    pushl $32
823; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
824; X86-SSE1-NEXT:    pushl {{[0-9]+}}(%esp)
825; X86-SSE1-NEXT:    calll memcmp
826; X86-SSE1-NEXT:    addl $16, %esp
827; X86-SSE1-NEXT:    testl %eax, %eax
828; X86-SSE1-NEXT:    sete %al
829; X86-SSE1-NEXT:    retl
830;
831; X86-SSE2-LABEL: length32_eq:
832; X86-SSE2:       # %bb.0:
833; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
834; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
835; X86-SSE2-NEXT:    movdqu (%ecx), %xmm0
836; X86-SSE2-NEXT:    movdqu 16(%ecx), %xmm1
837; X86-SSE2-NEXT:    movdqu (%eax), %xmm2
838; X86-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
839; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm0
840; X86-SSE2-NEXT:    pcmpeqb %xmm1, %xmm0
841; X86-SSE2-NEXT:    pand %xmm2, %xmm0
842; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
843; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
844; X86-SSE2-NEXT:    sete %al
845; X86-SSE2-NEXT:    retl
846;
847; X64-SSE2-LABEL: length32_eq:
848; X64-SSE2:       # %bb.0:
849; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
850; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm1
851; X64-SSE2-NEXT:    movdqu (%rsi), %xmm2
852; X64-SSE2-NEXT:    pcmpeqb %xmm0, %xmm2
853; X64-SSE2-NEXT:    movdqu 16(%rsi), %xmm0
854; X64-SSE2-NEXT:    pcmpeqb %xmm1, %xmm0
855; X64-SSE2-NEXT:    pand %xmm2, %xmm0
856; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
857; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
858; X64-SSE2-NEXT:    sete %al
859; X64-SSE2-NEXT:    retq
860;
861; X64-AVX1-LABEL: length32_eq:
862; X64-AVX1:       # %bb.0:
863; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
864; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm1
865; X64-AVX1-NEXT:    vpcmpeqb 16(%rsi), %xmm1, %xmm1
866; X64-AVX1-NEXT:    vpcmpeqb (%rsi), %xmm0, %xmm0
867; X64-AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
868; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
869; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
870; X64-AVX1-NEXT:    sete %al
871; X64-AVX1-NEXT:    retq
872;
873; X64-AVX2-LABEL: length32_eq:
874; X64-AVX2:       # %bb.0:
875; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
876; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
877; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
878; X64-AVX2-NEXT:    cmpl $-1, %eax
879; X64-AVX2-NEXT:    sete %al
880; X64-AVX2-NEXT:    vzeroupper
881; X64-AVX2-NEXT:    retq
882  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
883  %cmp = icmp eq i32 %call, 0
884  ret i1 %cmp
885}
886
887define i1 @length32_eq_const(i8* %X) nounwind {
888; X86-NOSSE-LABEL: length32_eq_const:
889; X86-NOSSE:       # %bb.0:
890; X86-NOSSE-NEXT:    pushl $0
891; X86-NOSSE-NEXT:    pushl $32
892; X86-NOSSE-NEXT:    pushl $.L.str
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:    setne %al
898; X86-NOSSE-NEXT:    retl
899;
900; X86-SSE1-LABEL: length32_eq_const:
901; X86-SSE1:       # %bb.0:
902; X86-SSE1-NEXT:    pushl $0
903; X86-SSE1-NEXT:    pushl $32
904; X86-SSE1-NEXT:    pushl $.L.str
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:    setne %al
910; X86-SSE1-NEXT:    retl
911;
912; X86-SSE2-LABEL: length32_eq_const:
913; X86-SSE2:       # %bb.0:
914; X86-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
915; X86-SSE2-NEXT:    movdqu (%eax), %xmm0
916; X86-SSE2-NEXT:    movdqu 16(%eax), %xmm1
917; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm1
918; X86-SSE2-NEXT:    pcmpeqb {{\.LCPI.*}}, %xmm0
919; X86-SSE2-NEXT:    pand %xmm1, %xmm0
920; X86-SSE2-NEXT:    pmovmskb %xmm0, %eax
921; X86-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
922; X86-SSE2-NEXT:    setne %al
923; X86-SSE2-NEXT:    retl
924;
925; X64-SSE2-LABEL: length32_eq_const:
926; X64-SSE2:       # %bb.0:
927; X64-SSE2-NEXT:    movdqu (%rdi), %xmm0
928; X64-SSE2-NEXT:    movdqu 16(%rdi), %xmm1
929; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm1
930; X64-SSE2-NEXT:    pcmpeqb {{.*}}(%rip), %xmm0
931; X64-SSE2-NEXT:    pand %xmm1, %xmm0
932; X64-SSE2-NEXT:    pmovmskb %xmm0, %eax
933; X64-SSE2-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
934; X64-SSE2-NEXT:    setne %al
935; X64-SSE2-NEXT:    retq
936;
937; X64-AVX1-LABEL: length32_eq_const:
938; X64-AVX1:       # %bb.0:
939; X64-AVX1-NEXT:    vmovdqu (%rdi), %xmm0
940; X64-AVX1-NEXT:    vmovdqu 16(%rdi), %xmm1
941; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm1, %xmm1
942; X64-AVX1-NEXT:    vpcmpeqb {{.*}}(%rip), %xmm0, %xmm0
943; X64-AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
944; X64-AVX1-NEXT:    vpmovmskb %xmm0, %eax
945; X64-AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
946; X64-AVX1-NEXT:    setne %al
947; X64-AVX1-NEXT:    retq
948;
949; X64-AVX2-LABEL: length32_eq_const:
950; X64-AVX2:       # %bb.0:
951; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
952; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
953; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
954; X64-AVX2-NEXT:    cmpl $-1, %eax
955; X64-AVX2-NEXT:    setne %al
956; X64-AVX2-NEXT:    vzeroupper
957; X64-AVX2-NEXT:    retq
958  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
959  %c = icmp ne i32 %m, 0
960  ret i1 %c
961}
962
963define i32 @length64(i8* %X, i8* %Y) nounwind {
964; X86-LABEL: length64:
965; X86:       # %bb.0:
966; X86-NEXT:    pushl $0
967; X86-NEXT:    pushl $64
968; X86-NEXT:    pushl {{[0-9]+}}(%esp)
969; X86-NEXT:    pushl {{[0-9]+}}(%esp)
970; X86-NEXT:    calll memcmp
971; X86-NEXT:    addl $16, %esp
972; X86-NEXT:    retl
973;
974; X64-LABEL: length64:
975; X64:       # %bb.0:
976; X64-NEXT:    movl $64, %edx
977; X64-NEXT:    jmp memcmp # TAILCALL
978  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
979  ret i32 %m
980}
981
982define i1 @length64_eq(i8* %x, i8* %y) nounwind {
983; X86-LABEL: length64_eq:
984; X86:       # %bb.0:
985; X86-NEXT:    pushl $0
986; X86-NEXT:    pushl $64
987; X86-NEXT:    pushl {{[0-9]+}}(%esp)
988; X86-NEXT:    pushl {{[0-9]+}}(%esp)
989; X86-NEXT:    calll memcmp
990; X86-NEXT:    addl $16, %esp
991; X86-NEXT:    testl %eax, %eax
992; X86-NEXT:    setne %al
993; X86-NEXT:    retl
994;
995; X64-SSE2-LABEL: length64_eq:
996; X64-SSE2:       # %bb.0:
997; X64-SSE2-NEXT:    pushq %rax
998; X64-SSE2-NEXT:    movl $64, %edx
999; X64-SSE2-NEXT:    callq memcmp
1000; X64-SSE2-NEXT:    testl %eax, %eax
1001; X64-SSE2-NEXT:    setne %al
1002; X64-SSE2-NEXT:    popq %rcx
1003; X64-SSE2-NEXT:    retq
1004;
1005; X64-AVX1-LABEL: length64_eq:
1006; X64-AVX1:       # %bb.0:
1007; X64-AVX1-NEXT:    pushq %rax
1008; X64-AVX1-NEXT:    movl $64, %edx
1009; X64-AVX1-NEXT:    callq memcmp
1010; X64-AVX1-NEXT:    testl %eax, %eax
1011; X64-AVX1-NEXT:    setne %al
1012; X64-AVX1-NEXT:    popq %rcx
1013; X64-AVX1-NEXT:    retq
1014;
1015; X64-AVX2-LABEL: length64_eq:
1016; X64-AVX2:       # %bb.0:
1017; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1018; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm1
1019; X64-AVX2-NEXT:    vpcmpeqb 32(%rsi), %ymm1, %ymm1
1020; X64-AVX2-NEXT:    vpcmpeqb (%rsi), %ymm0, %ymm0
1021; X64-AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
1022; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1023; X64-AVX2-NEXT:    cmpl $-1, %eax
1024; X64-AVX2-NEXT:    setne %al
1025; X64-AVX2-NEXT:    vzeroupper
1026; X64-AVX2-NEXT:    retq
1027  %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
1028  %cmp = icmp ne i32 %call, 0
1029  ret i1 %cmp
1030}
1031
1032define i1 @length64_eq_const(i8* %X) nounwind {
1033; X86-LABEL: length64_eq_const:
1034; X86:       # %bb.0:
1035; X86-NEXT:    pushl $0
1036; X86-NEXT:    pushl $64
1037; X86-NEXT:    pushl $.L.str
1038; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1039; X86-NEXT:    calll memcmp
1040; X86-NEXT:    addl $16, %esp
1041; X86-NEXT:    testl %eax, %eax
1042; X86-NEXT:    sete %al
1043; X86-NEXT:    retl
1044;
1045; X64-SSE2-LABEL: length64_eq_const:
1046; X64-SSE2:       # %bb.0:
1047; X64-SSE2-NEXT:    pushq %rax
1048; X64-SSE2-NEXT:    movl $.L.str, %esi
1049; X64-SSE2-NEXT:    movl $64, %edx
1050; X64-SSE2-NEXT:    callq memcmp
1051; X64-SSE2-NEXT:    testl %eax, %eax
1052; X64-SSE2-NEXT:    sete %al
1053; X64-SSE2-NEXT:    popq %rcx
1054; X64-SSE2-NEXT:    retq
1055;
1056; X64-AVX1-LABEL: length64_eq_const:
1057; X64-AVX1:       # %bb.0:
1058; X64-AVX1-NEXT:    pushq %rax
1059; X64-AVX1-NEXT:    movl $.L.str, %esi
1060; X64-AVX1-NEXT:    movl $64, %edx
1061; X64-AVX1-NEXT:    callq memcmp
1062; X64-AVX1-NEXT:    testl %eax, %eax
1063; X64-AVX1-NEXT:    sete %al
1064; X64-AVX1-NEXT:    popq %rcx
1065; X64-AVX1-NEXT:    retq
1066;
1067; X64-AVX2-LABEL: length64_eq_const:
1068; X64-AVX2:       # %bb.0:
1069; X64-AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1070; X64-AVX2-NEXT:    vmovdqu 32(%rdi), %ymm1
1071; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm1, %ymm1
1072; X64-AVX2-NEXT:    vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
1073; X64-AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
1074; X64-AVX2-NEXT:    vpmovmskb %ymm0, %eax
1075; X64-AVX2-NEXT:    cmpl $-1, %eax
1076; X64-AVX2-NEXT:    sete %al
1077; X64-AVX2-NEXT:    vzeroupper
1078; X64-AVX2-NEXT:    retq
1079  %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
1080  %c = icmp eq i32 %m, 0
1081  ret i1 %c
1082}
1083
1084; This checks that we do not do stupid things with huge sizes.
1085define i32 @huge_length(i8* %X, i8* %Y) nounwind {
1086; X86-LABEL: huge_length:
1087; X86:       # %bb.0:
1088; X86-NEXT:    pushl $2147483647 # imm = 0x7FFFFFFF
1089; X86-NEXT:    pushl $-1
1090; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1091; X86-NEXT:    pushl {{[0-9]+}}(%esp)
1092; X86-NEXT:    calll memcmp
1093; X86-NEXT:    addl $16, %esp
1094; X86-NEXT:    retl
1095;
1096; X64-LABEL: huge_length:
1097; X64:       # %bb.0:
1098; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
1099; X64-NEXT:    jmp memcmp # TAILCALL
1100  %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 9223372036854775807) nounwind
1101  ret i32 %m
1102}
1103
1104
1105