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=X86,X86-NOBMI2
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI2
4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI2
5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-BMI2
6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-BMI2
7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI2
8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI2
9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI2
10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-BMI2
11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-BMI2
12
13; Patterns:
14;    c) x &  (-1 << y)
15;   ic) x &  (-1 << (32 - y))
16;    d) x >> y << y
17;   id) x >> (32 - y) << (32 - y)
18; are equivalent, but we prefer the second variant if we have BMI2.
19
20; ---------------------------------------------------------------------------- ;
21; Pattern c.
22; ---------------------------------------------------------------------------- ;
23
24; 8-bit
25
26define i8 @clear_lowbits8_c0(i8 %val, i8 %numlowbits) nounwind {
27; X86-LABEL: clear_lowbits8_c0:
28; X86:       # %bb.0:
29; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
30; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
31; X86-NEXT:    shrb %cl, %al
32; X86-NEXT:    shlb %cl, %al
33; X86-NEXT:    retl
34;
35; X64-LABEL: clear_lowbits8_c0:
36; X64:       # %bb.0:
37; X64-NEXT:    movl %esi, %ecx
38; X64-NEXT:    movl %edi, %eax
39; X64-NEXT:    shrb %cl, %al
40; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
41; X64-NEXT:    shlb %cl, %al
42; X64-NEXT:    # kill: def $al killed $al killed $eax
43; X64-NEXT:    retq
44  %mask = shl i8 -1, %numlowbits
45  %masked = and i8 %mask, %val
46  ret i8 %masked
47}
48
49define i8 @clear_lowbits8_c2_load(i8* %w, i8 %numlowbits) nounwind {
50; X86-LABEL: clear_lowbits8_c2_load:
51; X86:       # %bb.0:
52; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
53; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
54; X86-NEXT:    movb (%eax), %al
55; X86-NEXT:    shrb %cl, %al
56; X86-NEXT:    shlb %cl, %al
57; X86-NEXT:    retl
58;
59; X64-LABEL: clear_lowbits8_c2_load:
60; X64:       # %bb.0:
61; X64-NEXT:    movl %esi, %ecx
62; X64-NEXT:    movb (%rdi), %al
63; X64-NEXT:    shrb %cl, %al
64; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
65; X64-NEXT:    shlb %cl, %al
66; X64-NEXT:    retq
67  %val = load i8, i8* %w
68  %mask = shl i8 -1, %numlowbits
69  %masked = and i8 %mask, %val
70  ret i8 %masked
71}
72
73define i8 @clear_lowbits8_c4_commutative(i8 %val, i8 %numlowbits) nounwind {
74; X86-LABEL: clear_lowbits8_c4_commutative:
75; X86:       # %bb.0:
76; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
77; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
78; X86-NEXT:    shrb %cl, %al
79; X86-NEXT:    shlb %cl, %al
80; X86-NEXT:    retl
81;
82; X64-LABEL: clear_lowbits8_c4_commutative:
83; X64:       # %bb.0:
84; X64-NEXT:    movl %esi, %ecx
85; X64-NEXT:    movl %edi, %eax
86; X64-NEXT:    shrb %cl, %al
87; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
88; X64-NEXT:    shlb %cl, %al
89; X64-NEXT:    # kill: def $al killed $al killed $eax
90; X64-NEXT:    retq
91  %mask = shl i8 -1, %numlowbits
92  %masked = and i8 %val, %mask ; swapped order
93  ret i8 %masked
94}
95
96; 16-bit
97
98define i16 @clear_lowbits16_c0(i16 %val, i16 %numlowbits) nounwind {
99; X86-NOBMI2-LABEL: clear_lowbits16_c0:
100; X86-NOBMI2:       # %bb.0:
101; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
102; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
103; X86-NOBMI2-NEXT:    shrl %cl, %eax
104; X86-NOBMI2-NEXT:    shll %cl, %eax
105; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
106; X86-NOBMI2-NEXT:    retl
107;
108; X86-BMI2-LABEL: clear_lowbits16_c0:
109; X86-BMI2:       # %bb.0:
110; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
111; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
112; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
113; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
114; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
115; X86-BMI2-NEXT:    retl
116;
117; X64-NOBMI2-LABEL: clear_lowbits16_c0:
118; X64-NOBMI2:       # %bb.0:
119; X64-NOBMI2-NEXT:    movl %esi, %ecx
120; X64-NOBMI2-NEXT:    movzwl %di, %eax
121; X64-NOBMI2-NEXT:    shrl %cl, %eax
122; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
123; X64-NOBMI2-NEXT:    shll %cl, %eax
124; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
125; X64-NOBMI2-NEXT:    retq
126;
127; X64-BMI2-LABEL: clear_lowbits16_c0:
128; X64-BMI2:       # %bb.0:
129; X64-BMI2-NEXT:    movzwl %di, %eax
130; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
131; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
132; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
133; X64-BMI2-NEXT:    retq
134  %mask = shl i16 -1, %numlowbits
135  %masked = and i16 %mask, %val
136  ret i16 %masked
137}
138
139define i16 @clear_lowbits16_c1_indexzext(i16 %val, i8 %numlowbits) nounwind {
140; X86-NOBMI2-LABEL: clear_lowbits16_c1_indexzext:
141; X86-NOBMI2:       # %bb.0:
142; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
143; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
144; X86-NOBMI2-NEXT:    shrl %cl, %eax
145; X86-NOBMI2-NEXT:    shll %cl, %eax
146; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
147; X86-NOBMI2-NEXT:    retl
148;
149; X86-BMI2-LABEL: clear_lowbits16_c1_indexzext:
150; X86-BMI2:       # %bb.0:
151; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
152; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
153; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
154; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
155; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
156; X86-BMI2-NEXT:    retl
157;
158; X64-NOBMI2-LABEL: clear_lowbits16_c1_indexzext:
159; X64-NOBMI2:       # %bb.0:
160; X64-NOBMI2-NEXT:    movl %esi, %ecx
161; X64-NOBMI2-NEXT:    movzwl %di, %eax
162; X64-NOBMI2-NEXT:    shrl %cl, %eax
163; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
164; X64-NOBMI2-NEXT:    shll %cl, %eax
165; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
166; X64-NOBMI2-NEXT:    retq
167;
168; X64-BMI2-LABEL: clear_lowbits16_c1_indexzext:
169; X64-BMI2:       # %bb.0:
170; X64-BMI2-NEXT:    movzwl %di, %eax
171; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
172; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
173; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
174; X64-BMI2-NEXT:    retq
175  %sh_prom = zext i8 %numlowbits to i16
176  %mask = shl i16 -1, %sh_prom
177  %masked = and i16 %mask, %val
178  ret i16 %masked
179}
180
181define i16 @clear_lowbits16_c2_load(i16* %w, i16 %numlowbits) nounwind {
182; X86-NOBMI2-LABEL: clear_lowbits16_c2_load:
183; X86-NOBMI2:       # %bb.0:
184; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
185; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
186; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
187; X86-NOBMI2-NEXT:    shrl %cl, %eax
188; X86-NOBMI2-NEXT:    shll %cl, %eax
189; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
190; X86-NOBMI2-NEXT:    retl
191;
192; X86-BMI2-LABEL: clear_lowbits16_c2_load:
193; X86-BMI2:       # %bb.0:
194; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
195; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
196; X86-BMI2-NEXT:    movzwl (%ecx), %ecx
197; X86-BMI2-NEXT:    shrxl %eax, %ecx, %ecx
198; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
199; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
200; X86-BMI2-NEXT:    retl
201;
202; X64-NOBMI2-LABEL: clear_lowbits16_c2_load:
203; X64-NOBMI2:       # %bb.0:
204; X64-NOBMI2-NEXT:    movl %esi, %ecx
205; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
206; X64-NOBMI2-NEXT:    shrl %cl, %eax
207; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
208; X64-NOBMI2-NEXT:    shll %cl, %eax
209; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
210; X64-NOBMI2-NEXT:    retq
211;
212; X64-BMI2-LABEL: clear_lowbits16_c2_load:
213; X64-BMI2:       # %bb.0:
214; X64-BMI2-NEXT:    movzwl (%rdi), %eax
215; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
216; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
217; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
218; X64-BMI2-NEXT:    retq
219  %val = load i16, i16* %w
220  %mask = shl i16 -1, %numlowbits
221  %masked = and i16 %mask, %val
222  ret i16 %masked
223}
224
225define i16 @clear_lowbits16_c3_load_indexzext(i16* %w, i8 %numlowbits) nounwind {
226; X86-NOBMI2-LABEL: clear_lowbits16_c3_load_indexzext:
227; X86-NOBMI2:       # %bb.0:
228; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
229; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
230; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
231; X86-NOBMI2-NEXT:    shrl %cl, %eax
232; X86-NOBMI2-NEXT:    shll %cl, %eax
233; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
234; X86-NOBMI2-NEXT:    retl
235;
236; X86-BMI2-LABEL: clear_lowbits16_c3_load_indexzext:
237; X86-BMI2:       # %bb.0:
238; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
239; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
240; X86-BMI2-NEXT:    movzwl (%ecx), %ecx
241; X86-BMI2-NEXT:    shrxl %eax, %ecx, %ecx
242; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
243; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
244; X86-BMI2-NEXT:    retl
245;
246; X64-NOBMI2-LABEL: clear_lowbits16_c3_load_indexzext:
247; X64-NOBMI2:       # %bb.0:
248; X64-NOBMI2-NEXT:    movl %esi, %ecx
249; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
250; X64-NOBMI2-NEXT:    shrl %cl, %eax
251; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
252; X64-NOBMI2-NEXT:    shll %cl, %eax
253; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
254; X64-NOBMI2-NEXT:    retq
255;
256; X64-BMI2-LABEL: clear_lowbits16_c3_load_indexzext:
257; X64-BMI2:       # %bb.0:
258; X64-BMI2-NEXT:    movzwl (%rdi), %eax
259; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
260; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
261; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
262; X64-BMI2-NEXT:    retq
263  %val = load i16, i16* %w
264  %sh_prom = zext i8 %numlowbits to i16
265  %mask = shl i16 -1, %sh_prom
266  %masked = and i16 %mask, %val
267  ret i16 %masked
268}
269
270define i16 @clear_lowbits16_c4_commutative(i16 %val, i16 %numlowbits) nounwind {
271; X86-NOBMI2-LABEL: clear_lowbits16_c4_commutative:
272; X86-NOBMI2:       # %bb.0:
273; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
274; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
275; X86-NOBMI2-NEXT:    shrl %cl, %eax
276; X86-NOBMI2-NEXT:    shll %cl, %eax
277; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
278; X86-NOBMI2-NEXT:    retl
279;
280; X86-BMI2-LABEL: clear_lowbits16_c4_commutative:
281; X86-BMI2:       # %bb.0:
282; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
283; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
284; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
285; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
286; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
287; X86-BMI2-NEXT:    retl
288;
289; X64-NOBMI2-LABEL: clear_lowbits16_c4_commutative:
290; X64-NOBMI2:       # %bb.0:
291; X64-NOBMI2-NEXT:    movl %esi, %ecx
292; X64-NOBMI2-NEXT:    movzwl %di, %eax
293; X64-NOBMI2-NEXT:    shrl %cl, %eax
294; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
295; X64-NOBMI2-NEXT:    shll %cl, %eax
296; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
297; X64-NOBMI2-NEXT:    retq
298;
299; X64-BMI2-LABEL: clear_lowbits16_c4_commutative:
300; X64-BMI2:       # %bb.0:
301; X64-BMI2-NEXT:    movzwl %di, %eax
302; X64-BMI2-NEXT:    shrxl %esi, %eax, %eax
303; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
304; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
305; X64-BMI2-NEXT:    retq
306  %mask = shl i16 -1, %numlowbits
307  %masked = and i16 %val, %mask ; swapped order
308  ret i16 %masked
309}
310
311; 32-bit
312
313define i32 @clear_lowbits32_c0(i32 %val, i32 %numlowbits) nounwind {
314; X86-NOBMI2-LABEL: clear_lowbits32_c0:
315; X86-NOBMI2:       # %bb.0:
316; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
317; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
318; X86-NOBMI2-NEXT:    shrl %cl, %eax
319; X86-NOBMI2-NEXT:    shll %cl, %eax
320; X86-NOBMI2-NEXT:    retl
321;
322; X86-BMI2-LABEL: clear_lowbits32_c0:
323; X86-BMI2:       # %bb.0:
324; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
325; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
326; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
327; X86-BMI2-NEXT:    retl
328;
329; X64-NOBMI2-LABEL: clear_lowbits32_c0:
330; X64-NOBMI2:       # %bb.0:
331; X64-NOBMI2-NEXT:    movl %esi, %ecx
332; X64-NOBMI2-NEXT:    movl %edi, %eax
333; X64-NOBMI2-NEXT:    shrl %cl, %eax
334; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
335; X64-NOBMI2-NEXT:    shll %cl, %eax
336; X64-NOBMI2-NEXT:    retq
337;
338; X64-BMI2-LABEL: clear_lowbits32_c0:
339; X64-BMI2:       # %bb.0:
340; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
341; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
342; X64-BMI2-NEXT:    retq
343  %mask = shl i32 -1, %numlowbits
344  %masked = and i32 %mask, %val
345  ret i32 %masked
346}
347
348define i32 @clear_lowbits32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind {
349; X86-NOBMI2-LABEL: clear_lowbits32_c1_indexzext:
350; X86-NOBMI2:       # %bb.0:
351; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
352; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
353; X86-NOBMI2-NEXT:    shrl %cl, %eax
354; X86-NOBMI2-NEXT:    shll %cl, %eax
355; X86-NOBMI2-NEXT:    retl
356;
357; X86-BMI2-LABEL: clear_lowbits32_c1_indexzext:
358; X86-BMI2:       # %bb.0:
359; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
360; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
361; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
362; X86-BMI2-NEXT:    retl
363;
364; X64-NOBMI2-LABEL: clear_lowbits32_c1_indexzext:
365; X64-NOBMI2:       # %bb.0:
366; X64-NOBMI2-NEXT:    movl %esi, %ecx
367; X64-NOBMI2-NEXT:    movl %edi, %eax
368; X64-NOBMI2-NEXT:    shrl %cl, %eax
369; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
370; X64-NOBMI2-NEXT:    shll %cl, %eax
371; X64-NOBMI2-NEXT:    retq
372;
373; X64-BMI2-LABEL: clear_lowbits32_c1_indexzext:
374; X64-BMI2:       # %bb.0:
375; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
376; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
377; X64-BMI2-NEXT:    retq
378  %sh_prom = zext i8 %numlowbits to i32
379  %mask = shl i32 -1, %sh_prom
380  %masked = and i32 %mask, %val
381  ret i32 %masked
382}
383
384define i32 @clear_lowbits32_c2_load(i32* %w, i32 %numlowbits) nounwind {
385; X86-NOBMI2-LABEL: clear_lowbits32_c2_load:
386; X86-NOBMI2:       # %bb.0:
387; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
388; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
389; X86-NOBMI2-NEXT:    movl (%eax), %eax
390; X86-NOBMI2-NEXT:    shrl %cl, %eax
391; X86-NOBMI2-NEXT:    shll %cl, %eax
392; X86-NOBMI2-NEXT:    retl
393;
394; X86-BMI2-LABEL: clear_lowbits32_c2_load:
395; X86-BMI2:       # %bb.0:
396; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
397; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
398; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
399; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
400; X86-BMI2-NEXT:    retl
401;
402; X64-NOBMI2-LABEL: clear_lowbits32_c2_load:
403; X64-NOBMI2:       # %bb.0:
404; X64-NOBMI2-NEXT:    movl %esi, %ecx
405; X64-NOBMI2-NEXT:    movl (%rdi), %eax
406; X64-NOBMI2-NEXT:    shrl %cl, %eax
407; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
408; X64-NOBMI2-NEXT:    shll %cl, %eax
409; X64-NOBMI2-NEXT:    retq
410;
411; X64-BMI2-LABEL: clear_lowbits32_c2_load:
412; X64-BMI2:       # %bb.0:
413; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
414; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
415; X64-BMI2-NEXT:    retq
416  %val = load i32, i32* %w
417  %mask = shl i32 -1, %numlowbits
418  %masked = and i32 %mask, %val
419  ret i32 %masked
420}
421
422define i32 @clear_lowbits32_c3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
423; X86-NOBMI2-LABEL: clear_lowbits32_c3_load_indexzext:
424; X86-NOBMI2:       # %bb.0:
425; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
426; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
427; X86-NOBMI2-NEXT:    movl (%eax), %eax
428; X86-NOBMI2-NEXT:    shrl %cl, %eax
429; X86-NOBMI2-NEXT:    shll %cl, %eax
430; X86-NOBMI2-NEXT:    retl
431;
432; X86-BMI2-LABEL: clear_lowbits32_c3_load_indexzext:
433; X86-BMI2:       # %bb.0:
434; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
435; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
436; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
437; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
438; X86-BMI2-NEXT:    retl
439;
440; X64-NOBMI2-LABEL: clear_lowbits32_c3_load_indexzext:
441; X64-NOBMI2:       # %bb.0:
442; X64-NOBMI2-NEXT:    movl %esi, %ecx
443; X64-NOBMI2-NEXT:    movl (%rdi), %eax
444; X64-NOBMI2-NEXT:    shrl %cl, %eax
445; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
446; X64-NOBMI2-NEXT:    shll %cl, %eax
447; X64-NOBMI2-NEXT:    retq
448;
449; X64-BMI2-LABEL: clear_lowbits32_c3_load_indexzext:
450; X64-BMI2:       # %bb.0:
451; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
452; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
453; X64-BMI2-NEXT:    retq
454  %val = load i32, i32* %w
455  %sh_prom = zext i8 %numlowbits to i32
456  %mask = shl i32 -1, %sh_prom
457  %masked = and i32 %mask, %val
458  ret i32 %masked
459}
460
461define i32 @clear_lowbits32_c4_commutative(i32 %val, i32 %numlowbits) nounwind {
462; X86-NOBMI2-LABEL: clear_lowbits32_c4_commutative:
463; X86-NOBMI2:       # %bb.0:
464; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
465; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
466; X86-NOBMI2-NEXT:    shrl %cl, %eax
467; X86-NOBMI2-NEXT:    shll %cl, %eax
468; X86-NOBMI2-NEXT:    retl
469;
470; X86-BMI2-LABEL: clear_lowbits32_c4_commutative:
471; X86-BMI2:       # %bb.0:
472; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
473; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
474; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
475; X86-BMI2-NEXT:    retl
476;
477; X64-NOBMI2-LABEL: clear_lowbits32_c4_commutative:
478; X64-NOBMI2:       # %bb.0:
479; X64-NOBMI2-NEXT:    movl %esi, %ecx
480; X64-NOBMI2-NEXT:    movl %edi, %eax
481; X64-NOBMI2-NEXT:    shrl %cl, %eax
482; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
483; X64-NOBMI2-NEXT:    shll %cl, %eax
484; X64-NOBMI2-NEXT:    retq
485;
486; X64-BMI2-LABEL: clear_lowbits32_c4_commutative:
487; X64-BMI2:       # %bb.0:
488; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
489; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
490; X64-BMI2-NEXT:    retq
491  %mask = shl i32 -1, %numlowbits
492  %masked = and i32 %val, %mask ; swapped order
493  ret i32 %masked
494}
495
496; 64-bit
497
498define i64 @clear_lowbits64_c0(i64 %val, i64 %numlowbits) nounwind {
499; X86-NOBMI2-LABEL: clear_lowbits64_c0:
500; X86-NOBMI2:       # %bb.0:
501; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
502; X86-NOBMI2-NEXT:    movl $-1, %edx
503; X86-NOBMI2-NEXT:    movl $-1, %eax
504; X86-NOBMI2-NEXT:    shll %cl, %eax
505; X86-NOBMI2-NEXT:    testb $32, %cl
506; X86-NOBMI2-NEXT:    je .LBB13_2
507; X86-NOBMI2-NEXT:  # %bb.1:
508; X86-NOBMI2-NEXT:    movl %eax, %edx
509; X86-NOBMI2-NEXT:    xorl %eax, %eax
510; X86-NOBMI2-NEXT:  .LBB13_2:
511; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
512; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
513; X86-NOBMI2-NEXT:    retl
514;
515; X86-BMI2-LABEL: clear_lowbits64_c0:
516; X86-BMI2:       # %bb.0:
517; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
518; X86-BMI2-NEXT:    movl $-1, %edx
519; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
520; X86-BMI2-NEXT:    testb $32, %cl
521; X86-BMI2-NEXT:    je .LBB13_2
522; X86-BMI2-NEXT:  # %bb.1:
523; X86-BMI2-NEXT:    movl %eax, %edx
524; X86-BMI2-NEXT:    xorl %eax, %eax
525; X86-BMI2-NEXT:  .LBB13_2:
526; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
527; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
528; X86-BMI2-NEXT:    retl
529;
530; X64-NOBMI2-LABEL: clear_lowbits64_c0:
531; X64-NOBMI2:       # %bb.0:
532; X64-NOBMI2-NEXT:    movq %rsi, %rcx
533; X64-NOBMI2-NEXT:    movq %rdi, %rax
534; X64-NOBMI2-NEXT:    shrq %cl, %rax
535; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
536; X64-NOBMI2-NEXT:    shlq %cl, %rax
537; X64-NOBMI2-NEXT:    retq
538;
539; X64-BMI2-LABEL: clear_lowbits64_c0:
540; X64-BMI2:       # %bb.0:
541; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
542; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
543; X64-BMI2-NEXT:    retq
544  %mask = shl i64 -1, %numlowbits
545  %masked = and i64 %mask, %val
546  ret i64 %masked
547}
548
549define i64 @clear_lowbits64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind {
550; X86-NOBMI2-LABEL: clear_lowbits64_c1_indexzext:
551; X86-NOBMI2:       # %bb.0:
552; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
553; X86-NOBMI2-NEXT:    movl $-1, %edx
554; X86-NOBMI2-NEXT:    movl $-1, %eax
555; X86-NOBMI2-NEXT:    shll %cl, %eax
556; X86-NOBMI2-NEXT:    testb $32, %cl
557; X86-NOBMI2-NEXT:    je .LBB14_2
558; X86-NOBMI2-NEXT:  # %bb.1:
559; X86-NOBMI2-NEXT:    movl %eax, %edx
560; X86-NOBMI2-NEXT:    xorl %eax, %eax
561; X86-NOBMI2-NEXT:  .LBB14_2:
562; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
563; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
564; X86-NOBMI2-NEXT:    retl
565;
566; X86-BMI2-LABEL: clear_lowbits64_c1_indexzext:
567; X86-BMI2:       # %bb.0:
568; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
569; X86-BMI2-NEXT:    movl $-1, %edx
570; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
571; X86-BMI2-NEXT:    testb $32, %cl
572; X86-BMI2-NEXT:    je .LBB14_2
573; X86-BMI2-NEXT:  # %bb.1:
574; X86-BMI2-NEXT:    movl %eax, %edx
575; X86-BMI2-NEXT:    xorl %eax, %eax
576; X86-BMI2-NEXT:  .LBB14_2:
577; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
578; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
579; X86-BMI2-NEXT:    retl
580;
581; X64-NOBMI2-LABEL: clear_lowbits64_c1_indexzext:
582; X64-NOBMI2:       # %bb.0:
583; X64-NOBMI2-NEXT:    movl %esi, %ecx
584; X64-NOBMI2-NEXT:    movq %rdi, %rax
585; X64-NOBMI2-NEXT:    shrq %cl, %rax
586; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
587; X64-NOBMI2-NEXT:    shlq %cl, %rax
588; X64-NOBMI2-NEXT:    retq
589;
590; X64-BMI2-LABEL: clear_lowbits64_c1_indexzext:
591; X64-BMI2:       # %bb.0:
592; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
593; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
594; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
595; X64-BMI2-NEXT:    retq
596  %sh_prom = zext i8 %numlowbits to i64
597  %mask = shl i64 -1, %sh_prom
598  %masked = and i64 %mask, %val
599  ret i64 %masked
600}
601
602define i64 @clear_lowbits64_c2_load(i64* %w, i64 %numlowbits) nounwind {
603; X86-NOBMI2-LABEL: clear_lowbits64_c2_load:
604; X86-NOBMI2:       # %bb.0:
605; X86-NOBMI2-NEXT:    pushl %esi
606; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
607; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
608; X86-NOBMI2-NEXT:    movl $-1, %edx
609; X86-NOBMI2-NEXT:    movl $-1, %eax
610; X86-NOBMI2-NEXT:    shll %cl, %eax
611; X86-NOBMI2-NEXT:    testb $32, %cl
612; X86-NOBMI2-NEXT:    je .LBB15_2
613; X86-NOBMI2-NEXT:  # %bb.1:
614; X86-NOBMI2-NEXT:    movl %eax, %edx
615; X86-NOBMI2-NEXT:    xorl %eax, %eax
616; X86-NOBMI2-NEXT:  .LBB15_2:
617; X86-NOBMI2-NEXT:    andl (%esi), %eax
618; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
619; X86-NOBMI2-NEXT:    popl %esi
620; X86-NOBMI2-NEXT:    retl
621;
622; X86-BMI2-LABEL: clear_lowbits64_c2_load:
623; X86-BMI2:       # %bb.0:
624; X86-BMI2-NEXT:    pushl %ebx
625; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
626; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
627; X86-BMI2-NEXT:    movl $-1, %edx
628; X86-BMI2-NEXT:    shlxl %ebx, %edx, %eax
629; X86-BMI2-NEXT:    testb $32, %bl
630; X86-BMI2-NEXT:    je .LBB15_2
631; X86-BMI2-NEXT:  # %bb.1:
632; X86-BMI2-NEXT:    movl %eax, %edx
633; X86-BMI2-NEXT:    xorl %eax, %eax
634; X86-BMI2-NEXT:  .LBB15_2:
635; X86-BMI2-NEXT:    andl (%ecx), %eax
636; X86-BMI2-NEXT:    andl 4(%ecx), %edx
637; X86-BMI2-NEXT:    popl %ebx
638; X86-BMI2-NEXT:    retl
639;
640; X64-NOBMI2-LABEL: clear_lowbits64_c2_load:
641; X64-NOBMI2:       # %bb.0:
642; X64-NOBMI2-NEXT:    movq %rsi, %rcx
643; X64-NOBMI2-NEXT:    movq (%rdi), %rax
644; X64-NOBMI2-NEXT:    shrq %cl, %rax
645; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
646; X64-NOBMI2-NEXT:    shlq %cl, %rax
647; X64-NOBMI2-NEXT:    retq
648;
649; X64-BMI2-LABEL: clear_lowbits64_c2_load:
650; X64-BMI2:       # %bb.0:
651; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
652; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
653; X64-BMI2-NEXT:    retq
654  %val = load i64, i64* %w
655  %mask = shl i64 -1, %numlowbits
656  %masked = and i64 %mask, %val
657  ret i64 %masked
658}
659
660define i64 @clear_lowbits64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
661; X86-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext:
662; X86-NOBMI2:       # %bb.0:
663; X86-NOBMI2-NEXT:    pushl %esi
664; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
665; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
666; X86-NOBMI2-NEXT:    movl $-1, %edx
667; X86-NOBMI2-NEXT:    movl $-1, %eax
668; X86-NOBMI2-NEXT:    shll %cl, %eax
669; X86-NOBMI2-NEXT:    testb $32, %cl
670; X86-NOBMI2-NEXT:    je .LBB16_2
671; X86-NOBMI2-NEXT:  # %bb.1:
672; X86-NOBMI2-NEXT:    movl %eax, %edx
673; X86-NOBMI2-NEXT:    xorl %eax, %eax
674; X86-NOBMI2-NEXT:  .LBB16_2:
675; X86-NOBMI2-NEXT:    andl (%esi), %eax
676; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
677; X86-NOBMI2-NEXT:    popl %esi
678; X86-NOBMI2-NEXT:    retl
679;
680; X86-BMI2-LABEL: clear_lowbits64_c3_load_indexzext:
681; X86-BMI2:       # %bb.0:
682; X86-BMI2-NEXT:    pushl %ebx
683; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
684; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
685; X86-BMI2-NEXT:    movl $-1, %edx
686; X86-BMI2-NEXT:    shlxl %ebx, %edx, %eax
687; X86-BMI2-NEXT:    testb $32, %bl
688; X86-BMI2-NEXT:    je .LBB16_2
689; X86-BMI2-NEXT:  # %bb.1:
690; X86-BMI2-NEXT:    movl %eax, %edx
691; X86-BMI2-NEXT:    xorl %eax, %eax
692; X86-BMI2-NEXT:  .LBB16_2:
693; X86-BMI2-NEXT:    andl (%ecx), %eax
694; X86-BMI2-NEXT:    andl 4(%ecx), %edx
695; X86-BMI2-NEXT:    popl %ebx
696; X86-BMI2-NEXT:    retl
697;
698; X64-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext:
699; X64-NOBMI2:       # %bb.0:
700; X64-NOBMI2-NEXT:    movl %esi, %ecx
701; X64-NOBMI2-NEXT:    movq (%rdi), %rax
702; X64-NOBMI2-NEXT:    shrq %cl, %rax
703; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
704; X64-NOBMI2-NEXT:    shlq %cl, %rax
705; X64-NOBMI2-NEXT:    retq
706;
707; X64-BMI2-LABEL: clear_lowbits64_c3_load_indexzext:
708; X64-BMI2:       # %bb.0:
709; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
710; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
711; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
712; X64-BMI2-NEXT:    retq
713  %val = load i64, i64* %w
714  %sh_prom = zext i8 %numlowbits to i64
715  %mask = shl i64 -1, %sh_prom
716  %masked = and i64 %mask, %val
717  ret i64 %masked
718}
719
720define i64 @clear_lowbits64_c4_commutative(i64 %val, i64 %numlowbits) nounwind {
721; X86-NOBMI2-LABEL: clear_lowbits64_c4_commutative:
722; X86-NOBMI2:       # %bb.0:
723; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
724; X86-NOBMI2-NEXT:    movl $-1, %edx
725; X86-NOBMI2-NEXT:    movl $-1, %eax
726; X86-NOBMI2-NEXT:    shll %cl, %eax
727; X86-NOBMI2-NEXT:    testb $32, %cl
728; X86-NOBMI2-NEXT:    je .LBB17_2
729; X86-NOBMI2-NEXT:  # %bb.1:
730; X86-NOBMI2-NEXT:    movl %eax, %edx
731; X86-NOBMI2-NEXT:    xorl %eax, %eax
732; X86-NOBMI2-NEXT:  .LBB17_2:
733; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
734; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
735; X86-NOBMI2-NEXT:    retl
736;
737; X86-BMI2-LABEL: clear_lowbits64_c4_commutative:
738; X86-BMI2:       # %bb.0:
739; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
740; X86-BMI2-NEXT:    movl $-1, %edx
741; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
742; X86-BMI2-NEXT:    testb $32, %cl
743; X86-BMI2-NEXT:    je .LBB17_2
744; X86-BMI2-NEXT:  # %bb.1:
745; X86-BMI2-NEXT:    movl %eax, %edx
746; X86-BMI2-NEXT:    xorl %eax, %eax
747; X86-BMI2-NEXT:  .LBB17_2:
748; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
749; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
750; X86-BMI2-NEXT:    retl
751;
752; X64-NOBMI2-LABEL: clear_lowbits64_c4_commutative:
753; X64-NOBMI2:       # %bb.0:
754; X64-NOBMI2-NEXT:    movq %rsi, %rcx
755; X64-NOBMI2-NEXT:    movq %rdi, %rax
756; X64-NOBMI2-NEXT:    shrq %cl, %rax
757; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
758; X64-NOBMI2-NEXT:    shlq %cl, %rax
759; X64-NOBMI2-NEXT:    retq
760;
761; X64-BMI2-LABEL: clear_lowbits64_c4_commutative:
762; X64-BMI2:       # %bb.0:
763; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
764; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
765; X64-BMI2-NEXT:    retq
766  %mask = shl i64 -1, %numlowbits
767  %masked = and i64 %val, %mask ; swapped order
768  ret i64 %masked
769}
770
771; ---------------------------------------------------------------------------- ;
772; Pattern ic.
773; ---------------------------------------------------------------------------- ;
774
775; 8-bit
776
777define i8 @clear_lowbits8_ic0(i8 %val, i8 %numlowbits) nounwind {
778; X86-LABEL: clear_lowbits8_ic0:
779; X86:       # %bb.0:
780; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
781; X86-NEXT:    movb $8, %cl
782; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
783; X86-NEXT:    shrb %cl, %al
784; X86-NEXT:    shlb %cl, %al
785; X86-NEXT:    retl
786;
787; X64-LABEL: clear_lowbits8_ic0:
788; X64:       # %bb.0:
789; X64-NEXT:    movl %edi, %eax
790; X64-NEXT:    movb $8, %cl
791; X64-NEXT:    subb %sil, %cl
792; X64-NEXT:    shrb %cl, %al
793; X64-NEXT:    shlb %cl, %al
794; X64-NEXT:    # kill: def $al killed $al killed $eax
795; X64-NEXT:    retq
796  %numhighbits = sub i8 8, %numlowbits
797  %mask = shl i8 -1, %numhighbits
798  %masked = and i8 %mask, %val
799  ret i8 %masked
800}
801
802define i8 @clear_lowbits8_ic2_load(i8* %w, i8 %numlowbits) nounwind {
803; X86-LABEL: clear_lowbits8_ic2_load:
804; X86:       # %bb.0:
805; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
806; X86-NEXT:    movb (%eax), %al
807; X86-NEXT:    movb $8, %cl
808; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
809; X86-NEXT:    shrb %cl, %al
810; X86-NEXT:    shlb %cl, %al
811; X86-NEXT:    retl
812;
813; X64-LABEL: clear_lowbits8_ic2_load:
814; X64:       # %bb.0:
815; X64-NEXT:    movb (%rdi), %al
816; X64-NEXT:    movb $8, %cl
817; X64-NEXT:    subb %sil, %cl
818; X64-NEXT:    shrb %cl, %al
819; X64-NEXT:    shlb %cl, %al
820; X64-NEXT:    retq
821  %val = load i8, i8* %w
822  %numhighbits = sub i8 8, %numlowbits
823  %mask = shl i8 -1, %numhighbits
824  %masked = and i8 %mask, %val
825  ret i8 %masked
826}
827
828define i8 @clear_lowbits8_ic4_commutative(i8 %val, i8 %numlowbits) nounwind {
829; X86-LABEL: clear_lowbits8_ic4_commutative:
830; X86:       # %bb.0:
831; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
832; X86-NEXT:    movb $8, %cl
833; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
834; X86-NEXT:    shrb %cl, %al
835; X86-NEXT:    shlb %cl, %al
836; X86-NEXT:    retl
837;
838; X64-LABEL: clear_lowbits8_ic4_commutative:
839; X64:       # %bb.0:
840; X64-NEXT:    movl %edi, %eax
841; X64-NEXT:    movb $8, %cl
842; X64-NEXT:    subb %sil, %cl
843; X64-NEXT:    shrb %cl, %al
844; X64-NEXT:    shlb %cl, %al
845; X64-NEXT:    # kill: def $al killed $al killed $eax
846; X64-NEXT:    retq
847  %numhighbits = sub i8 8, %numlowbits
848  %mask = shl i8 -1, %numhighbits
849  %masked = and i8 %val, %mask ; swapped order
850  ret i8 %masked
851}
852
853; 16-bit
854
855define i16 @clear_lowbits16_ic0(i16 %val, i16 %numlowbits) nounwind {
856; X86-NOBMI2-LABEL: clear_lowbits16_ic0:
857; X86-NOBMI2:       # %bb.0:
858; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
859; X86-NOBMI2-NEXT:    movb $16, %cl
860; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
861; X86-NOBMI2-NEXT:    shrl %cl, %eax
862; X86-NOBMI2-NEXT:    shll %cl, %eax
863; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
864; X86-NOBMI2-NEXT:    retl
865;
866; X86-BMI2-LABEL: clear_lowbits16_ic0:
867; X86-BMI2:       # %bb.0:
868; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
869; X86-BMI2-NEXT:    movb $16, %cl
870; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
871; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
872; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
873; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
874; X86-BMI2-NEXT:    retl
875;
876; X64-NOBMI2-LABEL: clear_lowbits16_ic0:
877; X64-NOBMI2:       # %bb.0:
878; X64-NOBMI2-NEXT:    movzwl %di, %eax
879; X64-NOBMI2-NEXT:    movb $16, %cl
880; X64-NOBMI2-NEXT:    subb %sil, %cl
881; X64-NOBMI2-NEXT:    shrl %cl, %eax
882; X64-NOBMI2-NEXT:    shll %cl, %eax
883; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
884; X64-NOBMI2-NEXT:    retq
885;
886; X64-BMI2-LABEL: clear_lowbits16_ic0:
887; X64-BMI2:       # %bb.0:
888; X64-BMI2-NEXT:    movzwl %di, %eax
889; X64-BMI2-NEXT:    movb $16, %cl
890; X64-BMI2-NEXT:    subb %sil, %cl
891; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
892; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
893; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
894; X64-BMI2-NEXT:    retq
895  %numhighbits = sub i16 16, %numlowbits
896  %mask = shl i16 -1, %numhighbits
897  %masked = and i16 %mask, %val
898  ret i16 %masked
899}
900
901define i16 @clear_lowbits16_ic1_indexzext(i16 %val, i8 %numlowbits) nounwind {
902; X86-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext:
903; X86-NOBMI2:       # %bb.0:
904; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
905; X86-NOBMI2-NEXT:    movb $16, %cl
906; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
907; X86-NOBMI2-NEXT:    shrl %cl, %eax
908; X86-NOBMI2-NEXT:    shll %cl, %eax
909; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
910; X86-NOBMI2-NEXT:    retl
911;
912; X86-BMI2-LABEL: clear_lowbits16_ic1_indexzext:
913; X86-BMI2:       # %bb.0:
914; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
915; X86-BMI2-NEXT:    movb $16, %cl
916; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
917; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
918; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
919; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
920; X86-BMI2-NEXT:    retl
921;
922; X64-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext:
923; X64-NOBMI2:       # %bb.0:
924; X64-NOBMI2-NEXT:    movzwl %di, %eax
925; X64-NOBMI2-NEXT:    movb $16, %cl
926; X64-NOBMI2-NEXT:    subb %sil, %cl
927; X64-NOBMI2-NEXT:    shrl %cl, %eax
928; X64-NOBMI2-NEXT:    shll %cl, %eax
929; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
930; X64-NOBMI2-NEXT:    retq
931;
932; X64-BMI2-LABEL: clear_lowbits16_ic1_indexzext:
933; X64-BMI2:       # %bb.0:
934; X64-BMI2-NEXT:    movzwl %di, %eax
935; X64-BMI2-NEXT:    movb $16, %cl
936; X64-BMI2-NEXT:    subb %sil, %cl
937; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
938; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
939; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
940; X64-BMI2-NEXT:    retq
941  %numhighbits = sub i8 16, %numlowbits
942  %sh_prom = zext i8 %numhighbits to i16
943  %mask = shl i16 -1, %sh_prom
944  %masked = and i16 %mask, %val
945  ret i16 %masked
946}
947
948define i16 @clear_lowbits16_ic2_load(i16* %w, i16 %numlowbits) nounwind {
949; X86-NOBMI2-LABEL: clear_lowbits16_ic2_load:
950; X86-NOBMI2:       # %bb.0:
951; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
952; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
953; X86-NOBMI2-NEXT:    movb $16, %cl
954; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
955; X86-NOBMI2-NEXT:    shrl %cl, %eax
956; X86-NOBMI2-NEXT:    shll %cl, %eax
957; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
958; X86-NOBMI2-NEXT:    retl
959;
960; X86-BMI2-LABEL: clear_lowbits16_ic2_load:
961; X86-BMI2:       # %bb.0:
962; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
963; X86-BMI2-NEXT:    movzwl (%eax), %eax
964; X86-BMI2-NEXT:    movb $16, %cl
965; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
966; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
967; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
968; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
969; X86-BMI2-NEXT:    retl
970;
971; X64-NOBMI2-LABEL: clear_lowbits16_ic2_load:
972; X64-NOBMI2:       # %bb.0:
973; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
974; X64-NOBMI2-NEXT:    movb $16, %cl
975; X64-NOBMI2-NEXT:    subb %sil, %cl
976; X64-NOBMI2-NEXT:    shrl %cl, %eax
977; X64-NOBMI2-NEXT:    shll %cl, %eax
978; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
979; X64-NOBMI2-NEXT:    retq
980;
981; X64-BMI2-LABEL: clear_lowbits16_ic2_load:
982; X64-BMI2:       # %bb.0:
983; X64-BMI2-NEXT:    movzwl (%rdi), %eax
984; X64-BMI2-NEXT:    movb $16, %cl
985; X64-BMI2-NEXT:    subb %sil, %cl
986; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
987; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
988; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
989; X64-BMI2-NEXT:    retq
990  %val = load i16, i16* %w
991  %numhighbits = sub i16 16, %numlowbits
992  %mask = shl i16 -1, %numhighbits
993  %masked = and i16 %mask, %val
994  ret i16 %masked
995}
996
997define i16 @clear_lowbits16_ic3_load_indexzext(i16* %w, i8 %numlowbits) nounwind {
998; X86-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
999; X86-NOBMI2:       # %bb.0:
1000; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1001; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
1002; X86-NOBMI2-NEXT:    movb $16, %cl
1003; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1004; X86-NOBMI2-NEXT:    shrl %cl, %eax
1005; X86-NOBMI2-NEXT:    shll %cl, %eax
1006; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1007; X86-NOBMI2-NEXT:    retl
1008;
1009; X86-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1010; X86-BMI2:       # %bb.0:
1011; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1012; X86-BMI2-NEXT:    movzwl (%eax), %eax
1013; X86-BMI2-NEXT:    movb $16, %cl
1014; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1015; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1016; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1017; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1018; X86-BMI2-NEXT:    retl
1019;
1020; X64-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1021; X64-NOBMI2:       # %bb.0:
1022; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
1023; X64-NOBMI2-NEXT:    movb $16, %cl
1024; X64-NOBMI2-NEXT:    subb %sil, %cl
1025; X64-NOBMI2-NEXT:    shrl %cl, %eax
1026; X64-NOBMI2-NEXT:    shll %cl, %eax
1027; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1028; X64-NOBMI2-NEXT:    retq
1029;
1030; X64-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1031; X64-BMI2:       # %bb.0:
1032; X64-BMI2-NEXT:    movzwl (%rdi), %eax
1033; X64-BMI2-NEXT:    movb $16, %cl
1034; X64-BMI2-NEXT:    subb %sil, %cl
1035; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1036; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1037; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1038; X64-BMI2-NEXT:    retq
1039  %val = load i16, i16* %w
1040  %numhighbits = sub i8 16, %numlowbits
1041  %sh_prom = zext i8 %numhighbits to i16
1042  %mask = shl i16 -1, %sh_prom
1043  %masked = and i16 %mask, %val
1044  ret i16 %masked
1045}
1046
1047define i16 @clear_lowbits16_ic4_commutative(i16 %val, i16 %numlowbits) nounwind {
1048; X86-NOBMI2-LABEL: clear_lowbits16_ic4_commutative:
1049; X86-NOBMI2:       # %bb.0:
1050; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1051; X86-NOBMI2-NEXT:    movb $16, %cl
1052; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1053; X86-NOBMI2-NEXT:    shrl %cl, %eax
1054; X86-NOBMI2-NEXT:    shll %cl, %eax
1055; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1056; X86-NOBMI2-NEXT:    retl
1057;
1058; X86-BMI2-LABEL: clear_lowbits16_ic4_commutative:
1059; X86-BMI2:       # %bb.0:
1060; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1061; X86-BMI2-NEXT:    movb $16, %cl
1062; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1063; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1064; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1065; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1066; X86-BMI2-NEXT:    retl
1067;
1068; X64-NOBMI2-LABEL: clear_lowbits16_ic4_commutative:
1069; X64-NOBMI2:       # %bb.0:
1070; X64-NOBMI2-NEXT:    movzwl %di, %eax
1071; X64-NOBMI2-NEXT:    movb $16, %cl
1072; X64-NOBMI2-NEXT:    subb %sil, %cl
1073; X64-NOBMI2-NEXT:    shrl %cl, %eax
1074; X64-NOBMI2-NEXT:    shll %cl, %eax
1075; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1076; X64-NOBMI2-NEXT:    retq
1077;
1078; X64-BMI2-LABEL: clear_lowbits16_ic4_commutative:
1079; X64-BMI2:       # %bb.0:
1080; X64-BMI2-NEXT:    movzwl %di, %eax
1081; X64-BMI2-NEXT:    movb $16, %cl
1082; X64-BMI2-NEXT:    subb %sil, %cl
1083; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1084; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1085; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1086; X64-BMI2-NEXT:    retq
1087  %numhighbits = sub i16 16, %numlowbits
1088  %mask = shl i16 -1, %numhighbits
1089  %masked = and i16 %val, %mask ; swapped order
1090  ret i16 %masked
1091}
1092
1093; 32-bit
1094
1095define i32 @clear_lowbits32_ic0(i32 %val, i32 %numlowbits) nounwind {
1096; X86-NOBMI2-LABEL: clear_lowbits32_ic0:
1097; X86-NOBMI2:       # %bb.0:
1098; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1099; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1100; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1101; X86-NOBMI2-NEXT:    shrl %cl, %eax
1102; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1103; X86-NOBMI2-NEXT:    shll %cl, %eax
1104; X86-NOBMI2-NEXT:    retl
1105;
1106; X86-BMI2-LABEL: clear_lowbits32_ic0:
1107; X86-BMI2:       # %bb.0:
1108; X86-BMI2-NEXT:    xorl %eax, %eax
1109; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1110; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1111; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1112; X86-BMI2-NEXT:    retl
1113;
1114; X64-NOBMI2-LABEL: clear_lowbits32_ic0:
1115; X64-NOBMI2:       # %bb.0:
1116; X64-NOBMI2-NEXT:    movl %esi, %ecx
1117; X64-NOBMI2-NEXT:    movl %edi, %eax
1118; X64-NOBMI2-NEXT:    negb %cl
1119; X64-NOBMI2-NEXT:    shrl %cl, %eax
1120; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1121; X64-NOBMI2-NEXT:    shll %cl, %eax
1122; X64-NOBMI2-NEXT:    retq
1123;
1124; X64-BMI2-LABEL: clear_lowbits32_ic0:
1125; X64-BMI2:       # %bb.0:
1126; X64-BMI2-NEXT:    negb %sil
1127; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1128; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1129; X64-BMI2-NEXT:    retq
1130  %numhighbits = sub i32 32, %numlowbits
1131  %mask = shl i32 -1, %numhighbits
1132  %masked = and i32 %mask, %val
1133  ret i32 %masked
1134}
1135
1136define i32 @clear_lowbits32_ic1_indexzext(i32 %val, i8 %numlowbits) nounwind {
1137; X86-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext:
1138; X86-NOBMI2:       # %bb.0:
1139; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1140; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1141; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1142; X86-NOBMI2-NEXT:    shrl %cl, %eax
1143; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1144; X86-NOBMI2-NEXT:    shll %cl, %eax
1145; X86-NOBMI2-NEXT:    retl
1146;
1147; X86-BMI2-LABEL: clear_lowbits32_ic1_indexzext:
1148; X86-BMI2:       # %bb.0:
1149; X86-BMI2-NEXT:    xorl %eax, %eax
1150; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1151; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1152; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1153; X86-BMI2-NEXT:    retl
1154;
1155; X64-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext:
1156; X64-NOBMI2:       # %bb.0:
1157; X64-NOBMI2-NEXT:    movl %esi, %ecx
1158; X64-NOBMI2-NEXT:    movl %edi, %eax
1159; X64-NOBMI2-NEXT:    negb %cl
1160; X64-NOBMI2-NEXT:    shrl %cl, %eax
1161; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1162; X64-NOBMI2-NEXT:    shll %cl, %eax
1163; X64-NOBMI2-NEXT:    retq
1164;
1165; X64-BMI2-LABEL: clear_lowbits32_ic1_indexzext:
1166; X64-BMI2:       # %bb.0:
1167; X64-BMI2-NEXT:    negb %sil
1168; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1169; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1170; X64-BMI2-NEXT:    retq
1171  %numhighbits = sub i8 32, %numlowbits
1172  %sh_prom = zext i8 %numhighbits to i32
1173  %mask = shl i32 -1, %sh_prom
1174  %masked = and i32 %mask, %val
1175  ret i32 %masked
1176}
1177
1178define i32 @clear_lowbits32_ic2_load(i32* %w, i32 %numlowbits) nounwind {
1179; X86-NOBMI2-LABEL: clear_lowbits32_ic2_load:
1180; X86-NOBMI2:       # %bb.0:
1181; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1182; X86-NOBMI2-NEXT:    movl (%eax), %eax
1183; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1184; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1185; X86-NOBMI2-NEXT:    shrl %cl, %eax
1186; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1187; X86-NOBMI2-NEXT:    shll %cl, %eax
1188; X86-NOBMI2-NEXT:    retl
1189;
1190; X86-BMI2-LABEL: clear_lowbits32_ic2_load:
1191; X86-BMI2:       # %bb.0:
1192; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1193; X86-BMI2-NEXT:    xorl %ecx, %ecx
1194; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1195; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
1196; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1197; X86-BMI2-NEXT:    retl
1198;
1199; X64-NOBMI2-LABEL: clear_lowbits32_ic2_load:
1200; X64-NOBMI2:       # %bb.0:
1201; X64-NOBMI2-NEXT:    movl %esi, %ecx
1202; X64-NOBMI2-NEXT:    movl (%rdi), %eax
1203; X64-NOBMI2-NEXT:    negb %cl
1204; X64-NOBMI2-NEXT:    shrl %cl, %eax
1205; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1206; X64-NOBMI2-NEXT:    shll %cl, %eax
1207; X64-NOBMI2-NEXT:    retq
1208;
1209; X64-BMI2-LABEL: clear_lowbits32_ic2_load:
1210; X64-BMI2:       # %bb.0:
1211; X64-BMI2-NEXT:    negb %sil
1212; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1213; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1214; X64-BMI2-NEXT:    retq
1215  %val = load i32, i32* %w
1216  %numhighbits = sub i32 32, %numlowbits
1217  %mask = shl i32 -1, %numhighbits
1218  %masked = and i32 %mask, %val
1219  ret i32 %masked
1220}
1221
1222define i32 @clear_lowbits32_ic3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
1223; X86-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1224; X86-NOBMI2:       # %bb.0:
1225; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1226; X86-NOBMI2-NEXT:    movl (%eax), %eax
1227; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1228; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1229; X86-NOBMI2-NEXT:    shrl %cl, %eax
1230; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1231; X86-NOBMI2-NEXT:    shll %cl, %eax
1232; X86-NOBMI2-NEXT:    retl
1233;
1234; X86-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1235; X86-BMI2:       # %bb.0:
1236; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1237; X86-BMI2-NEXT:    xorl %ecx, %ecx
1238; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1239; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
1240; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1241; X86-BMI2-NEXT:    retl
1242;
1243; X64-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1244; X64-NOBMI2:       # %bb.0:
1245; X64-NOBMI2-NEXT:    movl %esi, %ecx
1246; X64-NOBMI2-NEXT:    movl (%rdi), %eax
1247; X64-NOBMI2-NEXT:    negb %cl
1248; X64-NOBMI2-NEXT:    shrl %cl, %eax
1249; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1250; X64-NOBMI2-NEXT:    shll %cl, %eax
1251; X64-NOBMI2-NEXT:    retq
1252;
1253; X64-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1254; X64-BMI2:       # %bb.0:
1255; X64-BMI2-NEXT:    negb %sil
1256; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1257; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1258; X64-BMI2-NEXT:    retq
1259  %val = load i32, i32* %w
1260  %numhighbits = sub i8 32, %numlowbits
1261  %sh_prom = zext i8 %numhighbits to i32
1262  %mask = shl i32 -1, %sh_prom
1263  %masked = and i32 %mask, %val
1264  ret i32 %masked
1265}
1266
1267define i32 @clear_lowbits32_ic4_commutative(i32 %val, i32 %numlowbits) nounwind {
1268; X86-NOBMI2-LABEL: clear_lowbits32_ic4_commutative:
1269; X86-NOBMI2:       # %bb.0:
1270; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1271; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1272; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1273; X86-NOBMI2-NEXT:    shrl %cl, %eax
1274; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1275; X86-NOBMI2-NEXT:    shll %cl, %eax
1276; X86-NOBMI2-NEXT:    retl
1277;
1278; X86-BMI2-LABEL: clear_lowbits32_ic4_commutative:
1279; X86-BMI2:       # %bb.0:
1280; X86-BMI2-NEXT:    xorl %eax, %eax
1281; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1282; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1283; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1284; X86-BMI2-NEXT:    retl
1285;
1286; X64-NOBMI2-LABEL: clear_lowbits32_ic4_commutative:
1287; X64-NOBMI2:       # %bb.0:
1288; X64-NOBMI2-NEXT:    movl %esi, %ecx
1289; X64-NOBMI2-NEXT:    movl %edi, %eax
1290; X64-NOBMI2-NEXT:    negb %cl
1291; X64-NOBMI2-NEXT:    shrl %cl, %eax
1292; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1293; X64-NOBMI2-NEXT:    shll %cl, %eax
1294; X64-NOBMI2-NEXT:    retq
1295;
1296; X64-BMI2-LABEL: clear_lowbits32_ic4_commutative:
1297; X64-BMI2:       # %bb.0:
1298; X64-BMI2-NEXT:    negb %sil
1299; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1300; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1301; X64-BMI2-NEXT:    retq
1302  %numhighbits = sub i32 32, %numlowbits
1303  %mask = shl i32 -1, %numhighbits
1304  %masked = and i32 %val, %mask ; swapped order
1305  ret i32 %masked
1306}
1307
1308; 64-bit
1309
1310define i64 @clear_lowbits64_ic0(i64 %val, i64 %numlowbits) nounwind {
1311; X86-NOBMI2-LABEL: clear_lowbits64_ic0:
1312; X86-NOBMI2:       # %bb.0:
1313; X86-NOBMI2-NEXT:    movb $64, %cl
1314; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1315; X86-NOBMI2-NEXT:    movl $-1, %edx
1316; X86-NOBMI2-NEXT:    movl $-1, %eax
1317; X86-NOBMI2-NEXT:    shll %cl, %eax
1318; X86-NOBMI2-NEXT:    testb $32, %cl
1319; X86-NOBMI2-NEXT:    je .LBB31_2
1320; X86-NOBMI2-NEXT:  # %bb.1:
1321; X86-NOBMI2-NEXT:    movl %eax, %edx
1322; X86-NOBMI2-NEXT:    xorl %eax, %eax
1323; X86-NOBMI2-NEXT:  .LBB31_2:
1324; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1325; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1326; X86-NOBMI2-NEXT:    retl
1327;
1328; X86-BMI2-LABEL: clear_lowbits64_ic0:
1329; X86-BMI2:       # %bb.0:
1330; X86-BMI2-NEXT:    movb $64, %cl
1331; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1332; X86-BMI2-NEXT:    movl $-1, %edx
1333; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1334; X86-BMI2-NEXT:    testb $32, %cl
1335; X86-BMI2-NEXT:    je .LBB31_2
1336; X86-BMI2-NEXT:  # %bb.1:
1337; X86-BMI2-NEXT:    movl %eax, %edx
1338; X86-BMI2-NEXT:    xorl %eax, %eax
1339; X86-BMI2-NEXT:  .LBB31_2:
1340; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1341; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1342; X86-BMI2-NEXT:    retl
1343;
1344; X64-NOBMI2-LABEL: clear_lowbits64_ic0:
1345; X64-NOBMI2:       # %bb.0:
1346; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1347; X64-NOBMI2-NEXT:    movq %rdi, %rax
1348; X64-NOBMI2-NEXT:    negb %cl
1349; X64-NOBMI2-NEXT:    shrq %cl, %rax
1350; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1351; X64-NOBMI2-NEXT:    shlq %cl, %rax
1352; X64-NOBMI2-NEXT:    retq
1353;
1354; X64-BMI2-LABEL: clear_lowbits64_ic0:
1355; X64-BMI2:       # %bb.0:
1356; X64-BMI2-NEXT:    negb %sil
1357; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1358; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1359; X64-BMI2-NEXT:    retq
1360  %numhighbits = sub i64 64, %numlowbits
1361  %mask = shl i64 -1, %numhighbits
1362  %masked = and i64 %mask, %val
1363  ret i64 %masked
1364}
1365
1366define i64 @clear_lowbits64_ic1_indexzext(i64 %val, i8 %numlowbits) nounwind {
1367; X86-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext:
1368; X86-NOBMI2:       # %bb.0:
1369; X86-NOBMI2-NEXT:    movb $64, %cl
1370; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1371; X86-NOBMI2-NEXT:    movl $-1, %edx
1372; X86-NOBMI2-NEXT:    movl $-1, %eax
1373; X86-NOBMI2-NEXT:    shll %cl, %eax
1374; X86-NOBMI2-NEXT:    testb $32, %cl
1375; X86-NOBMI2-NEXT:    je .LBB32_2
1376; X86-NOBMI2-NEXT:  # %bb.1:
1377; X86-NOBMI2-NEXT:    movl %eax, %edx
1378; X86-NOBMI2-NEXT:    xorl %eax, %eax
1379; X86-NOBMI2-NEXT:  .LBB32_2:
1380; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1381; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1382; X86-NOBMI2-NEXT:    retl
1383;
1384; X86-BMI2-LABEL: clear_lowbits64_ic1_indexzext:
1385; X86-BMI2:       # %bb.0:
1386; X86-BMI2-NEXT:    movb $64, %cl
1387; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1388; X86-BMI2-NEXT:    movl $-1, %edx
1389; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1390; X86-BMI2-NEXT:    testb $32, %cl
1391; X86-BMI2-NEXT:    je .LBB32_2
1392; X86-BMI2-NEXT:  # %bb.1:
1393; X86-BMI2-NEXT:    movl %eax, %edx
1394; X86-BMI2-NEXT:    xorl %eax, %eax
1395; X86-BMI2-NEXT:  .LBB32_2:
1396; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1397; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1398; X86-BMI2-NEXT:    retl
1399;
1400; X64-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext:
1401; X64-NOBMI2:       # %bb.0:
1402; X64-NOBMI2-NEXT:    movl %esi, %ecx
1403; X64-NOBMI2-NEXT:    movq %rdi, %rax
1404; X64-NOBMI2-NEXT:    negb %cl
1405; X64-NOBMI2-NEXT:    shrq %cl, %rax
1406; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1407; X64-NOBMI2-NEXT:    shlq %cl, %rax
1408; X64-NOBMI2-NEXT:    retq
1409;
1410; X64-BMI2-LABEL: clear_lowbits64_ic1_indexzext:
1411; X64-BMI2:       # %bb.0:
1412; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1413; X64-BMI2-NEXT:    negb %sil
1414; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1415; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1416; X64-BMI2-NEXT:    retq
1417  %numhighbits = sub i8 64, %numlowbits
1418  %sh_prom = zext i8 %numhighbits to i64
1419  %mask = shl i64 -1, %sh_prom
1420  %masked = and i64 %mask, %val
1421  ret i64 %masked
1422}
1423
1424define i64 @clear_lowbits64_ic2_load(i64* %w, i64 %numlowbits) nounwind {
1425; X86-NOBMI2-LABEL: clear_lowbits64_ic2_load:
1426; X86-NOBMI2:       # %bb.0:
1427; X86-NOBMI2-NEXT:    pushl %esi
1428; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1429; X86-NOBMI2-NEXT:    movb $64, %cl
1430; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1431; X86-NOBMI2-NEXT:    movl $-1, %edx
1432; X86-NOBMI2-NEXT:    movl $-1, %eax
1433; X86-NOBMI2-NEXT:    shll %cl, %eax
1434; X86-NOBMI2-NEXT:    testb $32, %cl
1435; X86-NOBMI2-NEXT:    je .LBB33_2
1436; X86-NOBMI2-NEXT:  # %bb.1:
1437; X86-NOBMI2-NEXT:    movl %eax, %edx
1438; X86-NOBMI2-NEXT:    xorl %eax, %eax
1439; X86-NOBMI2-NEXT:  .LBB33_2:
1440; X86-NOBMI2-NEXT:    andl (%esi), %eax
1441; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
1442; X86-NOBMI2-NEXT:    popl %esi
1443; X86-NOBMI2-NEXT:    retl
1444;
1445; X86-BMI2-LABEL: clear_lowbits64_ic2_load:
1446; X86-BMI2:       # %bb.0:
1447; X86-BMI2-NEXT:    pushl %ebx
1448; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1449; X86-BMI2-NEXT:    movb $64, %bl
1450; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %bl
1451; X86-BMI2-NEXT:    movl $-1, %edx
1452; X86-BMI2-NEXT:    shlxl %ebx, %edx, %eax
1453; X86-BMI2-NEXT:    testb $32, %bl
1454; X86-BMI2-NEXT:    je .LBB33_2
1455; X86-BMI2-NEXT:  # %bb.1:
1456; X86-BMI2-NEXT:    movl %eax, %edx
1457; X86-BMI2-NEXT:    xorl %eax, %eax
1458; X86-BMI2-NEXT:  .LBB33_2:
1459; X86-BMI2-NEXT:    andl (%ecx), %eax
1460; X86-BMI2-NEXT:    andl 4(%ecx), %edx
1461; X86-BMI2-NEXT:    popl %ebx
1462; X86-BMI2-NEXT:    retl
1463;
1464; X64-NOBMI2-LABEL: clear_lowbits64_ic2_load:
1465; X64-NOBMI2:       # %bb.0:
1466; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1467; X64-NOBMI2-NEXT:    movq (%rdi), %rax
1468; X64-NOBMI2-NEXT:    negb %cl
1469; X64-NOBMI2-NEXT:    shrq %cl, %rax
1470; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1471; X64-NOBMI2-NEXT:    shlq %cl, %rax
1472; X64-NOBMI2-NEXT:    retq
1473;
1474; X64-BMI2-LABEL: clear_lowbits64_ic2_load:
1475; X64-BMI2:       # %bb.0:
1476; X64-BMI2-NEXT:    negb %sil
1477; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1478; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1479; X64-BMI2-NEXT:    retq
1480  %val = load i64, i64* %w
1481  %numhighbits = sub i64 64, %numlowbits
1482  %mask = shl i64 -1, %numhighbits
1483  %masked = and i64 %mask, %val
1484  ret i64 %masked
1485}
1486
1487define i64 @clear_lowbits64_ic3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
1488; X86-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1489; X86-NOBMI2:       # %bb.0:
1490; X86-NOBMI2-NEXT:    pushl %esi
1491; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1492; X86-NOBMI2-NEXT:    movb $64, %cl
1493; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1494; X86-NOBMI2-NEXT:    movl $-1, %edx
1495; X86-NOBMI2-NEXT:    movl $-1, %eax
1496; X86-NOBMI2-NEXT:    shll %cl, %eax
1497; X86-NOBMI2-NEXT:    testb $32, %cl
1498; X86-NOBMI2-NEXT:    je .LBB34_2
1499; X86-NOBMI2-NEXT:  # %bb.1:
1500; X86-NOBMI2-NEXT:    movl %eax, %edx
1501; X86-NOBMI2-NEXT:    xorl %eax, %eax
1502; X86-NOBMI2-NEXT:  .LBB34_2:
1503; X86-NOBMI2-NEXT:    andl (%esi), %eax
1504; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
1505; X86-NOBMI2-NEXT:    popl %esi
1506; X86-NOBMI2-NEXT:    retl
1507;
1508; X86-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1509; X86-BMI2:       # %bb.0:
1510; X86-BMI2-NEXT:    pushl %ebx
1511; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1512; X86-BMI2-NEXT:    movb $64, %bl
1513; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %bl
1514; X86-BMI2-NEXT:    movl $-1, %edx
1515; X86-BMI2-NEXT:    shlxl %ebx, %edx, %eax
1516; X86-BMI2-NEXT:    testb $32, %bl
1517; X86-BMI2-NEXT:    je .LBB34_2
1518; X86-BMI2-NEXT:  # %bb.1:
1519; X86-BMI2-NEXT:    movl %eax, %edx
1520; X86-BMI2-NEXT:    xorl %eax, %eax
1521; X86-BMI2-NEXT:  .LBB34_2:
1522; X86-BMI2-NEXT:    andl (%ecx), %eax
1523; X86-BMI2-NEXT:    andl 4(%ecx), %edx
1524; X86-BMI2-NEXT:    popl %ebx
1525; X86-BMI2-NEXT:    retl
1526;
1527; X64-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1528; X64-NOBMI2:       # %bb.0:
1529; X64-NOBMI2-NEXT:    movl %esi, %ecx
1530; X64-NOBMI2-NEXT:    movq (%rdi), %rax
1531; X64-NOBMI2-NEXT:    negb %cl
1532; X64-NOBMI2-NEXT:    shrq %cl, %rax
1533; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1534; X64-NOBMI2-NEXT:    shlq %cl, %rax
1535; X64-NOBMI2-NEXT:    retq
1536;
1537; X64-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1538; X64-BMI2:       # %bb.0:
1539; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1540; X64-BMI2-NEXT:    negb %sil
1541; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1542; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1543; X64-BMI2-NEXT:    retq
1544  %val = load i64, i64* %w
1545  %numhighbits = sub i8 64, %numlowbits
1546  %sh_prom = zext i8 %numhighbits to i64
1547  %mask = shl i64 -1, %sh_prom
1548  %masked = and i64 %mask, %val
1549  ret i64 %masked
1550}
1551
1552define i64 @clear_lowbits64_ic4_commutative(i64 %val, i64 %numlowbits) nounwind {
1553; X86-NOBMI2-LABEL: clear_lowbits64_ic4_commutative:
1554; X86-NOBMI2:       # %bb.0:
1555; X86-NOBMI2-NEXT:    movb $64, %cl
1556; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1557; X86-NOBMI2-NEXT:    movl $-1, %edx
1558; X86-NOBMI2-NEXT:    movl $-1, %eax
1559; X86-NOBMI2-NEXT:    shll %cl, %eax
1560; X86-NOBMI2-NEXT:    testb $32, %cl
1561; X86-NOBMI2-NEXT:    je .LBB35_2
1562; X86-NOBMI2-NEXT:  # %bb.1:
1563; X86-NOBMI2-NEXT:    movl %eax, %edx
1564; X86-NOBMI2-NEXT:    xorl %eax, %eax
1565; X86-NOBMI2-NEXT:  .LBB35_2:
1566; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1567; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1568; X86-NOBMI2-NEXT:    retl
1569;
1570; X86-BMI2-LABEL: clear_lowbits64_ic4_commutative:
1571; X86-BMI2:       # %bb.0:
1572; X86-BMI2-NEXT:    movb $64, %cl
1573; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1574; X86-BMI2-NEXT:    movl $-1, %edx
1575; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1576; X86-BMI2-NEXT:    testb $32, %cl
1577; X86-BMI2-NEXT:    je .LBB35_2
1578; X86-BMI2-NEXT:  # %bb.1:
1579; X86-BMI2-NEXT:    movl %eax, %edx
1580; X86-BMI2-NEXT:    xorl %eax, %eax
1581; X86-BMI2-NEXT:  .LBB35_2:
1582; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1583; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1584; X86-BMI2-NEXT:    retl
1585;
1586; X64-NOBMI2-LABEL: clear_lowbits64_ic4_commutative:
1587; X64-NOBMI2:       # %bb.0:
1588; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1589; X64-NOBMI2-NEXT:    movq %rdi, %rax
1590; X64-NOBMI2-NEXT:    negb %cl
1591; X64-NOBMI2-NEXT:    shrq %cl, %rax
1592; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1593; X64-NOBMI2-NEXT:    shlq %cl, %rax
1594; X64-NOBMI2-NEXT:    retq
1595;
1596; X64-BMI2-LABEL: clear_lowbits64_ic4_commutative:
1597; X64-BMI2:       # %bb.0:
1598; X64-BMI2-NEXT:    negb %sil
1599; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1600; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1601; X64-BMI2-NEXT:    retq
1602  %numhighbits = sub i64 64, %numlowbits
1603  %mask = shl i64 -1, %numhighbits
1604  %masked = and i64 %val, %mask ; swapped order
1605  ret i64 %masked
1606}
1607
1608; ---------------------------------------------------------------------------- ;
1609; Multi-use tests
1610; ---------------------------------------------------------------------------- ;
1611
1612declare void @use32(i32)
1613declare void @use64(i64)
1614
1615define i32 @oneuse32(i32 %val, i32 %numlowbits) nounwind {
1616; X86-NOBMI2-LABEL: oneuse32:
1617; X86-NOBMI2:       # %bb.0:
1618; X86-NOBMI2-NEXT:    pushl %esi
1619; X86-NOBMI2-NEXT:    subl $8, %esp
1620; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1621; X86-NOBMI2-NEXT:    movl $-1, %esi
1622; X86-NOBMI2-NEXT:    shll %cl, %esi
1623; X86-NOBMI2-NEXT:    movl %esi, (%esp)
1624; X86-NOBMI2-NEXT:    calll use32
1625; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1626; X86-NOBMI2-NEXT:    movl %esi, %eax
1627; X86-NOBMI2-NEXT:    addl $8, %esp
1628; X86-NOBMI2-NEXT:    popl %esi
1629; X86-NOBMI2-NEXT:    retl
1630;
1631; X86-BMI2-LABEL: oneuse32:
1632; X86-BMI2:       # %bb.0:
1633; X86-BMI2-NEXT:    pushl %esi
1634; X86-BMI2-NEXT:    subl $8, %esp
1635; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1636; X86-BMI2-NEXT:    movl $-1, %ecx
1637; X86-BMI2-NEXT:    shlxl %eax, %ecx, %esi
1638; X86-BMI2-NEXT:    movl %esi, (%esp)
1639; X86-BMI2-NEXT:    calll use32
1640; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1641; X86-BMI2-NEXT:    movl %esi, %eax
1642; X86-BMI2-NEXT:    addl $8, %esp
1643; X86-BMI2-NEXT:    popl %esi
1644; X86-BMI2-NEXT:    retl
1645;
1646; X64-NOBMI2-LABEL: oneuse32:
1647; X64-NOBMI2:       # %bb.0:
1648; X64-NOBMI2-NEXT:    pushq %rbp
1649; X64-NOBMI2-NEXT:    pushq %rbx
1650; X64-NOBMI2-NEXT:    pushq %rax
1651; X64-NOBMI2-NEXT:    movl %esi, %ecx
1652; X64-NOBMI2-NEXT:    movl %edi, %ebx
1653; X64-NOBMI2-NEXT:    movl $-1, %ebp
1654; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1655; X64-NOBMI2-NEXT:    shll %cl, %ebp
1656; X64-NOBMI2-NEXT:    movl %ebp, %edi
1657; X64-NOBMI2-NEXT:    callq use32
1658; X64-NOBMI2-NEXT:    andl %ebx, %ebp
1659; X64-NOBMI2-NEXT:    movl %ebp, %eax
1660; X64-NOBMI2-NEXT:    addq $8, %rsp
1661; X64-NOBMI2-NEXT:    popq %rbx
1662; X64-NOBMI2-NEXT:    popq %rbp
1663; X64-NOBMI2-NEXT:    retq
1664;
1665; X64-BMI2-LABEL: oneuse32:
1666; X64-BMI2:       # %bb.0:
1667; X64-BMI2-NEXT:    pushq %rbp
1668; X64-BMI2-NEXT:    pushq %rbx
1669; X64-BMI2-NEXT:    pushq %rax
1670; X64-BMI2-NEXT:    movl %edi, %ebx
1671; X64-BMI2-NEXT:    movl $-1, %eax
1672; X64-BMI2-NEXT:    shlxl %esi, %eax, %ebp
1673; X64-BMI2-NEXT:    movl %ebp, %edi
1674; X64-BMI2-NEXT:    callq use32
1675; X64-BMI2-NEXT:    andl %ebx, %ebp
1676; X64-BMI2-NEXT:    movl %ebp, %eax
1677; X64-BMI2-NEXT:    addq $8, %rsp
1678; X64-BMI2-NEXT:    popq %rbx
1679; X64-BMI2-NEXT:    popq %rbp
1680; X64-BMI2-NEXT:    retq
1681  %mask = shl i32 -1, %numlowbits
1682  call void @use32(i32 %mask)
1683  %masked = and i32 %mask, %val
1684  ret i32 %masked
1685}
1686
1687define i64 @oneuse64(i64 %val, i64 %numlowbits) nounwind {
1688; X86-NOBMI2-LABEL: oneuse64:
1689; X86-NOBMI2:       # %bb.0:
1690; X86-NOBMI2-NEXT:    pushl %edi
1691; X86-NOBMI2-NEXT:    pushl %esi
1692; X86-NOBMI2-NEXT:    pushl %eax
1693; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1694; X86-NOBMI2-NEXT:    movl $-1, %esi
1695; X86-NOBMI2-NEXT:    movl $-1, %eax
1696; X86-NOBMI2-NEXT:    shll %cl, %eax
1697; X86-NOBMI2-NEXT:    xorl %edi, %edi
1698; X86-NOBMI2-NEXT:    testb $32, %cl
1699; X86-NOBMI2-NEXT:    jne .LBB37_1
1700; X86-NOBMI2-NEXT:  # %bb.2:
1701; X86-NOBMI2-NEXT:    movl %eax, %edi
1702; X86-NOBMI2-NEXT:    jmp .LBB37_3
1703; X86-NOBMI2-NEXT:  .LBB37_1:
1704; X86-NOBMI2-NEXT:    movl %eax, %esi
1705; X86-NOBMI2-NEXT:  .LBB37_3:
1706; X86-NOBMI2-NEXT:    subl $8, %esp
1707; X86-NOBMI2-NEXT:    pushl %esi
1708; X86-NOBMI2-NEXT:    pushl %edi
1709; X86-NOBMI2-NEXT:    calll use64
1710; X86-NOBMI2-NEXT:    addl $16, %esp
1711; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
1712; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1713; X86-NOBMI2-NEXT:    movl %edi, %eax
1714; X86-NOBMI2-NEXT:    movl %esi, %edx
1715; X86-NOBMI2-NEXT:    addl $4, %esp
1716; X86-NOBMI2-NEXT:    popl %esi
1717; X86-NOBMI2-NEXT:    popl %edi
1718; X86-NOBMI2-NEXT:    retl
1719;
1720; X86-BMI2-LABEL: oneuse64:
1721; X86-BMI2:       # %bb.0:
1722; X86-BMI2-NEXT:    pushl %edi
1723; X86-BMI2-NEXT:    pushl %esi
1724; X86-BMI2-NEXT:    pushl %eax
1725; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1726; X86-BMI2-NEXT:    movl $-1, %esi
1727; X86-BMI2-NEXT:    shlxl %ecx, %esi, %eax
1728; X86-BMI2-NEXT:    xorl %edi, %edi
1729; X86-BMI2-NEXT:    testb $32, %cl
1730; X86-BMI2-NEXT:    jne .LBB37_1
1731; X86-BMI2-NEXT:  # %bb.2:
1732; X86-BMI2-NEXT:    movl %eax, %edi
1733; X86-BMI2-NEXT:    jmp .LBB37_3
1734; X86-BMI2-NEXT:  .LBB37_1:
1735; X86-BMI2-NEXT:    movl %eax, %esi
1736; X86-BMI2-NEXT:  .LBB37_3:
1737; X86-BMI2-NEXT:    subl $8, %esp
1738; X86-BMI2-NEXT:    pushl %esi
1739; X86-BMI2-NEXT:    pushl %edi
1740; X86-BMI2-NEXT:    calll use64
1741; X86-BMI2-NEXT:    addl $16, %esp
1742; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
1743; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1744; X86-BMI2-NEXT:    movl %edi, %eax
1745; X86-BMI2-NEXT:    movl %esi, %edx
1746; X86-BMI2-NEXT:    addl $4, %esp
1747; X86-BMI2-NEXT:    popl %esi
1748; X86-BMI2-NEXT:    popl %edi
1749; X86-BMI2-NEXT:    retl
1750;
1751; X64-NOBMI2-LABEL: oneuse64:
1752; X64-NOBMI2:       # %bb.0:
1753; X64-NOBMI2-NEXT:    pushq %r14
1754; X64-NOBMI2-NEXT:    pushq %rbx
1755; X64-NOBMI2-NEXT:    pushq %rax
1756; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1757; X64-NOBMI2-NEXT:    movq %rdi, %r14
1758; X64-NOBMI2-NEXT:    movq $-1, %rbx
1759; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1760; X64-NOBMI2-NEXT:    shlq %cl, %rbx
1761; X64-NOBMI2-NEXT:    movq %rbx, %rdi
1762; X64-NOBMI2-NEXT:    callq use64
1763; X64-NOBMI2-NEXT:    andq %r14, %rbx
1764; X64-NOBMI2-NEXT:    movq %rbx, %rax
1765; X64-NOBMI2-NEXT:    addq $8, %rsp
1766; X64-NOBMI2-NEXT:    popq %rbx
1767; X64-NOBMI2-NEXT:    popq %r14
1768; X64-NOBMI2-NEXT:    retq
1769;
1770; X64-BMI2-LABEL: oneuse64:
1771; X64-BMI2:       # %bb.0:
1772; X64-BMI2-NEXT:    pushq %r14
1773; X64-BMI2-NEXT:    pushq %rbx
1774; X64-BMI2-NEXT:    pushq %rax
1775; X64-BMI2-NEXT:    movq %rdi, %r14
1776; X64-BMI2-NEXT:    movq $-1, %rax
1777; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rbx
1778; X64-BMI2-NEXT:    movq %rbx, %rdi
1779; X64-BMI2-NEXT:    callq use64
1780; X64-BMI2-NEXT:    andq %r14, %rbx
1781; X64-BMI2-NEXT:    movq %rbx, %rax
1782; X64-BMI2-NEXT:    addq $8, %rsp
1783; X64-BMI2-NEXT:    popq %rbx
1784; X64-BMI2-NEXT:    popq %r14
1785; X64-BMI2-NEXT:    retq
1786  %mask = shl i64 -1, %numlowbits
1787  call void @use64(i64 %mask)
1788  %masked = and i64 %mask, %val
1789  ret i64 %masked
1790}
1791