blob: 4a5f30890513ea7d25f3928dae0421d591a8dbba [file] [log] [blame]
Simon Pilgrimc2cbb522017-07-18 14:26:07 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=cmov | FileCheck %s --check-prefix=X86 --check-prefix=X86-NOSSE
3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE2
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 --check-prefix=X64-SSE2
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx2 | FileCheck %s --check-prefix=X64 --check-prefix=X64-AVX2
6
7; This tests codegen time inlining/optimization of memcmp
8; rdar://6480398
9
10@.str = private constant [65 x i8] c"0123456789012345678901234567890123456789012345678901234567890123\00", align 1
11
12declare i32 @memcmp(i8*, i8*, i64)
13
14define i32 @length2(i8* %X, i8* %Y) nounwind optsize {
15; X86-LABEL: length2:
16; X86: # BB#0:
17; X86-NEXT: pushl %edi
18; X86-NEXT: pushl %esi
19; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
20; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
21; X86-NEXT: movzwl (%ecx), %ecx
22; X86-NEXT: movzwl (%eax), %edx
23; X86-NEXT: rolw $8, %cx
24; X86-NEXT: rolw $8, %dx
25; X86-NEXT: xorl %esi, %esi
26; X86-NEXT: xorl %edi, %edi
27; X86-NEXT: incl %edi
28; X86-NEXT: xorl %eax, %eax
29; X86-NEXT: decl %eax
30; X86-NEXT: cmpw %dx, %cx
31; X86-NEXT: cmovael %edi, %eax
32; X86-NEXT: cmovel %esi, %eax
33; X86-NEXT: popl %esi
34; X86-NEXT: popl %edi
35; X86-NEXT: retl
36;
37; X64-LABEL: length2:
38; X64: # BB#0:
39; X64-NEXT: movzwl (%rdi), %eax
40; X64-NEXT: movzwl (%rsi), %ecx
41; X64-NEXT: rolw $8, %ax
42; X64-NEXT: rolw $8, %cx
43; X64-NEXT: xorl %edx, %edx
44; X64-NEXT: cmpw %cx, %ax
45; X64-NEXT: movl $-1, %ecx
46; X64-NEXT: movl $1, %eax
47; X64-NEXT: cmovbl %ecx, %eax
48; X64-NEXT: cmovel %edx, %eax
49; X64-NEXT: retq
50 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
51 ret i32 %m
52}
53
54define i1 @length2_eq(i8* %X, i8* %Y) nounwind optsize {
55; X86-LABEL: length2_eq:
56; X86: # BB#0:
57; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
58; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
59; X86-NEXT: movzwl (%ecx), %ecx
60; X86-NEXT: cmpw (%eax), %cx
61; X86-NEXT: sete %al
62; X86-NEXT: retl
63;
64; X64-LABEL: length2_eq:
65; X64: # BB#0:
66; X64-NEXT: movzwl (%rdi), %eax
67; X64-NEXT: cmpw (%rsi), %ax
68; X64-NEXT: sete %al
69; X64-NEXT: retq
70 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
71 %c = icmp eq i32 %m, 0
72 ret i1 %c
73}
74
75define i1 @length2_eq_const(i8* %X) nounwind optsize {
76; X86-LABEL: length2_eq_const:
77; X86: # BB#0:
78; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
79; X86-NEXT: movzwl (%eax), %eax
80; X86-NEXT: cmpl $12849, %eax # imm = 0x3231
81; X86-NEXT: setne %al
82; X86-NEXT: retl
83;
84; X64-LABEL: length2_eq_const:
85; X64: # BB#0:
86; X64-NEXT: movzwl (%rdi), %eax
87; X64-NEXT: cmpl $12849, %eax # imm = 0x3231
88; X64-NEXT: setne %al
89; X64-NEXT: retq
90 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind
91 %c = icmp ne i32 %m, 0
92 ret i1 %c
93}
94
95define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind optsize {
96; X86-LABEL: length2_eq_nobuiltin_attr:
97; X86: # BB#0:
98; X86-NEXT: pushl $0
99; X86-NEXT: pushl $2
100; X86-NEXT: pushl {{[0-9]+}}(%esp)
101; X86-NEXT: pushl {{[0-9]+}}(%esp)
102; X86-NEXT: calll memcmp
103; X86-NEXT: addl $16, %esp
104; X86-NEXT: testl %eax, %eax
105; X86-NEXT: sete %al
106; X86-NEXT: retl
107;
108; X64-LABEL: length2_eq_nobuiltin_attr:
109; X64: # BB#0:
110; X64-NEXT: pushq %rax
111; X64-NEXT: movl $2, %edx
112; X64-NEXT: callq memcmp
113; X64-NEXT: testl %eax, %eax
114; X64-NEXT: sete %al
115; X64-NEXT: popq %rcx
116; X64-NEXT: retq
117 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin
118 %c = icmp eq i32 %m, 0
119 ret i1 %c
120}
121
122define i32 @length3(i8* %X, i8* %Y) nounwind optsize {
123; X86-LABEL: length3:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000124; X86: # BB#0: # %loadbb
125; X86-NEXT: pushl %esi
126; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
127; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
128; X86-NEXT: movzwl (%eax), %edx
129; X86-NEXT: movzwl (%ecx), %esi
130; X86-NEXT: rolw $8, %dx
131; X86-NEXT: rolw $8, %si
132; X86-NEXT: movzwl %dx, %edx
133; X86-NEXT: movzwl %si, %esi
134; X86-NEXT: cmpl %esi, %edx
135; X86-NEXT: jne .LBB4_1
136; X86-NEXT: # BB#2: # %loadbb1
137; X86-NEXT: movzbl 2(%eax), %eax
138; X86-NEXT: movzbl 2(%ecx), %ecx
139; X86-NEXT: subl %ecx, %eax
140; X86-NEXT: jmp .LBB4_3
141; X86-NEXT: .LBB4_1: # %res_block
142; X86-NEXT: xorl %ecx, %ecx
143; X86-NEXT: incl %ecx
144; X86-NEXT: xorl %eax, %eax
145; X86-NEXT: decl %eax
146; X86-NEXT: cmpl %esi, %edx
147; X86-NEXT: cmovael %ecx, %eax
148; X86-NEXT: .LBB4_3: # %endblock
149; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000150; X86-NEXT: retl
151;
152; X64-LABEL: length3:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000153; X64: # BB#0: # %loadbb
154; X64-NEXT: movzwl (%rdi), %eax
155; X64-NEXT: movzwl (%rsi), %ecx
156; X64-NEXT: rolw $8, %ax
157; X64-NEXT: rolw $8, %cx
158; X64-NEXT: movzwl %ax, %eax
159; X64-NEXT: movzwl %cx, %ecx
160; X64-NEXT: cmpq %rcx, %rax
161; X64-NEXT: jne .LBB4_1
162; X64-NEXT: # BB#2: # %loadbb1
163; X64-NEXT: movzbl 2(%rdi), %eax
164; X64-NEXT: movzbl 2(%rsi), %ecx
165; X64-NEXT: subl %ecx, %eax
166; X64-NEXT: retq
167; X64-NEXT: .LBB4_1: # %res_block
168; X64-NEXT: movl $-1, %ecx
169; X64-NEXT: movl $1, %eax
170; X64-NEXT: cmovbl %ecx, %eax
171; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000172 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
173 ret i32 %m
174}
175
176define i1 @length3_eq(i8* %X, i8* %Y) nounwind optsize {
177; X86-LABEL: length3_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000178; X86: # BB#0: # %loadbb
179; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
180; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
181; X86-NEXT: movzwl (%eax), %edx
182; X86-NEXT: cmpw (%ecx), %dx
183; X86-NEXT: jne .LBB5_1
184; X86-NEXT: # BB#2: # %loadbb1
185; X86-NEXT: movb 2(%eax), %dl
186; X86-NEXT: xorl %eax, %eax
187; X86-NEXT: cmpb 2(%ecx), %dl
188; X86-NEXT: je .LBB5_3
189; X86-NEXT: .LBB5_1: # %res_block
190; X86-NEXT: xorl %eax, %eax
191; X86-NEXT: incl %eax
192; X86-NEXT: .LBB5_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000193; X86-NEXT: testl %eax, %eax
194; X86-NEXT: setne %al
195; X86-NEXT: retl
196;
197; X64-LABEL: length3_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000198; X64: # BB#0: # %loadbb
199; X64-NEXT: movzwl (%rdi), %eax
200; X64-NEXT: cmpw (%rsi), %ax
201; X64-NEXT: jne .LBB5_1
202; X64-NEXT: # BB#2: # %loadbb1
203; X64-NEXT: movb 2(%rdi), %cl
204; X64-NEXT: xorl %eax, %eax
205; X64-NEXT: cmpb 2(%rsi), %cl
206; X64-NEXT: je .LBB5_3
207; X64-NEXT: .LBB5_1: # %res_block
208; X64-NEXT: movl $1, %eax
209; X64-NEXT: .LBB5_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000210; X64-NEXT: testl %eax, %eax
211; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000212; X64-NEXT: retq
213 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
214 %c = icmp ne i32 %m, 0
215 ret i1 %c
216}
217
218define i32 @length4(i8* %X, i8* %Y) nounwind optsize {
219; X86-LABEL: length4:
220; X86: # BB#0:
221; X86-NEXT: pushl %edi
222; X86-NEXT: pushl %esi
223; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
224; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
225; X86-NEXT: movl (%ecx), %ecx
226; X86-NEXT: movl (%eax), %edx
227; X86-NEXT: bswapl %ecx
228; X86-NEXT: bswapl %edx
229; X86-NEXT: xorl %esi, %esi
230; X86-NEXT: xorl %edi, %edi
231; X86-NEXT: incl %edi
232; X86-NEXT: xorl %eax, %eax
233; X86-NEXT: decl %eax
234; X86-NEXT: cmpl %edx, %ecx
235; X86-NEXT: cmovael %edi, %eax
236; X86-NEXT: cmovel %esi, %eax
237; X86-NEXT: popl %esi
238; X86-NEXT: popl %edi
239; X86-NEXT: retl
240;
241; X64-LABEL: length4:
242; X64: # BB#0:
243; X64-NEXT: movl (%rdi), %eax
244; X64-NEXT: movl (%rsi), %ecx
245; X64-NEXT: bswapl %eax
246; X64-NEXT: bswapl %ecx
247; X64-NEXT: xorl %edx, %edx
248; X64-NEXT: cmpl %ecx, %eax
249; X64-NEXT: movl $-1, %ecx
250; X64-NEXT: movl $1, %eax
251; X64-NEXT: cmovbl %ecx, %eax
252; X64-NEXT: cmovel %edx, %eax
253; X64-NEXT: retq
254 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
255 ret i32 %m
256}
257
258define i1 @length4_eq(i8* %X, i8* %Y) nounwind optsize {
259; X86-LABEL: length4_eq:
260; X86: # BB#0:
261; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
262; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
263; X86-NEXT: movl (%ecx), %ecx
264; X86-NEXT: cmpl (%eax), %ecx
265; X86-NEXT: setne %al
266; X86-NEXT: retl
267;
268; X64-LABEL: length4_eq:
269; X64: # BB#0:
270; X64-NEXT: movl (%rdi), %eax
271; X64-NEXT: cmpl (%rsi), %eax
272; X64-NEXT: setne %al
273; X64-NEXT: retq
274 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
275 %c = icmp ne i32 %m, 0
276 ret i1 %c
277}
278
279define i1 @length4_eq_const(i8* %X) nounwind optsize {
280; X86-LABEL: length4_eq_const:
281; X86: # BB#0:
282; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
283; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231
284; X86-NEXT: sete %al
285; X86-NEXT: retl
286;
287; X64-LABEL: length4_eq_const:
288; X64: # BB#0:
289; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231
290; X64-NEXT: sete %al
291; X64-NEXT: retq
292 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
293 %c = icmp eq i32 %m, 0
294 ret i1 %c
295}
296
297define i32 @length5(i8* %X, i8* %Y) nounwind optsize {
298; X86-LABEL: length5:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000299; X86: # BB#0: # %loadbb
300; X86-NEXT: pushl %esi
301; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
302; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
303; X86-NEXT: movl (%eax), %edx
304; X86-NEXT: movl (%ecx), %esi
305; X86-NEXT: bswapl %edx
306; X86-NEXT: bswapl %esi
307; X86-NEXT: cmpl %esi, %edx
308; X86-NEXT: jne .LBB9_1
309; X86-NEXT: # BB#2: # %loadbb1
310; X86-NEXT: movzbl 4(%eax), %eax
311; X86-NEXT: movzbl 4(%ecx), %ecx
312; X86-NEXT: subl %ecx, %eax
313; X86-NEXT: jmp .LBB9_3
314; X86-NEXT: .LBB9_1: # %res_block
315; X86-NEXT: xorl %ecx, %ecx
316; X86-NEXT: incl %ecx
317; X86-NEXT: xorl %eax, %eax
318; X86-NEXT: decl %eax
319; X86-NEXT: cmpl %esi, %edx
320; X86-NEXT: cmovael %ecx, %eax
321; X86-NEXT: .LBB9_3: # %endblock
322; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000323; X86-NEXT: retl
324;
325; X64-LABEL: length5:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000326; X64: # BB#0: # %loadbb
327; X64-NEXT: movl (%rdi), %eax
328; X64-NEXT: movl (%rsi), %ecx
329; X64-NEXT: bswapl %eax
330; X64-NEXT: bswapl %ecx
331; X64-NEXT: cmpq %rcx, %rax
332; X64-NEXT: jne .LBB9_1
333; X64-NEXT: # BB#2: # %loadbb1
334; X64-NEXT: movzbl 4(%rdi), %eax
335; X64-NEXT: movzbl 4(%rsi), %ecx
336; X64-NEXT: subl %ecx, %eax
337; X64-NEXT: retq
338; X64-NEXT: .LBB9_1: # %res_block
339; X64-NEXT: movl $-1, %ecx
340; X64-NEXT: movl $1, %eax
341; X64-NEXT: cmovbl %ecx, %eax
342; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000343 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
344 ret i32 %m
345}
346
347define i1 @length5_eq(i8* %X, i8* %Y) nounwind optsize {
348; X86-LABEL: length5_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000349; X86: # BB#0: # %loadbb
350; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
351; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
352; X86-NEXT: movl (%eax), %edx
353; X86-NEXT: cmpl (%ecx), %edx
354; X86-NEXT: jne .LBB10_1
355; X86-NEXT: # BB#2: # %loadbb1
356; X86-NEXT: movb 4(%eax), %dl
357; X86-NEXT: xorl %eax, %eax
358; X86-NEXT: cmpb 4(%ecx), %dl
359; X86-NEXT: je .LBB10_3
360; X86-NEXT: .LBB10_1: # %res_block
361; X86-NEXT: xorl %eax, %eax
362; X86-NEXT: incl %eax
363; X86-NEXT: .LBB10_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000364; X86-NEXT: testl %eax, %eax
365; X86-NEXT: setne %al
366; X86-NEXT: retl
367;
368; X64-LABEL: length5_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000369; X64: # BB#0: # %loadbb
370; X64-NEXT: movl (%rdi), %eax
371; X64-NEXT: cmpl (%rsi), %eax
372; X64-NEXT: jne .LBB10_1
373; X64-NEXT: # BB#2: # %loadbb1
374; X64-NEXT: movb 4(%rdi), %cl
375; X64-NEXT: xorl %eax, %eax
376; X64-NEXT: cmpb 4(%rsi), %cl
377; X64-NEXT: je .LBB10_3
378; X64-NEXT: .LBB10_1: # %res_block
379; X64-NEXT: movl $1, %eax
380; X64-NEXT: .LBB10_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000381; X64-NEXT: testl %eax, %eax
382; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000383; X64-NEXT: retq
384 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
385 %c = icmp ne i32 %m, 0
386 ret i1 %c
387}
388
389define i32 @length8(i8* %X, i8* %Y) nounwind optsize {
390; X86-LABEL: length8:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000391; X86: # BB#0: # %loadbb
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 .LBB11_1
401; X86-NEXT: # BB#2: # %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 .LBB11_3
409; X86-NEXT: .LBB11_1: # %res_block
410; X86-NEXT: xorl %esi, %esi
411; X86-NEXT: incl %esi
412; X86-NEXT: xorl %eax, %eax
413; X86-NEXT: decl %eax
414; X86-NEXT: cmpl %edx, %ecx
415; X86-NEXT: cmovael %esi, %eax
416; X86-NEXT: .LBB11_3: # %endblock
417; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000418; X86-NEXT: retl
419;
420; X64-LABEL: length8:
421; X64: # BB#0:
422; X64-NEXT: movq (%rdi), %rax
423; X64-NEXT: movq (%rsi), %rcx
424; X64-NEXT: bswapq %rax
425; X64-NEXT: bswapq %rcx
426; X64-NEXT: xorl %edx, %edx
427; X64-NEXT: cmpq %rcx, %rax
428; X64-NEXT: movl $-1, %ecx
429; X64-NEXT: movl $1, %eax
430; X64-NEXT: cmovbl %ecx, %eax
431; X64-NEXT: cmovel %edx, %eax
432; X64-NEXT: retq
433 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
434 ret i32 %m
435}
436
437define i1 @length8_eq(i8* %X, i8* %Y) nounwind optsize {
438; X86-LABEL: length8_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000439; X86: # BB#0: # %loadbb
440; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
441; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
442; X86-NEXT: movl (%eax), %edx
443; X86-NEXT: cmpl (%ecx), %edx
444; X86-NEXT: jne .LBB12_1
445; X86-NEXT: # BB#2: # %loadbb1
446; X86-NEXT: movl 4(%eax), %edx
447; X86-NEXT: xorl %eax, %eax
448; X86-NEXT: cmpl 4(%ecx), %edx
449; X86-NEXT: je .LBB12_3
450; X86-NEXT: .LBB12_1: # %res_block
451; X86-NEXT: xorl %eax, %eax
452; X86-NEXT: incl %eax
453; X86-NEXT: .LBB12_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000454; X86-NEXT: testl %eax, %eax
455; X86-NEXT: sete %al
456; X86-NEXT: retl
457;
458; X64-LABEL: length8_eq:
459; X64: # BB#0:
460; X64-NEXT: movq (%rdi), %rax
461; X64-NEXT: cmpq (%rsi), %rax
462; X64-NEXT: sete %al
463; X64-NEXT: retq
464 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
465 %c = icmp eq i32 %m, 0
466 ret i1 %c
467}
468
469define i1 @length8_eq_const(i8* %X) nounwind optsize {
470; X86-LABEL: length8_eq_const:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000471; X86: # BB#0: # %loadbb
472; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
473; X86-NEXT: cmpl $858927408, (%ecx) # imm = 0x33323130
474; X86-NEXT: jne .LBB13_1
475; X86-NEXT: # BB#2: # %loadbb1
476; X86-NEXT: xorl %eax, %eax
477; X86-NEXT: cmpl $926299444, 4(%ecx) # imm = 0x37363534
478; X86-NEXT: je .LBB13_3
479; X86-NEXT: .LBB13_1: # %res_block
480; X86-NEXT: xorl %eax, %eax
481; X86-NEXT: incl %eax
482; X86-NEXT: .LBB13_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000483; X86-NEXT: testl %eax, %eax
484; X86-NEXT: setne %al
485; X86-NEXT: retl
486;
487; X64-LABEL: length8_eq_const:
488; X64: # BB#0:
489; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
490; X64-NEXT: cmpq %rax, (%rdi)
491; X64-NEXT: setne %al
492; X64-NEXT: retq
493 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
494 %c = icmp ne i32 %m, 0
495 ret i1 %c
496}
497
498define i1 @length12_eq(i8* %X, i8* %Y) nounwind optsize {
499; X86-LABEL: length12_eq:
500; X86: # BB#0:
501; X86-NEXT: pushl $0
502; X86-NEXT: pushl $12
503; X86-NEXT: pushl {{[0-9]+}}(%esp)
504; X86-NEXT: pushl {{[0-9]+}}(%esp)
505; X86-NEXT: calll memcmp
506; X86-NEXT: addl $16, %esp
507; X86-NEXT: testl %eax, %eax
508; X86-NEXT: setne %al
509; X86-NEXT: retl
510;
511; X64-LABEL: length12_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000512; X64: # BB#0: # %loadbb
513; X64-NEXT: movq (%rdi), %rax
514; X64-NEXT: cmpq (%rsi), %rax
515; X64-NEXT: jne .LBB14_1
516; X64-NEXT: # BB#2: # %loadbb1
517; X64-NEXT: movl 8(%rdi), %ecx
518; X64-NEXT: xorl %eax, %eax
519; X64-NEXT: cmpl 8(%rsi), %ecx
520; X64-NEXT: je .LBB14_3
521; X64-NEXT: .LBB14_1: # %res_block
522; X64-NEXT: movl $1, %eax
523; X64-NEXT: .LBB14_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000524; X64-NEXT: testl %eax, %eax
525; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000526; X64-NEXT: retq
527 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
528 %c = icmp ne i32 %m, 0
529 ret i1 %c
530}
531
532define i32 @length12(i8* %X, i8* %Y) nounwind optsize {
533; X86-LABEL: length12:
534; X86: # BB#0:
535; X86-NEXT: pushl $0
536; X86-NEXT: pushl $12
537; X86-NEXT: pushl {{[0-9]+}}(%esp)
538; X86-NEXT: pushl {{[0-9]+}}(%esp)
539; X86-NEXT: calll memcmp
540; X86-NEXT: addl $16, %esp
541; X86-NEXT: retl
542;
543; X64-LABEL: length12:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000544; X64: # BB#0: # %loadbb
545; X64-NEXT: movq (%rdi), %rcx
546; X64-NEXT: movq (%rsi), %rdx
547; X64-NEXT: bswapq %rcx
548; X64-NEXT: bswapq %rdx
549; X64-NEXT: cmpq %rdx, %rcx
550; X64-NEXT: jne .LBB15_1
551; X64-NEXT: # BB#2: # %loadbb1
552; X64-NEXT: movl 8(%rdi), %ecx
553; X64-NEXT: movl 8(%rsi), %edx
554; X64-NEXT: bswapl %ecx
555; X64-NEXT: bswapl %edx
556; X64-NEXT: xorl %eax, %eax
557; X64-NEXT: cmpq %rdx, %rcx
558; X64-NEXT: jne .LBB15_1
559; X64-NEXT: # BB#3: # %endblock
560; X64-NEXT: retq
561; X64-NEXT: .LBB15_1: # %res_block
562; X64-NEXT: cmpq %rdx, %rcx
563; X64-NEXT: movl $-1, %ecx
564; X64-NEXT: movl $1, %eax
565; X64-NEXT: cmovbl %ecx, %eax
566; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000567 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
568 ret i32 %m
569}
570
571; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
572
573define i32 @length16(i8* %X, i8* %Y) nounwind optsize {
574; X86-LABEL: length16:
575; X86: # BB#0:
576; X86-NEXT: pushl $0
577; X86-NEXT: pushl $16
578; X86-NEXT: pushl {{[0-9]+}}(%esp)
579; X86-NEXT: pushl {{[0-9]+}}(%esp)
580; X86-NEXT: calll memcmp
581; X86-NEXT: addl $16, %esp
582; X86-NEXT: retl
583;
584; X64-LABEL: length16:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000585; X64: # BB#0: # %loadbb
586; X64-NEXT: movq (%rdi), %rcx
587; X64-NEXT: movq (%rsi), %rdx
588; X64-NEXT: bswapq %rcx
589; X64-NEXT: bswapq %rdx
590; X64-NEXT: cmpq %rdx, %rcx
591; X64-NEXT: jne .LBB16_1
592; X64-NEXT: # BB#2: # %loadbb1
593; X64-NEXT: movq 8(%rdi), %rcx
594; X64-NEXT: movq 8(%rsi), %rdx
595; X64-NEXT: bswapq %rcx
596; X64-NEXT: bswapq %rdx
597; X64-NEXT: xorl %eax, %eax
598; X64-NEXT: cmpq %rdx, %rcx
599; X64-NEXT: jne .LBB16_1
600; X64-NEXT: # BB#3: # %endblock
601; X64-NEXT: retq
602; X64-NEXT: .LBB16_1: # %res_block
603; X64-NEXT: cmpq %rdx, %rcx
604; X64-NEXT: movl $-1, %ecx
605; X64-NEXT: movl $1, %eax
606; X64-NEXT: cmovbl %ecx, %eax
607; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000608 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
609 ret i32 %m
610}
611
612define i1 @length16_eq(i8* %x, i8* %y) nounwind optsize {
613; X86-NOSSE-LABEL: length16_eq:
614; X86-NOSSE: # BB#0:
615; X86-NOSSE-NEXT: pushl $0
616; X86-NOSSE-NEXT: pushl $16
617; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
618; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
619; X86-NOSSE-NEXT: calll memcmp
620; X86-NOSSE-NEXT: addl $16, %esp
621; X86-NOSSE-NEXT: testl %eax, %eax
622; X86-NOSSE-NEXT: setne %al
623; X86-NOSSE-NEXT: retl
624;
625; X86-SSE2-LABEL: length16_eq:
626; X86-SSE2: # BB#0:
627; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
628; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
629; X86-SSE2-NEXT: movdqu (%ecx), %xmm0
630; X86-SSE2-NEXT: movdqu (%eax), %xmm1
631; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1
632; X86-SSE2-NEXT: pmovmskb %xmm1, %eax
633; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
634; X86-SSE2-NEXT: setne %al
635; X86-SSE2-NEXT: retl
636;
Simon Pilgrim483927a2017-07-18 15:55:30 +0000637; X64-LABEL: length16_eq:
638; X64: # BB#0: # %loadbb
639; X64-NEXT: movq (%rdi), %rax
640; X64-NEXT: cmpq (%rsi), %rax
641; X64-NEXT: jne .LBB17_1
642; X64-NEXT: # BB#2: # %loadbb1
643; X64-NEXT: movq 8(%rdi), %rcx
644; X64-NEXT: xorl %eax, %eax
645; X64-NEXT: cmpq 8(%rsi), %rcx
646; X64-NEXT: je .LBB17_3
647; X64-NEXT: .LBB17_1: # %res_block
648; X64-NEXT: movl $1, %eax
649; X64-NEXT: .LBB17_3: # %endblock
650; X64-NEXT: testl %eax, %eax
651; X64-NEXT: setne %al
652; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000653 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
654 %cmp = icmp ne i32 %call, 0
655 ret i1 %cmp
656}
657
658define i1 @length16_eq_const(i8* %X) nounwind optsize {
659; X86-NOSSE-LABEL: length16_eq_const:
660; X86-NOSSE: # BB#0:
661; X86-NOSSE-NEXT: pushl $0
662; X86-NOSSE-NEXT: pushl $16
663; X86-NOSSE-NEXT: pushl $.L.str
664; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
665; X86-NOSSE-NEXT: calll memcmp
666; X86-NOSSE-NEXT: addl $16, %esp
667; X86-NOSSE-NEXT: testl %eax, %eax
668; X86-NOSSE-NEXT: sete %al
669; X86-NOSSE-NEXT: retl
670;
671; X86-SSE2-LABEL: length16_eq_const:
672; X86-SSE2: # BB#0:
673; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
674; X86-SSE2-NEXT: movdqu (%eax), %xmm0
675; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0
676; X86-SSE2-NEXT: pmovmskb %xmm0, %eax
677; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
678; X86-SSE2-NEXT: sete %al
679; X86-SSE2-NEXT: retl
680;
Simon Pilgrim483927a2017-07-18 15:55:30 +0000681; X64-LABEL: length16_eq_const:
682; X64: # BB#0: # %loadbb
683; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
684; X64-NEXT: cmpq %rax, (%rdi)
685; X64-NEXT: jne .LBB18_1
686; X64-NEXT: # BB#2: # %loadbb1
687; X64-NEXT: xorl %eax, %eax
688; X64-NEXT: movabsq $3833745473465760056, %rcx # imm = 0x3534333231303938
689; X64-NEXT: cmpq %rcx, 8(%rdi)
690; X64-NEXT: je .LBB18_3
691; X64-NEXT: .LBB18_1: # %res_block
692; X64-NEXT: movl $1, %eax
693; X64-NEXT: .LBB18_3: # %endblock
694; X64-NEXT: testl %eax, %eax
695; X64-NEXT: sete %al
696; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000697 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
698 %c = icmp eq i32 %m, 0
699 ret i1 %c
700}
701
Simon Pilgrim3459f102017-07-25 10:33:36 +0000702; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
703
704define i32 @length24(i8* %X, i8* %Y) nounwind optsize {
705; X86-LABEL: length24:
706; X86: # BB#0:
707; X86-NEXT: pushl $0
708; X86-NEXT: pushl $24
709; X86-NEXT: pushl {{[0-9]+}}(%esp)
710; X86-NEXT: pushl {{[0-9]+}}(%esp)
711; X86-NEXT: calll memcmp
712; X86-NEXT: addl $16, %esp
713; X86-NEXT: retl
714;
715; X64-LABEL: length24:
716; X64: # BB#0:
717; X64-NEXT: movl $24, %edx
718; X64-NEXT: jmp memcmp # TAILCALL
719 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
720 ret i32 %m
721}
722
723define i1 @length24_eq(i8* %x, i8* %y) nounwind optsize {
724; X86-LABEL: length24_eq:
725; X86: # BB#0:
726; X86-NEXT: pushl $0
727; X86-NEXT: pushl $24
728; X86-NEXT: pushl {{[0-9]+}}(%esp)
729; X86-NEXT: pushl {{[0-9]+}}(%esp)
730; X86-NEXT: calll memcmp
731; X86-NEXT: addl $16, %esp
732; X86-NEXT: testl %eax, %eax
733; X86-NEXT: sete %al
734; X86-NEXT: retl
735;
736; X64-LABEL: length24_eq:
737; X64: # BB#0:
738; X64-NEXT: pushq %rax
739; X64-NEXT: movl $24, %edx
740; X64-NEXT: callq memcmp
741; X64-NEXT: testl %eax, %eax
742; X64-NEXT: sete %al
743; X64-NEXT: popq %rcx
744; X64-NEXT: retq
745 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
746 %cmp = icmp eq i32 %call, 0
747 ret i1 %cmp
748}
749
750define i1 @length24_eq_const(i8* %X) nounwind optsize {
751; X86-LABEL: length24_eq_const:
752; X86: # BB#0:
753; X86-NEXT: pushl $0
754; X86-NEXT: pushl $24
755; X86-NEXT: pushl $.L.str
756; X86-NEXT: pushl {{[0-9]+}}(%esp)
757; X86-NEXT: calll memcmp
758; X86-NEXT: addl $16, %esp
759; X86-NEXT: testl %eax, %eax
760; X86-NEXT: setne %al
761; X86-NEXT: retl
762;
763; X64-LABEL: length24_eq_const:
764; X64: # BB#0:
765; X64-NEXT: pushq %rax
766; X64-NEXT: movl $.L.str, %esi
767; X64-NEXT: movl $24, %edx
768; X64-NEXT: callq memcmp
769; X64-NEXT: testl %eax, %eax
770; X64-NEXT: setne %al
771; X64-NEXT: popq %rcx
772; X64-NEXT: retq
773 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
774 %c = icmp ne i32 %m, 0
775 ret i1 %c
776}
777
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000778define i32 @length32(i8* %X, i8* %Y) nounwind optsize {
779; X86-LABEL: length32:
780; X86: # BB#0:
781; X86-NEXT: pushl $0
782; X86-NEXT: pushl $32
783; X86-NEXT: pushl {{[0-9]+}}(%esp)
784; X86-NEXT: pushl {{[0-9]+}}(%esp)
785; X86-NEXT: calll memcmp
786; X86-NEXT: addl $16, %esp
787; X86-NEXT: retl
788;
789; X64-LABEL: length32:
790; X64: # BB#0:
791; X64-NEXT: movl $32, %edx
792; X64-NEXT: jmp memcmp # TAILCALL
793 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
794 ret i32 %m
795}
796
797; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
798
799define i1 @length32_eq(i8* %x, i8* %y) nounwind optsize {
800; X86-LABEL: length32_eq:
801; X86: # BB#0:
802; X86-NEXT: pushl $0
803; X86-NEXT: pushl $32
804; X86-NEXT: pushl {{[0-9]+}}(%esp)
805; X86-NEXT: pushl {{[0-9]+}}(%esp)
806; X86-NEXT: calll memcmp
807; X86-NEXT: addl $16, %esp
808; X86-NEXT: testl %eax, %eax
809; X86-NEXT: sete %al
810; X86-NEXT: retl
811;
812; X64-SSE2-LABEL: length32_eq:
813; X64-SSE2: # BB#0:
814; X64-SSE2-NEXT: pushq %rax
815; X64-SSE2-NEXT: movl $32, %edx
816; X64-SSE2-NEXT: callq memcmp
817; X64-SSE2-NEXT: testl %eax, %eax
818; X64-SSE2-NEXT: sete %al
819; X64-SSE2-NEXT: popq %rcx
820; X64-SSE2-NEXT: retq
821;
822; X64-AVX2-LABEL: length32_eq:
823; X64-AVX2: # BB#0:
824; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
825; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0
826; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
827; X64-AVX2-NEXT: cmpl $-1, %eax
828; X64-AVX2-NEXT: sete %al
829; X64-AVX2-NEXT: vzeroupper
830; X64-AVX2-NEXT: retq
831 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
832 %cmp = icmp eq i32 %call, 0
833 ret i1 %cmp
834}
835
836define i1 @length32_eq_const(i8* %X) nounwind optsize {
837; X86-LABEL: length32_eq_const:
838; X86: # BB#0:
839; X86-NEXT: pushl $0
840; X86-NEXT: pushl $32
841; X86-NEXT: pushl $.L.str
842; X86-NEXT: pushl {{[0-9]+}}(%esp)
843; X86-NEXT: calll memcmp
844; X86-NEXT: addl $16, %esp
845; X86-NEXT: testl %eax, %eax
846; X86-NEXT: setne %al
847; X86-NEXT: retl
848;
849; X64-SSE2-LABEL: length32_eq_const:
850; X64-SSE2: # BB#0:
851; X64-SSE2-NEXT: pushq %rax
852; X64-SSE2-NEXT: movl $.L.str, %esi
853; X64-SSE2-NEXT: movl $32, %edx
854; X64-SSE2-NEXT: callq memcmp
855; X64-SSE2-NEXT: testl %eax, %eax
856; X64-SSE2-NEXT: setne %al
857; X64-SSE2-NEXT: popq %rcx
858; X64-SSE2-NEXT: retq
859;
860; X64-AVX2-LABEL: length32_eq_const:
861; X64-AVX2: # BB#0:
862; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
863; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
864; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
865; X64-AVX2-NEXT: cmpl $-1, %eax
866; X64-AVX2-NEXT: setne %al
867; X64-AVX2-NEXT: vzeroupper
868; X64-AVX2-NEXT: retq
869 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 32) nounwind
870 %c = icmp ne i32 %m, 0
871 ret i1 %c
872}
873
874define i32 @length64(i8* %X, i8* %Y) nounwind optsize {
875; X86-LABEL: length64:
876; X86: # BB#0:
877; X86-NEXT: pushl $0
878; X86-NEXT: pushl $64
879; X86-NEXT: pushl {{[0-9]+}}(%esp)
880; X86-NEXT: pushl {{[0-9]+}}(%esp)
881; X86-NEXT: calll memcmp
882; X86-NEXT: addl $16, %esp
883; X86-NEXT: retl
884;
885; X64-LABEL: length64:
886; X64: # BB#0:
887; X64-NEXT: movl $64, %edx
888; X64-NEXT: jmp memcmp # TAILCALL
889 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
890 ret i32 %m
891}
892
893define i1 @length64_eq(i8* %x, i8* %y) nounwind optsize {
894; X86-LABEL: length64_eq:
895; X86: # BB#0:
896; X86-NEXT: pushl $0
897; X86-NEXT: pushl $64
898; X86-NEXT: pushl {{[0-9]+}}(%esp)
899; X86-NEXT: pushl {{[0-9]+}}(%esp)
900; X86-NEXT: calll memcmp
901; X86-NEXT: addl $16, %esp
902; X86-NEXT: testl %eax, %eax
903; X86-NEXT: setne %al
904; X86-NEXT: retl
905;
906; X64-LABEL: length64_eq:
907; X64: # BB#0:
908; X64-NEXT: pushq %rax
909; X64-NEXT: movl $64, %edx
910; X64-NEXT: callq memcmp
911; X64-NEXT: testl %eax, %eax
912; X64-NEXT: setne %al
913; X64-NEXT: popq %rcx
914; X64-NEXT: retq
915 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
916 %cmp = icmp ne i32 %call, 0
917 ret i1 %cmp
918}
919
920define i1 @length64_eq_const(i8* %X) nounwind optsize {
921; X86-LABEL: length64_eq_const:
922; X86: # BB#0:
923; X86-NEXT: pushl $0
924; X86-NEXT: pushl $64
925; X86-NEXT: pushl $.L.str
926; X86-NEXT: pushl {{[0-9]+}}(%esp)
927; X86-NEXT: calll memcmp
928; X86-NEXT: addl $16, %esp
929; X86-NEXT: testl %eax, %eax
930; X86-NEXT: sete %al
931; X86-NEXT: retl
932;
933; X64-LABEL: length64_eq_const:
934; X64: # BB#0:
935; X64-NEXT: pushq %rax
936; X64-NEXT: movl $.L.str, %esi
937; X64-NEXT: movl $64, %edx
938; X64-NEXT: callq memcmp
939; X64-NEXT: testl %eax, %eax
940; X64-NEXT: sete %al
941; X64-NEXT: popq %rcx
942; X64-NEXT: retq
943 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
944 %c = icmp eq i32 %m, 0
945 ret i1 %c
946}
947