blob: 1b0ffc03b67d60e315389e0b05958cc35f25d237 [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:
Simon Pilgrimc2cbb522017-07-18 14:26:07 +000017; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
18; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
19; X86-NEXT: movzwl (%ecx), %ecx
20; X86-NEXT: movzwl (%eax), %edx
21; X86-NEXT: rolw $8, %cx
22; X86-NEXT: rolw $8, %dx
Sanjay Patelfea731a2017-07-31 18:08:24 +000023; X86-NEXT: movzwl %cx, %eax
24; X86-NEXT: movzwl %dx, %ecx
25; X86-NEXT: subl %ecx, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +000026; X86-NEXT: retl
27;
28; X64-LABEL: length2:
29; X64: # BB#0:
30; X64-NEXT: movzwl (%rdi), %eax
31; X64-NEXT: movzwl (%rsi), %ecx
32; X64-NEXT: rolw $8, %ax
33; X64-NEXT: rolw $8, %cx
Sanjay Patelfea731a2017-07-31 18:08:24 +000034; X64-NEXT: movzwl %ax, %eax
35; X64-NEXT: movzwl %cx, %ecx
36; X64-NEXT: subl %ecx, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +000037; X64-NEXT: retq
38 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
39 ret i32 %m
40}
41
42define i1 @length2_eq(i8* %X, i8* %Y) nounwind optsize {
43; X86-LABEL: length2_eq:
44; X86: # BB#0:
45; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
46; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
47; X86-NEXT: movzwl (%ecx), %ecx
48; X86-NEXT: cmpw (%eax), %cx
49; X86-NEXT: sete %al
50; X86-NEXT: retl
51;
52; X64-LABEL: length2_eq:
53; X64: # BB#0:
54; X64-NEXT: movzwl (%rdi), %eax
55; X64-NEXT: cmpw (%rsi), %ax
56; X64-NEXT: sete %al
57; X64-NEXT: retq
58 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind
59 %c = icmp eq i32 %m, 0
60 ret i1 %c
61}
62
63define i1 @length2_eq_const(i8* %X) nounwind optsize {
64; X86-LABEL: length2_eq_const:
65; X86: # BB#0:
66; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
67; X86-NEXT: movzwl (%eax), %eax
68; X86-NEXT: cmpl $12849, %eax # imm = 0x3231
69; X86-NEXT: setne %al
70; X86-NEXT: retl
71;
72; X64-LABEL: length2_eq_const:
73; X64: # BB#0:
74; X64-NEXT: movzwl (%rdi), %eax
75; X64-NEXT: cmpl $12849, %eax # imm = 0x3231
76; X64-NEXT: setne %al
77; X64-NEXT: retq
78 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 2) nounwind
79 %c = icmp ne i32 %m, 0
80 ret i1 %c
81}
82
83define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind optsize {
84; X86-LABEL: length2_eq_nobuiltin_attr:
85; X86: # BB#0:
86; X86-NEXT: pushl $0
87; X86-NEXT: pushl $2
88; X86-NEXT: pushl {{[0-9]+}}(%esp)
89; X86-NEXT: pushl {{[0-9]+}}(%esp)
90; X86-NEXT: calll memcmp
91; X86-NEXT: addl $16, %esp
92; X86-NEXT: testl %eax, %eax
93; X86-NEXT: sete %al
94; X86-NEXT: retl
95;
96; X64-LABEL: length2_eq_nobuiltin_attr:
97; X64: # BB#0:
98; X64-NEXT: pushq %rax
99; X64-NEXT: movl $2, %edx
100; X64-NEXT: callq memcmp
101; X64-NEXT: testl %eax, %eax
102; X64-NEXT: sete %al
103; X64-NEXT: popq %rcx
104; X64-NEXT: retq
105 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin
106 %c = icmp eq i32 %m, 0
107 ret i1 %c
108}
109
110define i32 @length3(i8* %X, i8* %Y) nounwind optsize {
111; X86-LABEL: length3:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000112; X86: # BB#0: # %loadbb
113; X86-NEXT: pushl %esi
114; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
115; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
116; X86-NEXT: movzwl (%eax), %edx
117; X86-NEXT: movzwl (%ecx), %esi
118; X86-NEXT: rolw $8, %dx
119; X86-NEXT: rolw $8, %si
120; X86-NEXT: movzwl %dx, %edx
121; X86-NEXT: movzwl %si, %esi
122; X86-NEXT: cmpl %esi, %edx
123; X86-NEXT: jne .LBB4_1
124; X86-NEXT: # BB#2: # %loadbb1
125; X86-NEXT: movzbl 2(%eax), %eax
126; X86-NEXT: movzbl 2(%ecx), %ecx
127; X86-NEXT: subl %ecx, %eax
128; X86-NEXT: jmp .LBB4_3
129; X86-NEXT: .LBB4_1: # %res_block
130; X86-NEXT: xorl %ecx, %ecx
131; X86-NEXT: incl %ecx
132; X86-NEXT: xorl %eax, %eax
133; X86-NEXT: decl %eax
134; X86-NEXT: cmpl %esi, %edx
135; X86-NEXT: cmovael %ecx, %eax
136; X86-NEXT: .LBB4_3: # %endblock
137; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000138; X86-NEXT: retl
139;
140; X64-LABEL: length3:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000141; X64: # BB#0: # %loadbb
142; X64-NEXT: movzwl (%rdi), %eax
143; X64-NEXT: movzwl (%rsi), %ecx
144; X64-NEXT: rolw $8, %ax
145; X64-NEXT: rolw $8, %cx
146; X64-NEXT: movzwl %ax, %eax
147; X64-NEXT: movzwl %cx, %ecx
148; X64-NEXT: cmpq %rcx, %rax
149; X64-NEXT: jne .LBB4_1
150; X64-NEXT: # BB#2: # %loadbb1
151; X64-NEXT: movzbl 2(%rdi), %eax
152; X64-NEXT: movzbl 2(%rsi), %ecx
153; X64-NEXT: subl %ecx, %eax
154; X64-NEXT: retq
155; X64-NEXT: .LBB4_1: # %res_block
156; X64-NEXT: movl $-1, %ecx
157; X64-NEXT: movl $1, %eax
158; X64-NEXT: cmovbl %ecx, %eax
159; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000160 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
161 ret i32 %m
162}
163
164define i1 @length3_eq(i8* %X, i8* %Y) nounwind optsize {
165; X86-LABEL: length3_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000166; X86: # BB#0: # %loadbb
167; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
168; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
169; X86-NEXT: movzwl (%eax), %edx
170; X86-NEXT: cmpw (%ecx), %dx
171; X86-NEXT: jne .LBB5_1
172; X86-NEXT: # BB#2: # %loadbb1
173; X86-NEXT: movb 2(%eax), %dl
174; X86-NEXT: xorl %eax, %eax
175; X86-NEXT: cmpb 2(%ecx), %dl
176; X86-NEXT: je .LBB5_3
177; X86-NEXT: .LBB5_1: # %res_block
178; X86-NEXT: xorl %eax, %eax
179; X86-NEXT: incl %eax
180; X86-NEXT: .LBB5_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000181; X86-NEXT: testl %eax, %eax
182; X86-NEXT: setne %al
183; X86-NEXT: retl
184;
185; X64-LABEL: length3_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000186; X64: # BB#0: # %loadbb
187; X64-NEXT: movzwl (%rdi), %eax
188; X64-NEXT: cmpw (%rsi), %ax
189; X64-NEXT: jne .LBB5_1
190; X64-NEXT: # BB#2: # %loadbb1
191; X64-NEXT: movb 2(%rdi), %cl
192; X64-NEXT: xorl %eax, %eax
193; X64-NEXT: cmpb 2(%rsi), %cl
194; X64-NEXT: je .LBB5_3
195; X64-NEXT: .LBB5_1: # %res_block
196; X64-NEXT: movl $1, %eax
197; X64-NEXT: .LBB5_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000198; X64-NEXT: testl %eax, %eax
199; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000200; X64-NEXT: retq
201 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 3) nounwind
202 %c = icmp ne i32 %m, 0
203 ret i1 %c
204}
205
206define i32 @length4(i8* %X, i8* %Y) nounwind optsize {
207; X86-LABEL: length4:
208; X86: # BB#0:
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000209; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
210; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
211; X86-NEXT: movl (%ecx), %ecx
212; X86-NEXT: movl (%eax), %edx
213; X86-NEXT: bswapl %ecx
214; X86-NEXT: bswapl %edx
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000215; X86-NEXT: xorl %eax, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000216; X86-NEXT: cmpl %edx, %ecx
Sanjay Patelfea731a2017-07-31 18:08:24 +0000217; X86-NEXT: seta %al
218; X86-NEXT: sbbl $0, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000219; X86-NEXT: retl
220;
221; X64-LABEL: length4:
222; X64: # BB#0:
Sanjay Patelfea731a2017-07-31 18:08:24 +0000223; X64-NEXT: movl (%rdi), %ecx
224; X64-NEXT: movl (%rsi), %edx
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000225; X64-NEXT: bswapl %ecx
Sanjay Patelfea731a2017-07-31 18:08:24 +0000226; X64-NEXT: bswapl %edx
227; X64-NEXT: xorl %eax, %eax
228; X64-NEXT: cmpl %edx, %ecx
229; X64-NEXT: seta %al
230; X64-NEXT: sbbl $0, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000231; X64-NEXT: retq
232 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
233 ret i32 %m
234}
235
236define i1 @length4_eq(i8* %X, i8* %Y) nounwind optsize {
237; X86-LABEL: length4_eq:
238; X86: # BB#0:
239; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
240; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
241; X86-NEXT: movl (%ecx), %ecx
242; X86-NEXT: cmpl (%eax), %ecx
243; X86-NEXT: setne %al
244; X86-NEXT: retl
245;
246; X64-LABEL: length4_eq:
247; X64: # BB#0:
248; X64-NEXT: movl (%rdi), %eax
249; X64-NEXT: cmpl (%rsi), %eax
250; X64-NEXT: setne %al
251; X64-NEXT: retq
252 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind
253 %c = icmp ne i32 %m, 0
254 ret i1 %c
255}
256
257define i1 @length4_eq_const(i8* %X) nounwind optsize {
258; X86-LABEL: length4_eq_const:
259; X86: # BB#0:
260; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
261; X86-NEXT: cmpl $875770417, (%eax) # imm = 0x34333231
262; X86-NEXT: sete %al
263; X86-NEXT: retl
264;
265; X64-LABEL: length4_eq_const:
266; X64: # BB#0:
267; X64-NEXT: cmpl $875770417, (%rdi) # imm = 0x34333231
268; X64-NEXT: sete %al
269; X64-NEXT: retq
270 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 1), i64 4) nounwind
271 %c = icmp eq i32 %m, 0
272 ret i1 %c
273}
274
275define i32 @length5(i8* %X, i8* %Y) nounwind optsize {
276; X86-LABEL: length5:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000277; X86: # BB#0: # %loadbb
278; X86-NEXT: pushl %esi
279; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
280; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
281; X86-NEXT: movl (%eax), %edx
282; X86-NEXT: movl (%ecx), %esi
283; X86-NEXT: bswapl %edx
284; X86-NEXT: bswapl %esi
285; X86-NEXT: cmpl %esi, %edx
286; X86-NEXT: jne .LBB9_1
287; X86-NEXT: # BB#2: # %loadbb1
288; X86-NEXT: movzbl 4(%eax), %eax
289; X86-NEXT: movzbl 4(%ecx), %ecx
290; X86-NEXT: subl %ecx, %eax
291; X86-NEXT: jmp .LBB9_3
292; X86-NEXT: .LBB9_1: # %res_block
293; X86-NEXT: xorl %ecx, %ecx
294; X86-NEXT: incl %ecx
295; X86-NEXT: xorl %eax, %eax
296; X86-NEXT: decl %eax
297; X86-NEXT: cmpl %esi, %edx
298; X86-NEXT: cmovael %ecx, %eax
299; X86-NEXT: .LBB9_3: # %endblock
300; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000301; X86-NEXT: retl
302;
303; X64-LABEL: length5:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000304; X64: # BB#0: # %loadbb
305; X64-NEXT: movl (%rdi), %eax
306; X64-NEXT: movl (%rsi), %ecx
307; X64-NEXT: bswapl %eax
308; X64-NEXT: bswapl %ecx
309; X64-NEXT: cmpq %rcx, %rax
310; X64-NEXT: jne .LBB9_1
311; X64-NEXT: # BB#2: # %loadbb1
312; X64-NEXT: movzbl 4(%rdi), %eax
313; X64-NEXT: movzbl 4(%rsi), %ecx
314; X64-NEXT: subl %ecx, %eax
315; X64-NEXT: retq
316; X64-NEXT: .LBB9_1: # %res_block
317; X64-NEXT: movl $-1, %ecx
318; X64-NEXT: movl $1, %eax
319; X64-NEXT: cmovbl %ecx, %eax
320; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000321 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
322 ret i32 %m
323}
324
325define i1 @length5_eq(i8* %X, i8* %Y) nounwind optsize {
326; X86-LABEL: length5_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000327; X86: # BB#0: # %loadbb
328; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
329; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
330; X86-NEXT: movl (%eax), %edx
331; X86-NEXT: cmpl (%ecx), %edx
332; X86-NEXT: jne .LBB10_1
333; X86-NEXT: # BB#2: # %loadbb1
334; X86-NEXT: movb 4(%eax), %dl
335; X86-NEXT: xorl %eax, %eax
336; X86-NEXT: cmpb 4(%ecx), %dl
337; X86-NEXT: je .LBB10_3
338; X86-NEXT: .LBB10_1: # %res_block
339; X86-NEXT: xorl %eax, %eax
340; X86-NEXT: incl %eax
341; X86-NEXT: .LBB10_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000342; X86-NEXT: testl %eax, %eax
343; X86-NEXT: setne %al
344; X86-NEXT: retl
345;
346; X64-LABEL: length5_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000347; X64: # BB#0: # %loadbb
348; X64-NEXT: movl (%rdi), %eax
349; X64-NEXT: cmpl (%rsi), %eax
350; X64-NEXT: jne .LBB10_1
351; X64-NEXT: # BB#2: # %loadbb1
352; X64-NEXT: movb 4(%rdi), %cl
353; X64-NEXT: xorl %eax, %eax
354; X64-NEXT: cmpb 4(%rsi), %cl
355; X64-NEXT: je .LBB10_3
356; X64-NEXT: .LBB10_1: # %res_block
357; X64-NEXT: movl $1, %eax
358; X64-NEXT: .LBB10_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000359; X64-NEXT: testl %eax, %eax
360; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000361; X64-NEXT: retq
362 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 5) nounwind
363 %c = icmp ne i32 %m, 0
364 ret i1 %c
365}
366
367define i32 @length8(i8* %X, i8* %Y) nounwind optsize {
368; X86-LABEL: length8:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000369; X86: # BB#0: # %loadbb
370; X86-NEXT: pushl %esi
371; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
372; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
373; X86-NEXT: movl (%esi), %ecx
374; X86-NEXT: movl (%eax), %edx
375; X86-NEXT: bswapl %ecx
376; X86-NEXT: bswapl %edx
377; X86-NEXT: cmpl %edx, %ecx
378; X86-NEXT: jne .LBB11_1
379; X86-NEXT: # BB#2: # %loadbb1
380; X86-NEXT: movl 4(%esi), %ecx
381; X86-NEXT: movl 4(%eax), %edx
382; X86-NEXT: bswapl %ecx
383; X86-NEXT: bswapl %edx
384; X86-NEXT: xorl %eax, %eax
385; X86-NEXT: cmpl %edx, %ecx
386; X86-NEXT: je .LBB11_3
387; X86-NEXT: .LBB11_1: # %res_block
388; X86-NEXT: xorl %esi, %esi
389; X86-NEXT: incl %esi
390; X86-NEXT: xorl %eax, %eax
391; X86-NEXT: decl %eax
392; X86-NEXT: cmpl %edx, %ecx
393; X86-NEXT: cmovael %esi, %eax
394; X86-NEXT: .LBB11_3: # %endblock
395; X86-NEXT: popl %esi
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000396; X86-NEXT: retl
397;
398; X64-LABEL: length8:
399; X64: # BB#0:
Sanjay Patelfea731a2017-07-31 18:08:24 +0000400; X64-NEXT: movq (%rdi), %rcx
401; X64-NEXT: movq (%rsi), %rdx
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000402; X64-NEXT: bswapq %rcx
Sanjay Patelfea731a2017-07-31 18:08:24 +0000403; X64-NEXT: bswapq %rdx
404; X64-NEXT: xorl %eax, %eax
405; X64-NEXT: cmpq %rdx, %rcx
406; X64-NEXT: seta %al
407; X64-NEXT: sbbl $0, %eax
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000408; X64-NEXT: retq
409 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
410 ret i32 %m
411}
412
413define i1 @length8_eq(i8* %X, i8* %Y) nounwind optsize {
414; X86-LABEL: length8_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000415; X86: # BB#0: # %loadbb
416; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
417; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
418; X86-NEXT: movl (%eax), %edx
419; X86-NEXT: cmpl (%ecx), %edx
420; X86-NEXT: jne .LBB12_1
421; X86-NEXT: # BB#2: # %loadbb1
422; X86-NEXT: movl 4(%eax), %edx
423; X86-NEXT: xorl %eax, %eax
424; X86-NEXT: cmpl 4(%ecx), %edx
425; X86-NEXT: je .LBB12_3
426; X86-NEXT: .LBB12_1: # %res_block
427; X86-NEXT: xorl %eax, %eax
428; X86-NEXT: incl %eax
429; X86-NEXT: .LBB12_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000430; X86-NEXT: testl %eax, %eax
431; X86-NEXT: sete %al
432; X86-NEXT: retl
433;
434; X64-LABEL: length8_eq:
435; X64: # BB#0:
436; X64-NEXT: movq (%rdi), %rax
437; X64-NEXT: cmpq (%rsi), %rax
438; X64-NEXT: sete %al
439; X64-NEXT: retq
440 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind
441 %c = icmp eq i32 %m, 0
442 ret i1 %c
443}
444
445define i1 @length8_eq_const(i8* %X) nounwind optsize {
446; X86-LABEL: length8_eq_const:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000447; X86: # BB#0: # %loadbb
448; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
449; X86-NEXT: cmpl $858927408, (%ecx) # imm = 0x33323130
450; X86-NEXT: jne .LBB13_1
451; X86-NEXT: # BB#2: # %loadbb1
452; X86-NEXT: xorl %eax, %eax
453; X86-NEXT: cmpl $926299444, 4(%ecx) # imm = 0x37363534
454; X86-NEXT: je .LBB13_3
455; X86-NEXT: .LBB13_1: # %res_block
456; X86-NEXT: xorl %eax, %eax
457; X86-NEXT: incl %eax
458; X86-NEXT: .LBB13_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000459; X86-NEXT: testl %eax, %eax
460; X86-NEXT: setne %al
461; X86-NEXT: retl
462;
463; X64-LABEL: length8_eq_const:
464; X64: # BB#0:
465; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
466; X64-NEXT: cmpq %rax, (%rdi)
467; X64-NEXT: setne %al
468; X64-NEXT: retq
469 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 8) nounwind
470 %c = icmp ne i32 %m, 0
471 ret i1 %c
472}
473
474define i1 @length12_eq(i8* %X, i8* %Y) nounwind optsize {
475; X86-LABEL: length12_eq:
476; X86: # BB#0:
477; X86-NEXT: pushl $0
478; X86-NEXT: pushl $12
479; X86-NEXT: pushl {{[0-9]+}}(%esp)
480; X86-NEXT: pushl {{[0-9]+}}(%esp)
481; X86-NEXT: calll memcmp
482; X86-NEXT: addl $16, %esp
483; X86-NEXT: testl %eax, %eax
484; X86-NEXT: setne %al
485; X86-NEXT: retl
486;
487; X64-LABEL: length12_eq:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000488; X64: # BB#0: # %loadbb
489; X64-NEXT: movq (%rdi), %rax
490; X64-NEXT: cmpq (%rsi), %rax
491; X64-NEXT: jne .LBB14_1
492; X64-NEXT: # BB#2: # %loadbb1
493; X64-NEXT: movl 8(%rdi), %ecx
494; X64-NEXT: xorl %eax, %eax
495; X64-NEXT: cmpl 8(%rsi), %ecx
496; X64-NEXT: je .LBB14_3
497; X64-NEXT: .LBB14_1: # %res_block
498; X64-NEXT: movl $1, %eax
499; X64-NEXT: .LBB14_3: # %endblock
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000500; X64-NEXT: testl %eax, %eax
501; X64-NEXT: setne %al
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000502; X64-NEXT: retq
503 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
504 %c = icmp ne i32 %m, 0
505 ret i1 %c
506}
507
508define i32 @length12(i8* %X, i8* %Y) nounwind optsize {
509; X86-LABEL: length12:
510; X86: # BB#0:
511; X86-NEXT: pushl $0
512; X86-NEXT: pushl $12
513; X86-NEXT: pushl {{[0-9]+}}(%esp)
514; X86-NEXT: pushl {{[0-9]+}}(%esp)
515; X86-NEXT: calll memcmp
516; X86-NEXT: addl $16, %esp
517; X86-NEXT: retl
518;
519; X64-LABEL: length12:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000520; X64: # BB#0: # %loadbb
521; X64-NEXT: movq (%rdi), %rcx
522; X64-NEXT: movq (%rsi), %rdx
523; X64-NEXT: bswapq %rcx
524; X64-NEXT: bswapq %rdx
525; X64-NEXT: cmpq %rdx, %rcx
526; X64-NEXT: jne .LBB15_1
527; X64-NEXT: # BB#2: # %loadbb1
528; X64-NEXT: movl 8(%rdi), %ecx
529; X64-NEXT: movl 8(%rsi), %edx
530; X64-NEXT: bswapl %ecx
531; X64-NEXT: bswapl %edx
532; X64-NEXT: xorl %eax, %eax
533; X64-NEXT: cmpq %rdx, %rcx
534; X64-NEXT: jne .LBB15_1
535; X64-NEXT: # BB#3: # %endblock
536; X64-NEXT: retq
537; X64-NEXT: .LBB15_1: # %res_block
538; X64-NEXT: cmpq %rdx, %rcx
539; X64-NEXT: movl $-1, %ecx
540; X64-NEXT: movl $1, %eax
541; X64-NEXT: cmovbl %ecx, %eax
542; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000543 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 12) nounwind
544 ret i32 %m
545}
546
547; PR33329 - https://bugs.llvm.org/show_bug.cgi?id=33329
548
549define i32 @length16(i8* %X, i8* %Y) nounwind optsize {
550; X86-LABEL: length16:
551; X86: # BB#0:
552; X86-NEXT: pushl $0
553; X86-NEXT: pushl $16
554; X86-NEXT: pushl {{[0-9]+}}(%esp)
555; X86-NEXT: pushl {{[0-9]+}}(%esp)
556; X86-NEXT: calll memcmp
557; X86-NEXT: addl $16, %esp
558; X86-NEXT: retl
559;
560; X64-LABEL: length16:
Simon Pilgrim483927a2017-07-18 15:55:30 +0000561; X64: # BB#0: # %loadbb
562; X64-NEXT: movq (%rdi), %rcx
563; X64-NEXT: movq (%rsi), %rdx
564; X64-NEXT: bswapq %rcx
565; X64-NEXT: bswapq %rdx
566; X64-NEXT: cmpq %rdx, %rcx
567; X64-NEXT: jne .LBB16_1
568; X64-NEXT: # BB#2: # %loadbb1
569; X64-NEXT: movq 8(%rdi), %rcx
570; X64-NEXT: movq 8(%rsi), %rdx
571; X64-NEXT: bswapq %rcx
572; X64-NEXT: bswapq %rdx
573; X64-NEXT: xorl %eax, %eax
574; X64-NEXT: cmpq %rdx, %rcx
575; X64-NEXT: jne .LBB16_1
576; X64-NEXT: # BB#3: # %endblock
577; X64-NEXT: retq
578; X64-NEXT: .LBB16_1: # %res_block
579; X64-NEXT: cmpq %rdx, %rcx
580; X64-NEXT: movl $-1, %ecx
581; X64-NEXT: movl $1, %eax
582; X64-NEXT: cmovbl %ecx, %eax
583; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000584 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 16) nounwind
585 ret i32 %m
586}
587
588define i1 @length16_eq(i8* %x, i8* %y) nounwind optsize {
589; X86-NOSSE-LABEL: length16_eq:
590; X86-NOSSE: # BB#0:
591; X86-NOSSE-NEXT: pushl $0
592; X86-NOSSE-NEXT: pushl $16
593; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
594; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
595; X86-NOSSE-NEXT: calll memcmp
596; X86-NOSSE-NEXT: addl $16, %esp
597; X86-NOSSE-NEXT: testl %eax, %eax
598; X86-NOSSE-NEXT: setne %al
599; X86-NOSSE-NEXT: retl
600;
601; X86-SSE2-LABEL: length16_eq:
602; X86-SSE2: # BB#0:
603; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
604; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
605; X86-SSE2-NEXT: movdqu (%ecx), %xmm0
606; X86-SSE2-NEXT: movdqu (%eax), %xmm1
607; X86-SSE2-NEXT: pcmpeqb %xmm0, %xmm1
608; X86-SSE2-NEXT: pmovmskb %xmm1, %eax
609; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
610; X86-SSE2-NEXT: setne %al
611; X86-SSE2-NEXT: retl
612;
Simon Pilgrim483927a2017-07-18 15:55:30 +0000613; X64-LABEL: length16_eq:
614; X64: # BB#0: # %loadbb
615; X64-NEXT: movq (%rdi), %rax
616; X64-NEXT: cmpq (%rsi), %rax
617; X64-NEXT: jne .LBB17_1
618; X64-NEXT: # BB#2: # %loadbb1
619; X64-NEXT: movq 8(%rdi), %rcx
620; X64-NEXT: xorl %eax, %eax
621; X64-NEXT: cmpq 8(%rsi), %rcx
622; X64-NEXT: je .LBB17_3
623; X64-NEXT: .LBB17_1: # %res_block
624; X64-NEXT: movl $1, %eax
625; X64-NEXT: .LBB17_3: # %endblock
626; X64-NEXT: testl %eax, %eax
627; X64-NEXT: setne %al
628; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000629 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 16) nounwind
630 %cmp = icmp ne i32 %call, 0
631 ret i1 %cmp
632}
633
634define i1 @length16_eq_const(i8* %X) nounwind optsize {
635; X86-NOSSE-LABEL: length16_eq_const:
636; X86-NOSSE: # BB#0:
637; X86-NOSSE-NEXT: pushl $0
638; X86-NOSSE-NEXT: pushl $16
639; X86-NOSSE-NEXT: pushl $.L.str
640; X86-NOSSE-NEXT: pushl {{[0-9]+}}(%esp)
641; X86-NOSSE-NEXT: calll memcmp
642; X86-NOSSE-NEXT: addl $16, %esp
643; X86-NOSSE-NEXT: testl %eax, %eax
644; X86-NOSSE-NEXT: sete %al
645; X86-NOSSE-NEXT: retl
646;
647; X86-SSE2-LABEL: length16_eq_const:
648; X86-SSE2: # BB#0:
649; X86-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
650; X86-SSE2-NEXT: movdqu (%eax), %xmm0
651; X86-SSE2-NEXT: pcmpeqb {{\.LCPI.*}}, %xmm0
652; X86-SSE2-NEXT: pmovmskb %xmm0, %eax
653; X86-SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
654; X86-SSE2-NEXT: sete %al
655; X86-SSE2-NEXT: retl
656;
Simon Pilgrim483927a2017-07-18 15:55:30 +0000657; X64-LABEL: length16_eq_const:
658; X64: # BB#0: # %loadbb
659; X64-NEXT: movabsq $3978425819141910832, %rax # imm = 0x3736353433323130
660; X64-NEXT: cmpq %rax, (%rdi)
661; X64-NEXT: jne .LBB18_1
662; X64-NEXT: # BB#2: # %loadbb1
663; X64-NEXT: xorl %eax, %eax
664; X64-NEXT: movabsq $3833745473465760056, %rcx # imm = 0x3534333231303938
665; X64-NEXT: cmpq %rcx, 8(%rdi)
666; X64-NEXT: je .LBB18_3
667; X64-NEXT: .LBB18_1: # %res_block
668; X64-NEXT: movl $1, %eax
669; X64-NEXT: .LBB18_3: # %endblock
670; X64-NEXT: testl %eax, %eax
671; X64-NEXT: sete %al
672; X64-NEXT: retq
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000673 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 16) nounwind
674 %c = icmp eq i32 %m, 0
675 ret i1 %c
676}
677
Simon Pilgrim3459f102017-07-25 10:33:36 +0000678; PR33914 - https://bugs.llvm.org/show_bug.cgi?id=33914
679
680define i32 @length24(i8* %X, i8* %Y) nounwind optsize {
681; X86-LABEL: length24:
682; X86: # BB#0:
683; X86-NEXT: pushl $0
684; X86-NEXT: pushl $24
685; X86-NEXT: pushl {{[0-9]+}}(%esp)
686; X86-NEXT: pushl {{[0-9]+}}(%esp)
687; X86-NEXT: calll memcmp
688; X86-NEXT: addl $16, %esp
689; X86-NEXT: retl
690;
691; X64-LABEL: length24:
692; X64: # BB#0:
693; X64-NEXT: movl $24, %edx
694; X64-NEXT: jmp memcmp # TAILCALL
695 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 24) nounwind
696 ret i32 %m
697}
698
699define i1 @length24_eq(i8* %x, i8* %y) nounwind optsize {
700; X86-LABEL: length24_eq:
701; X86: # BB#0:
702; X86-NEXT: pushl $0
703; X86-NEXT: pushl $24
704; X86-NEXT: pushl {{[0-9]+}}(%esp)
705; X86-NEXT: pushl {{[0-9]+}}(%esp)
706; X86-NEXT: calll memcmp
707; X86-NEXT: addl $16, %esp
708; X86-NEXT: testl %eax, %eax
709; X86-NEXT: sete %al
710; X86-NEXT: retl
711;
712; X64-LABEL: length24_eq:
713; X64: # BB#0:
714; X64-NEXT: pushq %rax
715; X64-NEXT: movl $24, %edx
716; X64-NEXT: callq memcmp
717; X64-NEXT: testl %eax, %eax
718; X64-NEXT: sete %al
719; X64-NEXT: popq %rcx
720; X64-NEXT: retq
721 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 24) nounwind
722 %cmp = icmp eq i32 %call, 0
723 ret i1 %cmp
724}
725
726define i1 @length24_eq_const(i8* %X) nounwind optsize {
727; X86-LABEL: length24_eq_const:
728; X86: # BB#0:
729; X86-NEXT: pushl $0
730; X86-NEXT: pushl $24
731; X86-NEXT: pushl $.L.str
732; X86-NEXT: pushl {{[0-9]+}}(%esp)
733; X86-NEXT: calll memcmp
734; X86-NEXT: addl $16, %esp
735; X86-NEXT: testl %eax, %eax
736; X86-NEXT: setne %al
737; X86-NEXT: retl
738;
739; X64-LABEL: length24_eq_const:
740; X64: # BB#0:
741; X64-NEXT: pushq %rax
742; X64-NEXT: movl $.L.str, %esi
743; X64-NEXT: movl $24, %edx
744; X64-NEXT: callq memcmp
745; X64-NEXT: testl %eax, %eax
746; X64-NEXT: setne %al
747; X64-NEXT: popq %rcx
748; X64-NEXT: retq
749 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 24) nounwind
750 %c = icmp ne i32 %m, 0
751 ret i1 %c
752}
753
Simon Pilgrimc2cbb522017-07-18 14:26:07 +0000754define i32 @length32(i8* %X, i8* %Y) nounwind optsize {
755; X86-LABEL: length32:
756; X86: # BB#0:
757; X86-NEXT: pushl $0
758; X86-NEXT: pushl $32
759; X86-NEXT: pushl {{[0-9]+}}(%esp)
760; X86-NEXT: pushl {{[0-9]+}}(%esp)
761; X86-NEXT: calll memcmp
762; X86-NEXT: addl $16, %esp
763; X86-NEXT: retl
764;
765; X64-LABEL: length32:
766; X64: # BB#0:
767; X64-NEXT: movl $32, %edx
768; X64-NEXT: jmp memcmp # TAILCALL
769 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 32) nounwind
770 ret i32 %m
771}
772
773; PR33325 - https://bugs.llvm.org/show_bug.cgi?id=33325
774
775define i1 @length32_eq(i8* %x, i8* %y) nounwind optsize {
776; X86-LABEL: length32_eq:
777; X86: # BB#0:
778; X86-NEXT: pushl $0
779; X86-NEXT: pushl $32
780; X86-NEXT: pushl {{[0-9]+}}(%esp)
781; X86-NEXT: pushl {{[0-9]+}}(%esp)
782; X86-NEXT: calll memcmp
783; X86-NEXT: addl $16, %esp
784; X86-NEXT: testl %eax, %eax
785; X86-NEXT: sete %al
786; X86-NEXT: retl
787;
788; X64-SSE2-LABEL: length32_eq:
789; X64-SSE2: # BB#0:
790; X64-SSE2-NEXT: pushq %rax
791; X64-SSE2-NEXT: movl $32, %edx
792; X64-SSE2-NEXT: callq memcmp
793; X64-SSE2-NEXT: testl %eax, %eax
794; X64-SSE2-NEXT: sete %al
795; X64-SSE2-NEXT: popq %rcx
796; X64-SSE2-NEXT: retq
797;
798; X64-AVX2-LABEL: length32_eq:
799; X64-AVX2: # BB#0:
800; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
801; X64-AVX2-NEXT: vpcmpeqb (%rsi), %ymm0, %ymm0
802; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
803; X64-AVX2-NEXT: cmpl $-1, %eax
804; X64-AVX2-NEXT: sete %al
805; X64-AVX2-NEXT: vzeroupper
806; X64-AVX2-NEXT: retq
807 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 32) nounwind
808 %cmp = icmp eq i32 %call, 0
809 ret i1 %cmp
810}
811
812define i1 @length32_eq_const(i8* %X) nounwind optsize {
813; X86-LABEL: length32_eq_const:
814; X86: # BB#0:
815; X86-NEXT: pushl $0
816; X86-NEXT: pushl $32
817; X86-NEXT: pushl $.L.str
818; X86-NEXT: pushl {{[0-9]+}}(%esp)
819; X86-NEXT: calll memcmp
820; X86-NEXT: addl $16, %esp
821; X86-NEXT: testl %eax, %eax
822; X86-NEXT: setne %al
823; X86-NEXT: retl
824;
825; X64-SSE2-LABEL: length32_eq_const:
826; X64-SSE2: # BB#0:
827; X64-SSE2-NEXT: pushq %rax
828; X64-SSE2-NEXT: movl $.L.str, %esi
829; X64-SSE2-NEXT: movl $32, %edx
830; X64-SSE2-NEXT: callq memcmp
831; X64-SSE2-NEXT: testl %eax, %eax
832; X64-SSE2-NEXT: setne %al
833; X64-SSE2-NEXT: popq %rcx
834; X64-SSE2-NEXT: retq
835;
836; X64-AVX2-LABEL: length32_eq_const:
837; X64-AVX2: # BB#0:
838; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0
839; X64-AVX2-NEXT: vpcmpeqb {{.*}}(%rip), %ymm0, %ymm0
840; X64-AVX2-NEXT: vpmovmskb %ymm0, %eax
841; X64-AVX2-NEXT: cmpl $-1, %eax
842; X64-AVX2-NEXT: setne %al
843; X64-AVX2-NEXT: vzeroupper
844; X64-AVX2-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 32) nounwind
846 %c = icmp ne i32 %m, 0
847 ret i1 %c
848}
849
850define i32 @length64(i8* %X, i8* %Y) nounwind optsize {
851; X86-LABEL: length64:
852; X86: # BB#0:
853; X86-NEXT: pushl $0
854; X86-NEXT: pushl $64
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: length64:
862; X64: # BB#0:
863; X64-NEXT: movl $64, %edx
864; X64-NEXT: jmp memcmp # TAILCALL
865 %m = tail call i32 @memcmp(i8* %X, i8* %Y, i64 64) nounwind
866 ret i32 %m
867}
868
869define i1 @length64_eq(i8* %x, i8* %y) nounwind optsize {
870; X86-LABEL: length64_eq:
871; X86: # BB#0:
872; X86-NEXT: pushl $0
873; X86-NEXT: pushl $64
874; X86-NEXT: pushl {{[0-9]+}}(%esp)
875; X86-NEXT: pushl {{[0-9]+}}(%esp)
876; X86-NEXT: calll memcmp
877; X86-NEXT: addl $16, %esp
878; X86-NEXT: testl %eax, %eax
879; X86-NEXT: setne %al
880; X86-NEXT: retl
881;
882; X64-LABEL: length64_eq:
883; X64: # BB#0:
884; X64-NEXT: pushq %rax
885; X64-NEXT: movl $64, %edx
886; X64-NEXT: callq memcmp
887; X64-NEXT: testl %eax, %eax
888; X64-NEXT: setne %al
889; X64-NEXT: popq %rcx
890; X64-NEXT: retq
891 %call = tail call i32 @memcmp(i8* %x, i8* %y, i64 64) nounwind
892 %cmp = icmp ne i32 %call, 0
893 ret i1 %cmp
894}
895
896define i1 @length64_eq_const(i8* %X) nounwind optsize {
897; X86-LABEL: length64_eq_const:
898; X86: # BB#0:
899; X86-NEXT: pushl $0
900; X86-NEXT: pushl $64
901; X86-NEXT: pushl $.L.str
902; X86-NEXT: pushl {{[0-9]+}}(%esp)
903; X86-NEXT: calll memcmp
904; X86-NEXT: addl $16, %esp
905; X86-NEXT: testl %eax, %eax
906; X86-NEXT: sete %al
907; X86-NEXT: retl
908;
909; X64-LABEL: length64_eq_const:
910; X64: # BB#0:
911; X64-NEXT: pushq %rax
912; X64-NEXT: movl $.L.str, %esi
913; X64-NEXT: movl $64, %edx
914; X64-NEXT: callq memcmp
915; X64-NEXT: testl %eax, %eax
916; X64-NEXT: sete %al
917; X64-NEXT: popq %rcx
918; X64-NEXT: retq
919 %m = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i32 0, i32 0), i64 64) nounwind
920 %c = icmp eq i32 %m, 0
921 ret i1 %c
922}
923