comparison test/CodeGen/X86/memcmp.ll @ 121:803732b1fca8

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