[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / clear-highbits.ll
blobb23a69625b3543eadd7cf33ae04e13c44b50552c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK0,X86-FALLBACK0
3 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK1,X86-FALLBACK1
4 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK2,X86-FALLBACK2
5 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI2,X86-BMI2,FALLBACK3,X86-FALLBACK3
6 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI2,X86-BMI2,FALLBACK4,X86-FALLBACK4
7 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK0,X64-FALLBACK0
8 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK1,X64-FALLBACK1
9 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK2,X64-FALLBACK2
10 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI2,X64-BMI2,FALLBACK3,X64-FALLBACK3
11 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI2,X64-BMI2,FALLBACK4,X64-FALLBACK4
13 ; Patterns:
14 ;    c) x &  (-1 >> y)
15 ;    d) x << y >> y
16 ; are equivalent, but we prefer the second variant if we have BMI2.
18 ; We do not test the variant where y = (32 - z), because that is BMI2's BZHI.
20 ; ---------------------------------------------------------------------------- ;
21 ; 8-bit
22 ; ---------------------------------------------------------------------------- ;
24 define i8 @clear_highbits8_c0(i8 %val, i8 %numhighbits) nounwind {
25 ; X86-LABEL: clear_highbits8_c0:
26 ; X86:       # %bb.0:
27 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
28 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
29 ; X86-NEXT:    shlb %cl, %al
30 ; X86-NEXT:    shrb %cl, %al
31 ; X86-NEXT:    retl
33 ; X64-LABEL: clear_highbits8_c0:
34 ; X64:       # %bb.0:
35 ; X64-NEXT:    movl %esi, %ecx
36 ; X64-NEXT:    movl %edi, %eax
37 ; X64-NEXT:    shlb %cl, %al
38 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
39 ; X64-NEXT:    shrb %cl, %al
40 ; X64-NEXT:    # kill: def $al killed $al killed $eax
41 ; X64-NEXT:    retq
42   %mask = lshr i8 -1, %numhighbits
43   %masked = and i8 %mask, %val
44   ret i8 %masked
47 define i8 @clear_highbits8_c2_load(i8* %w, i8 %numhighbits) nounwind {
48 ; X86-LABEL: clear_highbits8_c2_load:
49 ; X86:       # %bb.0:
50 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
51 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
52 ; X86-NEXT:    movb (%eax), %al
53 ; X86-NEXT:    shlb %cl, %al
54 ; X86-NEXT:    shrb %cl, %al
55 ; X86-NEXT:    retl
57 ; X64-LABEL: clear_highbits8_c2_load:
58 ; X64:       # %bb.0:
59 ; X64-NEXT:    movl %esi, %ecx
60 ; X64-NEXT:    movb (%rdi), %al
61 ; X64-NEXT:    shlb %cl, %al
62 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
63 ; X64-NEXT:    shrb %cl, %al
64 ; X64-NEXT:    retq
65   %val = load i8, i8* %w
66   %mask = lshr i8 -1, %numhighbits
67   %masked = and i8 %mask, %val
68   ret i8 %masked
71 define i8 @clear_highbits8_c4_commutative(i8 %val, i8 %numhighbits) nounwind {
72 ; X86-LABEL: clear_highbits8_c4_commutative:
73 ; X86:       # %bb.0:
74 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
75 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
76 ; X86-NEXT:    shlb %cl, %al
77 ; X86-NEXT:    shrb %cl, %al
78 ; X86-NEXT:    retl
80 ; X64-LABEL: clear_highbits8_c4_commutative:
81 ; X64:       # %bb.0:
82 ; X64-NEXT:    movl %esi, %ecx
83 ; X64-NEXT:    movl %edi, %eax
84 ; X64-NEXT:    shlb %cl, %al
85 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
86 ; X64-NEXT:    shrb %cl, %al
87 ; X64-NEXT:    # kill: def $al killed $al killed $eax
88 ; X64-NEXT:    retq
89   %mask = lshr i8 -1, %numhighbits
90   %masked = and i8 %val, %mask ; swapped order
91   ret i8 %masked
94 ; ---------------------------------------------------------------------------- ;
95 ; 16-bit
96 ; ---------------------------------------------------------------------------- ;
98 define i16 @clear_highbits16_c0(i16 %val, i16 %numhighbits) nounwind {
99 ; X86-NOBMI2-LABEL: clear_highbits16_c0:
100 ; X86-NOBMI2:       # %bb.0:
101 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
102 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
103 ; X86-NOBMI2-NEXT:    shll %cl, %eax
104 ; X86-NOBMI2-NEXT:    movzwl %ax, %eax
105 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
106 ; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
107 ; X86-NOBMI2-NEXT:    retl
109 ; X86-BMI2-LABEL: clear_highbits16_c0:
110 ; X86-BMI2:       # %bb.0:
111 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
112 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
113 ; X86-BMI2-NEXT:    movzwl %cx, %ecx
114 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
115 ; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
116 ; X86-BMI2-NEXT:    retl
118 ; X64-NOBMI2-LABEL: clear_highbits16_c0:
119 ; X64-NOBMI2:       # %bb.0:
120 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
121 ; X64-NOBMI2-NEXT:    shll %cl, %edi
122 ; X64-NOBMI2-NEXT:    movzwl %di, %eax
123 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
124 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
125 ; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
126 ; X64-NOBMI2-NEXT:    retq
128 ; X64-BMI2-LABEL: clear_highbits16_c0:
129 ; X64-BMI2:       # %bb.0:
130 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
131 ; X64-BMI2-NEXT:    movzwl %ax, %eax
132 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
133 ; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
134 ; X64-BMI2-NEXT:    retq
135   %mask = lshr i16 -1, %numhighbits
136   %masked = and i16 %mask, %val
137   ret i16 %masked
140 define i16 @clear_highbits16_c1_indexzext(i16 %val, i8 %numhighbits) nounwind {
141 ; X86-NOBMI2-LABEL: clear_highbits16_c1_indexzext:
142 ; X86-NOBMI2:       # %bb.0:
143 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
144 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
145 ; X86-NOBMI2-NEXT:    shll %cl, %eax
146 ; X86-NOBMI2-NEXT:    movzwl %ax, %eax
147 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
148 ; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
149 ; X86-NOBMI2-NEXT:    retl
151 ; X86-BMI2-LABEL: clear_highbits16_c1_indexzext:
152 ; X86-BMI2:       # %bb.0:
153 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
154 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
155 ; X86-BMI2-NEXT:    movzwl %cx, %ecx
156 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
157 ; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
158 ; X86-BMI2-NEXT:    retl
160 ; X64-NOBMI2-LABEL: clear_highbits16_c1_indexzext:
161 ; X64-NOBMI2:       # %bb.0:
162 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
163 ; X64-NOBMI2-NEXT:    shll %cl, %edi
164 ; X64-NOBMI2-NEXT:    movzwl %di, %eax
165 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
166 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
167 ; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
168 ; X64-NOBMI2-NEXT:    retq
170 ; X64-BMI2-LABEL: clear_highbits16_c1_indexzext:
171 ; X64-BMI2:       # %bb.0:
172 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
173 ; X64-BMI2-NEXT:    movzwl %ax, %eax
174 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
175 ; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
176 ; X64-BMI2-NEXT:    retq
177   %sh_prom = zext i8 %numhighbits to i16
178   %mask = lshr i16 -1, %sh_prom
179   %masked = and i16 %mask, %val
180   ret i16 %masked
183 define i16 @clear_highbits16_c2_load(i16* %w, i16 %numhighbits) nounwind {
184 ; X86-NOBMI2-LABEL: clear_highbits16_c2_load:
185 ; X86-NOBMI2:       # %bb.0:
186 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
187 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
188 ; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
189 ; X86-NOBMI2-NEXT:    shll %cl, %eax
190 ; X86-NOBMI2-NEXT:    movzwl %ax, %eax
191 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
192 ; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
193 ; X86-NOBMI2-NEXT:    retl
195 ; X86-BMI2-LABEL: clear_highbits16_c2_load:
196 ; X86-BMI2:       # %bb.0:
197 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
198 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
199 ; X86-BMI2-NEXT:    movzwl (%ecx), %ecx
200 ; X86-BMI2-NEXT:    shlxl %eax, %ecx, %ecx
201 ; X86-BMI2-NEXT:    movzwl %cx, %ecx
202 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
203 ; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
204 ; X86-BMI2-NEXT:    retl
206 ; X64-NOBMI2-LABEL: clear_highbits16_c2_load:
207 ; X64-NOBMI2:       # %bb.0:
208 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
209 ; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
210 ; X64-NOBMI2-NEXT:    shll %cl, %eax
211 ; X64-NOBMI2-NEXT:    movzwl %ax, %eax
212 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
213 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
214 ; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
215 ; X64-NOBMI2-NEXT:    retq
217 ; X64-BMI2-LABEL: clear_highbits16_c2_load:
218 ; X64-BMI2:       # %bb.0:
219 ; X64-BMI2-NEXT:    movzwl (%rdi), %eax
220 ; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
221 ; X64-BMI2-NEXT:    movzwl %ax, %eax
222 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
223 ; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
224 ; X64-BMI2-NEXT:    retq
225   %val = load i16, i16* %w
226   %mask = lshr i16 -1, %numhighbits
227   %masked = and i16 %mask, %val
228   ret i16 %masked
231 define i16 @clear_highbits16_c3_load_indexzext(i16* %w, i8 %numhighbits) nounwind {
232 ; X86-NOBMI2-LABEL: clear_highbits16_c3_load_indexzext:
233 ; X86-NOBMI2:       # %bb.0:
234 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
235 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
236 ; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
237 ; X86-NOBMI2-NEXT:    shll %cl, %eax
238 ; X86-NOBMI2-NEXT:    movzwl %ax, %eax
239 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
240 ; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
241 ; X86-NOBMI2-NEXT:    retl
243 ; X86-BMI2-LABEL: clear_highbits16_c3_load_indexzext:
244 ; X86-BMI2:       # %bb.0:
245 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
246 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
247 ; X86-BMI2-NEXT:    movzwl (%ecx), %ecx
248 ; X86-BMI2-NEXT:    shlxl %eax, %ecx, %ecx
249 ; X86-BMI2-NEXT:    movzwl %cx, %ecx
250 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
251 ; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
252 ; X86-BMI2-NEXT:    retl
254 ; X64-NOBMI2-LABEL: clear_highbits16_c3_load_indexzext:
255 ; X64-NOBMI2:       # %bb.0:
256 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
257 ; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
258 ; X64-NOBMI2-NEXT:    shll %cl, %eax
259 ; X64-NOBMI2-NEXT:    movzwl %ax, %eax
260 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
261 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
262 ; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
263 ; X64-NOBMI2-NEXT:    retq
265 ; X64-BMI2-LABEL: clear_highbits16_c3_load_indexzext:
266 ; X64-BMI2:       # %bb.0:
267 ; X64-BMI2-NEXT:    movzwl (%rdi), %eax
268 ; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
269 ; X64-BMI2-NEXT:    movzwl %ax, %eax
270 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
271 ; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
272 ; X64-BMI2-NEXT:    retq
273   %val = load i16, i16* %w
274   %sh_prom = zext i8 %numhighbits to i16
275   %mask = lshr i16 -1, %sh_prom
276   %masked = and i16 %mask, %val
277   ret i16 %masked
280 define i16 @clear_highbits16_c4_commutative(i16 %val, i16 %numhighbits) nounwind {
281 ; X86-NOBMI2-LABEL: clear_highbits16_c4_commutative:
282 ; X86-NOBMI2:       # %bb.0:
283 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
284 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
285 ; X86-NOBMI2-NEXT:    shll %cl, %eax
286 ; X86-NOBMI2-NEXT:    movzwl %ax, %eax
287 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
288 ; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
289 ; X86-NOBMI2-NEXT:    retl
291 ; X86-BMI2-LABEL: clear_highbits16_c4_commutative:
292 ; X86-BMI2:       # %bb.0:
293 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
294 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
295 ; X86-BMI2-NEXT:    movzwl %cx, %ecx
296 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
297 ; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
298 ; X86-BMI2-NEXT:    retl
300 ; X64-NOBMI2-LABEL: clear_highbits16_c4_commutative:
301 ; X64-NOBMI2:       # %bb.0:
302 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
303 ; X64-NOBMI2-NEXT:    shll %cl, %edi
304 ; X64-NOBMI2-NEXT:    movzwl %di, %eax
305 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
306 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
307 ; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
308 ; X64-NOBMI2-NEXT:    retq
310 ; X64-BMI2-LABEL: clear_highbits16_c4_commutative:
311 ; X64-BMI2:       # %bb.0:
312 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
313 ; X64-BMI2-NEXT:    movzwl %ax, %eax
314 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
315 ; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
316 ; X64-BMI2-NEXT:    retq
317   %mask = lshr i16 -1, %numhighbits
318   %masked = and i16 %val, %mask ; swapped order
319   ret i16 %masked
322 ; ---------------------------------------------------------------------------- ;
323 ; 32-bit
324 ; ---------------------------------------------------------------------------- ;
326 define i32 @clear_highbits32_c0(i32 %val, i32 %numhighbits) nounwind {
327 ; X86-NOBMI2-LABEL: clear_highbits32_c0:
328 ; X86-NOBMI2:       # %bb.0:
329 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
330 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
331 ; X86-NOBMI2-NEXT:    shll %cl, %eax
332 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
333 ; X86-NOBMI2-NEXT:    retl
335 ; X86-BMI2-LABEL: clear_highbits32_c0:
336 ; X86-BMI2:       # %bb.0:
337 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
338 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
339 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
340 ; X86-BMI2-NEXT:    retl
342 ; X64-NOBMI2-LABEL: clear_highbits32_c0:
343 ; X64-NOBMI2:       # %bb.0:
344 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
345 ; X64-NOBMI2-NEXT:    movl %edi, %eax
346 ; X64-NOBMI2-NEXT:    shll %cl, %eax
347 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
348 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
349 ; X64-NOBMI2-NEXT:    retq
351 ; X64-BMI2-LABEL: clear_highbits32_c0:
352 ; X64-BMI2:       # %bb.0:
353 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
354 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
355 ; X64-BMI2-NEXT:    retq
356   %mask = lshr i32 -1, %numhighbits
357   %masked = and i32 %mask, %val
358   ret i32 %masked
361 define i32 @clear_highbits32_c1_indexzext(i32 %val, i8 %numhighbits) nounwind {
362 ; X86-NOBMI2-LABEL: clear_highbits32_c1_indexzext:
363 ; X86-NOBMI2:       # %bb.0:
364 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
365 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
366 ; X86-NOBMI2-NEXT:    shll %cl, %eax
367 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
368 ; X86-NOBMI2-NEXT:    retl
370 ; X86-BMI2-LABEL: clear_highbits32_c1_indexzext:
371 ; X86-BMI2:       # %bb.0:
372 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
373 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
374 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
375 ; X86-BMI2-NEXT:    retl
377 ; X64-NOBMI2-LABEL: clear_highbits32_c1_indexzext:
378 ; X64-NOBMI2:       # %bb.0:
379 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
380 ; X64-NOBMI2-NEXT:    movl %edi, %eax
381 ; X64-NOBMI2-NEXT:    shll %cl, %eax
382 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
383 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
384 ; X64-NOBMI2-NEXT:    retq
386 ; X64-BMI2-LABEL: clear_highbits32_c1_indexzext:
387 ; X64-BMI2:       # %bb.0:
388 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
389 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
390 ; X64-BMI2-NEXT:    retq
391   %sh_prom = zext i8 %numhighbits to i32
392   %mask = lshr i32 -1, %sh_prom
393   %masked = and i32 %mask, %val
394   ret i32 %masked
397 define i32 @clear_highbits32_c2_load(i32* %w, i32 %numhighbits) nounwind {
398 ; X86-NOBMI2-LABEL: clear_highbits32_c2_load:
399 ; X86-NOBMI2:       # %bb.0:
400 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
401 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
402 ; X86-NOBMI2-NEXT:    movl (%eax), %eax
403 ; X86-NOBMI2-NEXT:    shll %cl, %eax
404 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
405 ; X86-NOBMI2-NEXT:    retl
407 ; X86-BMI2-LABEL: clear_highbits32_c2_load:
408 ; X86-BMI2:       # %bb.0:
409 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
410 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
411 ; X86-BMI2-NEXT:    shlxl %ecx, (%eax), %eax
412 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
413 ; X86-BMI2-NEXT:    retl
415 ; X64-NOBMI2-LABEL: clear_highbits32_c2_load:
416 ; X64-NOBMI2:       # %bb.0:
417 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
418 ; X64-NOBMI2-NEXT:    movl (%rdi), %eax
419 ; X64-NOBMI2-NEXT:    shll %cl, %eax
420 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
421 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
422 ; X64-NOBMI2-NEXT:    retq
424 ; X64-BMI2-LABEL: clear_highbits32_c2_load:
425 ; X64-BMI2:       # %bb.0:
426 ; X64-BMI2-NEXT:    shlxl %esi, (%rdi), %eax
427 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
428 ; X64-BMI2-NEXT:    retq
429   %val = load i32, i32* %w
430   %mask = lshr i32 -1, %numhighbits
431   %masked = and i32 %mask, %val
432   ret i32 %masked
435 define i32 @clear_highbits32_c3_load_indexzext(i32* %w, i8 %numhighbits) nounwind {
436 ; X86-NOBMI2-LABEL: clear_highbits32_c3_load_indexzext:
437 ; X86-NOBMI2:       # %bb.0:
438 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
439 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
440 ; X86-NOBMI2-NEXT:    movl (%eax), %eax
441 ; X86-NOBMI2-NEXT:    shll %cl, %eax
442 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
443 ; X86-NOBMI2-NEXT:    retl
445 ; X86-BMI2-LABEL: clear_highbits32_c3_load_indexzext:
446 ; X86-BMI2:       # %bb.0:
447 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
448 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
449 ; X86-BMI2-NEXT:    shlxl %ecx, (%eax), %eax
450 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
451 ; X86-BMI2-NEXT:    retl
453 ; X64-NOBMI2-LABEL: clear_highbits32_c3_load_indexzext:
454 ; X64-NOBMI2:       # %bb.0:
455 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
456 ; X64-NOBMI2-NEXT:    movl (%rdi), %eax
457 ; X64-NOBMI2-NEXT:    shll %cl, %eax
458 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
459 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
460 ; X64-NOBMI2-NEXT:    retq
462 ; X64-BMI2-LABEL: clear_highbits32_c3_load_indexzext:
463 ; X64-BMI2:       # %bb.0:
464 ; X64-BMI2-NEXT:    shlxl %esi, (%rdi), %eax
465 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
466 ; X64-BMI2-NEXT:    retq
467   %val = load i32, i32* %w
468   %sh_prom = zext i8 %numhighbits to i32
469   %mask = lshr i32 -1, %sh_prom
470   %masked = and i32 %mask, %val
471   ret i32 %masked
474 define i32 @clear_highbits32_c4_commutative(i32 %val, i32 %numhighbits) nounwind {
475 ; X86-NOBMI2-LABEL: clear_highbits32_c4_commutative:
476 ; X86-NOBMI2:       # %bb.0:
477 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
478 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
479 ; X86-NOBMI2-NEXT:    shll %cl, %eax
480 ; X86-NOBMI2-NEXT:    shrl %cl, %eax
481 ; X86-NOBMI2-NEXT:    retl
483 ; X86-BMI2-LABEL: clear_highbits32_c4_commutative:
484 ; X86-BMI2:       # %bb.0:
485 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
486 ; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
487 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
488 ; X86-BMI2-NEXT:    retl
490 ; X64-NOBMI2-LABEL: clear_highbits32_c4_commutative:
491 ; X64-NOBMI2:       # %bb.0:
492 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
493 ; X64-NOBMI2-NEXT:    movl %edi, %eax
494 ; X64-NOBMI2-NEXT:    shll %cl, %eax
495 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
496 ; X64-NOBMI2-NEXT:    shrl %cl, %eax
497 ; X64-NOBMI2-NEXT:    retq
499 ; X64-BMI2-LABEL: clear_highbits32_c4_commutative:
500 ; X64-BMI2:       # %bb.0:
501 ; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
502 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
503 ; X64-BMI2-NEXT:    retq
504   %mask = lshr i32 -1, %numhighbits
505   %masked = and i32 %val, %mask ; swapped order
506   ret i32 %masked
509 ; ---------------------------------------------------------------------------- ;
510 ; 64-bit
511 ; ---------------------------------------------------------------------------- ;
513 define i64 @clear_highbits64_c0(i64 %val, i64 %numhighbits) nounwind {
514 ; X86-NOBMI2-LABEL: clear_highbits64_c0:
515 ; X86-NOBMI2:       # %bb.0:
516 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
517 ; X86-NOBMI2-NEXT:    movl $-1, %eax
518 ; X86-NOBMI2-NEXT:    movl $-1, %edx
519 ; X86-NOBMI2-NEXT:    shrl %cl, %edx
520 ; X86-NOBMI2-NEXT:    shrdl %cl, %eax, %eax
521 ; X86-NOBMI2-NEXT:    testb $32, %cl
522 ; X86-NOBMI2-NEXT:    je .LBB13_2
523 ; X86-NOBMI2-NEXT:  # %bb.1:
524 ; X86-NOBMI2-NEXT:    movl %edx, %eax
525 ; X86-NOBMI2-NEXT:    xorl %edx, %edx
526 ; X86-NOBMI2-NEXT:  .LBB13_2:
527 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
528 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
529 ; X86-NOBMI2-NEXT:    retl
531 ; X86-BMI2-LABEL: clear_highbits64_c0:
532 ; X86-BMI2:       # %bb.0:
533 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
534 ; X86-BMI2-NEXT:    movl $-1, %eax
535 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
536 ; X86-BMI2-NEXT:    shrdl %cl, %eax, %eax
537 ; X86-BMI2-NEXT:    testb $32, %cl
538 ; X86-BMI2-NEXT:    je .LBB13_2
539 ; X86-BMI2-NEXT:  # %bb.1:
540 ; X86-BMI2-NEXT:    movl %edx, %eax
541 ; X86-BMI2-NEXT:    xorl %edx, %edx
542 ; X86-BMI2-NEXT:  .LBB13_2:
543 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
544 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
545 ; X86-BMI2-NEXT:    retl
547 ; X64-NOBMI2-LABEL: clear_highbits64_c0:
548 ; X64-NOBMI2:       # %bb.0:
549 ; X64-NOBMI2-NEXT:    movq %rsi, %rcx
550 ; X64-NOBMI2-NEXT:    movq %rdi, %rax
551 ; X64-NOBMI2-NEXT:    shlq %cl, %rax
552 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
553 ; X64-NOBMI2-NEXT:    shrq %cl, %rax
554 ; X64-NOBMI2-NEXT:    retq
556 ; X64-BMI2-LABEL: clear_highbits64_c0:
557 ; X64-BMI2:       # %bb.0:
558 ; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
559 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rax
560 ; X64-BMI2-NEXT:    retq
561   %mask = lshr i64 -1, %numhighbits
562   %masked = and i64 %mask, %val
563   ret i64 %masked
566 define i64 @clear_highbits64_c1_indexzext(i64 %val, i8 %numhighbits) nounwind {
567 ; X86-NOBMI2-LABEL: clear_highbits64_c1_indexzext:
568 ; X86-NOBMI2:       # %bb.0:
569 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
570 ; X86-NOBMI2-NEXT:    movl $-1, %eax
571 ; X86-NOBMI2-NEXT:    movl $-1, %edx
572 ; X86-NOBMI2-NEXT:    shrl %cl, %edx
573 ; X86-NOBMI2-NEXT:    shrdl %cl, %eax, %eax
574 ; X86-NOBMI2-NEXT:    testb $32, %cl
575 ; X86-NOBMI2-NEXT:    je .LBB14_2
576 ; X86-NOBMI2-NEXT:  # %bb.1:
577 ; X86-NOBMI2-NEXT:    movl %edx, %eax
578 ; X86-NOBMI2-NEXT:    xorl %edx, %edx
579 ; X86-NOBMI2-NEXT:  .LBB14_2:
580 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
581 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
582 ; X86-NOBMI2-NEXT:    retl
584 ; X86-BMI2-LABEL: clear_highbits64_c1_indexzext:
585 ; X86-BMI2:       # %bb.0:
586 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
587 ; X86-BMI2-NEXT:    movl $-1, %eax
588 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
589 ; X86-BMI2-NEXT:    shrdl %cl, %eax, %eax
590 ; X86-BMI2-NEXT:    testb $32, %cl
591 ; X86-BMI2-NEXT:    je .LBB14_2
592 ; X86-BMI2-NEXT:  # %bb.1:
593 ; X86-BMI2-NEXT:    movl %edx, %eax
594 ; X86-BMI2-NEXT:    xorl %edx, %edx
595 ; X86-BMI2-NEXT:  .LBB14_2:
596 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
597 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
598 ; X86-BMI2-NEXT:    retl
600 ; X64-NOBMI2-LABEL: clear_highbits64_c1_indexzext:
601 ; X64-NOBMI2:       # %bb.0:
602 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
603 ; X64-NOBMI2-NEXT:    movq %rdi, %rax
604 ; X64-NOBMI2-NEXT:    shlq %cl, %rax
605 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
606 ; X64-NOBMI2-NEXT:    shrq %cl, %rax
607 ; X64-NOBMI2-NEXT:    retq
609 ; X64-BMI2-LABEL: clear_highbits64_c1_indexzext:
610 ; X64-BMI2:       # %bb.0:
611 ; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
612 ; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
613 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rax
614 ; X64-BMI2-NEXT:    retq
615   %sh_prom = zext i8 %numhighbits to i64
616   %mask = lshr i64 -1, %sh_prom
617   %masked = and i64 %mask, %val
618   ret i64 %masked
621 define i64 @clear_highbits64_c2_load(i64* %w, i64 %numhighbits) nounwind {
622 ; X86-NOBMI2-LABEL: clear_highbits64_c2_load:
623 ; X86-NOBMI2:       # %bb.0:
624 ; X86-NOBMI2-NEXT:    pushl %esi
625 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
626 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
627 ; X86-NOBMI2-NEXT:    movl $-1, %eax
628 ; X86-NOBMI2-NEXT:    movl $-1, %edx
629 ; X86-NOBMI2-NEXT:    shrl %cl, %edx
630 ; X86-NOBMI2-NEXT:    shrdl %cl, %eax, %eax
631 ; X86-NOBMI2-NEXT:    testb $32, %cl
632 ; X86-NOBMI2-NEXT:    je .LBB15_2
633 ; X86-NOBMI2-NEXT:  # %bb.1:
634 ; X86-NOBMI2-NEXT:    movl %edx, %eax
635 ; X86-NOBMI2-NEXT:    xorl %edx, %edx
636 ; X86-NOBMI2-NEXT:  .LBB15_2:
637 ; X86-NOBMI2-NEXT:    andl (%esi), %eax
638 ; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
639 ; X86-NOBMI2-NEXT:    popl %esi
640 ; X86-NOBMI2-NEXT:    retl
642 ; X86-BMI2-LABEL: clear_highbits64_c2_load:
643 ; X86-BMI2:       # %bb.0:
644 ; X86-BMI2-NEXT:    pushl %esi
645 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
646 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
647 ; X86-BMI2-NEXT:    movl $-1, %eax
648 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
649 ; X86-BMI2-NEXT:    shrdl %cl, %eax, %eax
650 ; X86-BMI2-NEXT:    testb $32, %cl
651 ; X86-BMI2-NEXT:    je .LBB15_2
652 ; X86-BMI2-NEXT:  # %bb.1:
653 ; X86-BMI2-NEXT:    movl %edx, %eax
654 ; X86-BMI2-NEXT:    xorl %edx, %edx
655 ; X86-BMI2-NEXT:  .LBB15_2:
656 ; X86-BMI2-NEXT:    andl (%esi), %eax
657 ; X86-BMI2-NEXT:    andl 4(%esi), %edx
658 ; X86-BMI2-NEXT:    popl %esi
659 ; X86-BMI2-NEXT:    retl
661 ; X64-NOBMI2-LABEL: clear_highbits64_c2_load:
662 ; X64-NOBMI2:       # %bb.0:
663 ; X64-NOBMI2-NEXT:    movq %rsi, %rcx
664 ; X64-NOBMI2-NEXT:    movq (%rdi), %rax
665 ; X64-NOBMI2-NEXT:    shlq %cl, %rax
666 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
667 ; X64-NOBMI2-NEXT:    shrq %cl, %rax
668 ; X64-NOBMI2-NEXT:    retq
670 ; X64-BMI2-LABEL: clear_highbits64_c2_load:
671 ; X64-BMI2:       # %bb.0:
672 ; X64-BMI2-NEXT:    shlxq %rsi, (%rdi), %rax
673 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rax
674 ; X64-BMI2-NEXT:    retq
675   %val = load i64, i64* %w
676   %mask = lshr i64 -1, %numhighbits
677   %masked = and i64 %mask, %val
678   ret i64 %masked
681 define i64 @clear_highbits64_c3_load_indexzext(i64* %w, i8 %numhighbits) nounwind {
682 ; X86-NOBMI2-LABEL: clear_highbits64_c3_load_indexzext:
683 ; X86-NOBMI2:       # %bb.0:
684 ; X86-NOBMI2-NEXT:    pushl %esi
685 ; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
686 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
687 ; X86-NOBMI2-NEXT:    movl $-1, %eax
688 ; X86-NOBMI2-NEXT:    movl $-1, %edx
689 ; X86-NOBMI2-NEXT:    shrl %cl, %edx
690 ; X86-NOBMI2-NEXT:    shrdl %cl, %eax, %eax
691 ; X86-NOBMI2-NEXT:    testb $32, %cl
692 ; X86-NOBMI2-NEXT:    je .LBB16_2
693 ; X86-NOBMI2-NEXT:  # %bb.1:
694 ; X86-NOBMI2-NEXT:    movl %edx, %eax
695 ; X86-NOBMI2-NEXT:    xorl %edx, %edx
696 ; X86-NOBMI2-NEXT:  .LBB16_2:
697 ; X86-NOBMI2-NEXT:    andl (%esi), %eax
698 ; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
699 ; X86-NOBMI2-NEXT:    popl %esi
700 ; X86-NOBMI2-NEXT:    retl
702 ; X86-BMI2-LABEL: clear_highbits64_c3_load_indexzext:
703 ; X86-BMI2:       # %bb.0:
704 ; X86-BMI2-NEXT:    pushl %esi
705 ; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
706 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
707 ; X86-BMI2-NEXT:    movl $-1, %eax
708 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
709 ; X86-BMI2-NEXT:    shrdl %cl, %eax, %eax
710 ; X86-BMI2-NEXT:    testb $32, %cl
711 ; X86-BMI2-NEXT:    je .LBB16_2
712 ; X86-BMI2-NEXT:  # %bb.1:
713 ; X86-BMI2-NEXT:    movl %edx, %eax
714 ; X86-BMI2-NEXT:    xorl %edx, %edx
715 ; X86-BMI2-NEXT:  .LBB16_2:
716 ; X86-BMI2-NEXT:    andl (%esi), %eax
717 ; X86-BMI2-NEXT:    andl 4(%esi), %edx
718 ; X86-BMI2-NEXT:    popl %esi
719 ; X86-BMI2-NEXT:    retl
721 ; X64-NOBMI2-LABEL: clear_highbits64_c3_load_indexzext:
722 ; X64-NOBMI2:       # %bb.0:
723 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
724 ; X64-NOBMI2-NEXT:    movq (%rdi), %rax
725 ; X64-NOBMI2-NEXT:    shlq %cl, %rax
726 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
727 ; X64-NOBMI2-NEXT:    shrq %cl, %rax
728 ; X64-NOBMI2-NEXT:    retq
730 ; X64-BMI2-LABEL: clear_highbits64_c3_load_indexzext:
731 ; X64-BMI2:       # %bb.0:
732 ; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
733 ; X64-BMI2-NEXT:    shlxq %rsi, (%rdi), %rax
734 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rax
735 ; X64-BMI2-NEXT:    retq
736   %val = load i64, i64* %w
737   %sh_prom = zext i8 %numhighbits to i64
738   %mask = lshr i64 -1, %sh_prom
739   %masked = and i64 %mask, %val
740   ret i64 %masked
743 define i64 @clear_highbits64_c4_commutative(i64 %val, i64 %numhighbits) nounwind {
744 ; X86-NOBMI2-LABEL: clear_highbits64_c4_commutative:
745 ; X86-NOBMI2:       # %bb.0:
746 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
747 ; X86-NOBMI2-NEXT:    movl $-1, %eax
748 ; X86-NOBMI2-NEXT:    movl $-1, %edx
749 ; X86-NOBMI2-NEXT:    shrl %cl, %edx
750 ; X86-NOBMI2-NEXT:    shrdl %cl, %eax, %eax
751 ; X86-NOBMI2-NEXT:    testb $32, %cl
752 ; X86-NOBMI2-NEXT:    je .LBB17_2
753 ; X86-NOBMI2-NEXT:  # %bb.1:
754 ; X86-NOBMI2-NEXT:    movl %edx, %eax
755 ; X86-NOBMI2-NEXT:    xorl %edx, %edx
756 ; X86-NOBMI2-NEXT:  .LBB17_2:
757 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
758 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
759 ; X86-NOBMI2-NEXT:    retl
761 ; X86-BMI2-LABEL: clear_highbits64_c4_commutative:
762 ; X86-BMI2:       # %bb.0:
763 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
764 ; X86-BMI2-NEXT:    movl $-1, %eax
765 ; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
766 ; X86-BMI2-NEXT:    shrdl %cl, %eax, %eax
767 ; X86-BMI2-NEXT:    testb $32, %cl
768 ; X86-BMI2-NEXT:    je .LBB17_2
769 ; X86-BMI2-NEXT:  # %bb.1:
770 ; X86-BMI2-NEXT:    movl %edx, %eax
771 ; X86-BMI2-NEXT:    xorl %edx, %edx
772 ; X86-BMI2-NEXT:  .LBB17_2:
773 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
774 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
775 ; X86-BMI2-NEXT:    retl
777 ; X64-NOBMI2-LABEL: clear_highbits64_c4_commutative:
778 ; X64-NOBMI2:       # %bb.0:
779 ; X64-NOBMI2-NEXT:    movq %rsi, %rcx
780 ; X64-NOBMI2-NEXT:    movq %rdi, %rax
781 ; X64-NOBMI2-NEXT:    shlq %cl, %rax
782 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
783 ; X64-NOBMI2-NEXT:    shrq %cl, %rax
784 ; X64-NOBMI2-NEXT:    retq
786 ; X64-BMI2-LABEL: clear_highbits64_c4_commutative:
787 ; X64-BMI2:       # %bb.0:
788 ; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
789 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rax
790 ; X64-BMI2-NEXT:    retq
791   %mask = lshr i64 -1, %numhighbits
792   %masked = and i64 %val, %mask ; swapped order
793   ret i64 %masked
796 ; ---------------------------------------------------------------------------- ;
797 ; Multi-use tests
798 ; ---------------------------------------------------------------------------- ;
800 declare void @use32(i32)
801 declare void @use64(i64)
803 define i32 @oneuse32(i32 %val, i32 %numhighbits) nounwind {
804 ; X86-NOBMI2-LABEL: oneuse32:
805 ; X86-NOBMI2:       # %bb.0:
806 ; X86-NOBMI2-NEXT:    pushl %esi
807 ; X86-NOBMI2-NEXT:    subl $8, %esp
808 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
809 ; X86-NOBMI2-NEXT:    movl $-1, %esi
810 ; X86-NOBMI2-NEXT:    shrl %cl, %esi
811 ; X86-NOBMI2-NEXT:    movl %esi, (%esp)
812 ; X86-NOBMI2-NEXT:    calll use32
813 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
814 ; X86-NOBMI2-NEXT:    movl %esi, %eax
815 ; X86-NOBMI2-NEXT:    addl $8, %esp
816 ; X86-NOBMI2-NEXT:    popl %esi
817 ; X86-NOBMI2-NEXT:    retl
819 ; X86-BMI2-LABEL: oneuse32:
820 ; X86-BMI2:       # %bb.0:
821 ; X86-BMI2-NEXT:    pushl %esi
822 ; X86-BMI2-NEXT:    subl $8, %esp
823 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
824 ; X86-BMI2-NEXT:    movl $-1, %ecx
825 ; X86-BMI2-NEXT:    shrxl %eax, %ecx, %esi
826 ; X86-BMI2-NEXT:    movl %esi, (%esp)
827 ; X86-BMI2-NEXT:    calll use32
828 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
829 ; X86-BMI2-NEXT:    movl %esi, %eax
830 ; X86-BMI2-NEXT:    addl $8, %esp
831 ; X86-BMI2-NEXT:    popl %esi
832 ; X86-BMI2-NEXT:    retl
834 ; X64-NOBMI2-LABEL: oneuse32:
835 ; X64-NOBMI2:       # %bb.0:
836 ; X64-NOBMI2-NEXT:    pushq %rbp
837 ; X64-NOBMI2-NEXT:    pushq %rbx
838 ; X64-NOBMI2-NEXT:    pushq %rax
839 ; X64-NOBMI2-NEXT:    movl %esi, %ecx
840 ; X64-NOBMI2-NEXT:    movl %edi, %ebx
841 ; X64-NOBMI2-NEXT:    movl $-1, %ebp
842 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
843 ; X64-NOBMI2-NEXT:    shrl %cl, %ebp
844 ; X64-NOBMI2-NEXT:    movl %ebp, %edi
845 ; X64-NOBMI2-NEXT:    callq use32
846 ; X64-NOBMI2-NEXT:    andl %ebx, %ebp
847 ; X64-NOBMI2-NEXT:    movl %ebp, %eax
848 ; X64-NOBMI2-NEXT:    addq $8, %rsp
849 ; X64-NOBMI2-NEXT:    popq %rbx
850 ; X64-NOBMI2-NEXT:    popq %rbp
851 ; X64-NOBMI2-NEXT:    retq
853 ; X64-BMI2-LABEL: oneuse32:
854 ; X64-BMI2:       # %bb.0:
855 ; X64-BMI2-NEXT:    pushq %rbp
856 ; X64-BMI2-NEXT:    pushq %rbx
857 ; X64-BMI2-NEXT:    pushq %rax
858 ; X64-BMI2-NEXT:    movl %edi, %ebx
859 ; X64-BMI2-NEXT:    movl $-1, %eax
860 ; X64-BMI2-NEXT:    shrxl %esi, %eax, %ebp
861 ; X64-BMI2-NEXT:    movl %ebp, %edi
862 ; X64-BMI2-NEXT:    callq use32
863 ; X64-BMI2-NEXT:    andl %ebx, %ebp
864 ; X64-BMI2-NEXT:    movl %ebp, %eax
865 ; X64-BMI2-NEXT:    addq $8, %rsp
866 ; X64-BMI2-NEXT:    popq %rbx
867 ; X64-BMI2-NEXT:    popq %rbp
868 ; X64-BMI2-NEXT:    retq
869   %mask = lshr i32 -1, %numhighbits
870   call void @use32(i32 %mask)
871   %masked = and i32 %mask, %val
872   ret i32 %masked
875 define i64 @oneuse64(i64 %val, i64 %numhighbits) nounwind {
876 ; X86-NOBMI2-LABEL: oneuse64:
877 ; X86-NOBMI2:       # %bb.0:
878 ; X86-NOBMI2-NEXT:    pushl %edi
879 ; X86-NOBMI2-NEXT:    pushl %esi
880 ; X86-NOBMI2-NEXT:    pushl %eax
881 ; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
882 ; X86-NOBMI2-NEXT:    movl $-1, %esi
883 ; X86-NOBMI2-NEXT:    movl $-1, %edi
884 ; X86-NOBMI2-NEXT:    shrl %cl, %edi
885 ; X86-NOBMI2-NEXT:    shrdl %cl, %esi, %esi
886 ; X86-NOBMI2-NEXT:    testb $32, %cl
887 ; X86-NOBMI2-NEXT:    je .LBB19_2
888 ; X86-NOBMI2-NEXT:  # %bb.1:
889 ; X86-NOBMI2-NEXT:    movl %edi, %esi
890 ; X86-NOBMI2-NEXT:    xorl %edi, %edi
891 ; X86-NOBMI2-NEXT:  .LBB19_2:
892 ; X86-NOBMI2-NEXT:    subl $8, %esp
893 ; X86-NOBMI2-NEXT:    pushl %edi
894 ; X86-NOBMI2-NEXT:    pushl %esi
895 ; X86-NOBMI2-NEXT:    calll use64
896 ; X86-NOBMI2-NEXT:    addl $16, %esp
897 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
898 ; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
899 ; X86-NOBMI2-NEXT:    movl %esi, %eax
900 ; X86-NOBMI2-NEXT:    movl %edi, %edx
901 ; X86-NOBMI2-NEXT:    addl $4, %esp
902 ; X86-NOBMI2-NEXT:    popl %esi
903 ; X86-NOBMI2-NEXT:    popl %edi
904 ; X86-NOBMI2-NEXT:    retl
906 ; X86-BMI2-LABEL: oneuse64:
907 ; X86-BMI2:       # %bb.0:
908 ; X86-BMI2-NEXT:    pushl %edi
909 ; X86-BMI2-NEXT:    pushl %esi
910 ; X86-BMI2-NEXT:    pushl %eax
911 ; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
912 ; X86-BMI2-NEXT:    movl $-1, %esi
913 ; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edi
914 ; X86-BMI2-NEXT:    shrdl %cl, %esi, %esi
915 ; X86-BMI2-NEXT:    testb $32, %cl
916 ; X86-BMI2-NEXT:    je .LBB19_2
917 ; X86-BMI2-NEXT:  # %bb.1:
918 ; X86-BMI2-NEXT:    movl %edi, %esi
919 ; X86-BMI2-NEXT:    xorl %edi, %edi
920 ; X86-BMI2-NEXT:  .LBB19_2:
921 ; X86-BMI2-NEXT:    subl $8, %esp
922 ; X86-BMI2-NEXT:    pushl %edi
923 ; X86-BMI2-NEXT:    pushl %esi
924 ; X86-BMI2-NEXT:    calll use64
925 ; X86-BMI2-NEXT:    addl $16, %esp
926 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
927 ; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
928 ; X86-BMI2-NEXT:    movl %esi, %eax
929 ; X86-BMI2-NEXT:    movl %edi, %edx
930 ; X86-BMI2-NEXT:    addl $4, %esp
931 ; X86-BMI2-NEXT:    popl %esi
932 ; X86-BMI2-NEXT:    popl %edi
933 ; X86-BMI2-NEXT:    retl
935 ; X64-NOBMI2-LABEL: oneuse64:
936 ; X64-NOBMI2:       # %bb.0:
937 ; X64-NOBMI2-NEXT:    pushq %r14
938 ; X64-NOBMI2-NEXT:    pushq %rbx
939 ; X64-NOBMI2-NEXT:    pushq %rax
940 ; X64-NOBMI2-NEXT:    movq %rsi, %rcx
941 ; X64-NOBMI2-NEXT:    movq %rdi, %r14
942 ; X64-NOBMI2-NEXT:    movq $-1, %rbx
943 ; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
944 ; X64-NOBMI2-NEXT:    shrq %cl, %rbx
945 ; X64-NOBMI2-NEXT:    movq %rbx, %rdi
946 ; X64-NOBMI2-NEXT:    callq use64
947 ; X64-NOBMI2-NEXT:    andq %r14, %rbx
948 ; X64-NOBMI2-NEXT:    movq %rbx, %rax
949 ; X64-NOBMI2-NEXT:    addq $8, %rsp
950 ; X64-NOBMI2-NEXT:    popq %rbx
951 ; X64-NOBMI2-NEXT:    popq %r14
952 ; X64-NOBMI2-NEXT:    retq
954 ; X64-BMI2-LABEL: oneuse64:
955 ; X64-BMI2:       # %bb.0:
956 ; X64-BMI2-NEXT:    pushq %r14
957 ; X64-BMI2-NEXT:    pushq %rbx
958 ; X64-BMI2-NEXT:    pushq %rax
959 ; X64-BMI2-NEXT:    movq %rdi, %r14
960 ; X64-BMI2-NEXT:    movq $-1, %rax
961 ; X64-BMI2-NEXT:    shrxq %rsi, %rax, %rbx
962 ; X64-BMI2-NEXT:    movq %rbx, %rdi
963 ; X64-BMI2-NEXT:    callq use64
964 ; X64-BMI2-NEXT:    andq %r14, %rbx
965 ; X64-BMI2-NEXT:    movq %rbx, %rax
966 ; X64-BMI2-NEXT:    addq $8, %rsp
967 ; X64-BMI2-NEXT:    popq %rbx
968 ; X64-BMI2-NEXT:    popq %r14
969 ; X64-BMI2-NEXT:    retq
970   %mask = lshr i64 -1, %numhighbits
971   call void @use64(i64 %mask)
972   %masked = and i64 %mask, %val
973   ret i64 %masked