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
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:    shldl %cl, %edx, %edx
506; X86-NOBMI2-NEXT:    testb $32, %cl
507; X86-NOBMI2-NEXT:    je .LBB13_2
508; X86-NOBMI2-NEXT:  # %bb.1:
509; X86-NOBMI2-NEXT:    movl %eax, %edx
510; X86-NOBMI2-NEXT:    xorl %eax, %eax
511; X86-NOBMI2-NEXT:  .LBB13_2:
512; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
513; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
514; X86-NOBMI2-NEXT:    retl
515;
516; X86-BMI2-LABEL: clear_lowbits64_c0:
517; X86-BMI2:       # %bb.0:
518; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
519; X86-BMI2-NEXT:    movl $-1, %edx
520; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
521; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
522; X86-BMI2-NEXT:    testb $32, %cl
523; X86-BMI2-NEXT:    je .LBB13_2
524; X86-BMI2-NEXT:  # %bb.1:
525; X86-BMI2-NEXT:    movl %eax, %edx
526; X86-BMI2-NEXT:    xorl %eax, %eax
527; X86-BMI2-NEXT:  .LBB13_2:
528; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
529; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
530; X86-BMI2-NEXT:    retl
531;
532; X64-NOBMI2-LABEL: clear_lowbits64_c0:
533; X64-NOBMI2:       # %bb.0:
534; X64-NOBMI2-NEXT:    movq %rsi, %rcx
535; X64-NOBMI2-NEXT:    movq %rdi, %rax
536; X64-NOBMI2-NEXT:    shrq %cl, %rax
537; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
538; X64-NOBMI2-NEXT:    shlq %cl, %rax
539; X64-NOBMI2-NEXT:    retq
540;
541; X64-BMI2-LABEL: clear_lowbits64_c0:
542; X64-BMI2:       # %bb.0:
543; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
544; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
545; X64-BMI2-NEXT:    retq
546  %mask = shl i64 -1, %numlowbits
547  %masked = and i64 %mask, %val
548  ret i64 %masked
549}
550
551define i64 @clear_lowbits64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind {
552; X86-NOBMI2-LABEL: clear_lowbits64_c1_indexzext:
553; X86-NOBMI2:       # %bb.0:
554; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
555; X86-NOBMI2-NEXT:    movl $-1, %edx
556; X86-NOBMI2-NEXT:    movl $-1, %eax
557; X86-NOBMI2-NEXT:    shll %cl, %eax
558; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
559; X86-NOBMI2-NEXT:    testb $32, %cl
560; X86-NOBMI2-NEXT:    je .LBB14_2
561; X86-NOBMI2-NEXT:  # %bb.1:
562; X86-NOBMI2-NEXT:    movl %eax, %edx
563; X86-NOBMI2-NEXT:    xorl %eax, %eax
564; X86-NOBMI2-NEXT:  .LBB14_2:
565; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
566; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
567; X86-NOBMI2-NEXT:    retl
568;
569; X86-BMI2-LABEL: clear_lowbits64_c1_indexzext:
570; X86-BMI2:       # %bb.0:
571; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
572; X86-BMI2-NEXT:    movl $-1, %edx
573; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
574; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
575; X86-BMI2-NEXT:    testb $32, %cl
576; X86-BMI2-NEXT:    je .LBB14_2
577; X86-BMI2-NEXT:  # %bb.1:
578; X86-BMI2-NEXT:    movl %eax, %edx
579; X86-BMI2-NEXT:    xorl %eax, %eax
580; X86-BMI2-NEXT:  .LBB14_2:
581; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
582; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
583; X86-BMI2-NEXT:    retl
584;
585; X64-NOBMI2-LABEL: clear_lowbits64_c1_indexzext:
586; X64-NOBMI2:       # %bb.0:
587; X64-NOBMI2-NEXT:    movl %esi, %ecx
588; X64-NOBMI2-NEXT:    movq %rdi, %rax
589; X64-NOBMI2-NEXT:    shrq %cl, %rax
590; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
591; X64-NOBMI2-NEXT:    shlq %cl, %rax
592; X64-NOBMI2-NEXT:    retq
593;
594; X64-BMI2-LABEL: clear_lowbits64_c1_indexzext:
595; X64-BMI2:       # %bb.0:
596; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
597; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
598; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
599; X64-BMI2-NEXT:    retq
600  %sh_prom = zext i8 %numlowbits to i64
601  %mask = shl i64 -1, %sh_prom
602  %masked = and i64 %mask, %val
603  ret i64 %masked
604}
605
606define i64 @clear_lowbits64_c2_load(i64* %w, i64 %numlowbits) nounwind {
607; X86-NOBMI2-LABEL: clear_lowbits64_c2_load:
608; X86-NOBMI2:       # %bb.0:
609; X86-NOBMI2-NEXT:    pushl %esi
610; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
611; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
612; X86-NOBMI2-NEXT:    movl $-1, %edx
613; X86-NOBMI2-NEXT:    movl $-1, %eax
614; X86-NOBMI2-NEXT:    shll %cl, %eax
615; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
616; X86-NOBMI2-NEXT:    testb $32, %cl
617; X86-NOBMI2-NEXT:    je .LBB15_2
618; X86-NOBMI2-NEXT:  # %bb.1:
619; X86-NOBMI2-NEXT:    movl %eax, %edx
620; X86-NOBMI2-NEXT:    xorl %eax, %eax
621; X86-NOBMI2-NEXT:  .LBB15_2:
622; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
623; X86-NOBMI2-NEXT:    andl (%esi), %eax
624; X86-NOBMI2-NEXT:    popl %esi
625; X86-NOBMI2-NEXT:    retl
626;
627; X86-BMI2-LABEL: clear_lowbits64_c2_load:
628; X86-BMI2:       # %bb.0:
629; X86-BMI2-NEXT:    pushl %esi
630; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
631; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
632; X86-BMI2-NEXT:    movl $-1, %edx
633; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
634; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
635; X86-BMI2-NEXT:    testb $32, %cl
636; X86-BMI2-NEXT:    je .LBB15_2
637; X86-BMI2-NEXT:  # %bb.1:
638; X86-BMI2-NEXT:    movl %eax, %edx
639; X86-BMI2-NEXT:    xorl %eax, %eax
640; X86-BMI2-NEXT:  .LBB15_2:
641; X86-BMI2-NEXT:    andl 4(%esi), %edx
642; X86-BMI2-NEXT:    andl (%esi), %eax
643; X86-BMI2-NEXT:    popl %esi
644; X86-BMI2-NEXT:    retl
645;
646; X64-NOBMI2-LABEL: clear_lowbits64_c2_load:
647; X64-NOBMI2:       # %bb.0:
648; X64-NOBMI2-NEXT:    movq %rsi, %rcx
649; X64-NOBMI2-NEXT:    movq (%rdi), %rax
650; X64-NOBMI2-NEXT:    shrq %cl, %rax
651; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
652; X64-NOBMI2-NEXT:    shlq %cl, %rax
653; X64-NOBMI2-NEXT:    retq
654;
655; X64-BMI2-LABEL: clear_lowbits64_c2_load:
656; X64-BMI2:       # %bb.0:
657; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
658; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
659; X64-BMI2-NEXT:    retq
660  %val = load i64, i64* %w
661  %mask = shl i64 -1, %numlowbits
662  %masked = and i64 %mask, %val
663  ret i64 %masked
664}
665
666define i64 @clear_lowbits64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
667; X86-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext:
668; X86-NOBMI2:       # %bb.0:
669; X86-NOBMI2-NEXT:    pushl %esi
670; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
671; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
672; X86-NOBMI2-NEXT:    movl $-1, %edx
673; X86-NOBMI2-NEXT:    movl $-1, %eax
674; X86-NOBMI2-NEXT:    shll %cl, %eax
675; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
676; X86-NOBMI2-NEXT:    testb $32, %cl
677; X86-NOBMI2-NEXT:    je .LBB16_2
678; X86-NOBMI2-NEXT:  # %bb.1:
679; X86-NOBMI2-NEXT:    movl %eax, %edx
680; X86-NOBMI2-NEXT:    xorl %eax, %eax
681; X86-NOBMI2-NEXT:  .LBB16_2:
682; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
683; X86-NOBMI2-NEXT:    andl (%esi), %eax
684; X86-NOBMI2-NEXT:    popl %esi
685; X86-NOBMI2-NEXT:    retl
686;
687; X86-BMI2-LABEL: clear_lowbits64_c3_load_indexzext:
688; X86-BMI2:       # %bb.0:
689; X86-BMI2-NEXT:    pushl %esi
690; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
691; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
692; X86-BMI2-NEXT:    movl $-1, %edx
693; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
694; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
695; X86-BMI2-NEXT:    testb $32, %cl
696; X86-BMI2-NEXT:    je .LBB16_2
697; X86-BMI2-NEXT:  # %bb.1:
698; X86-BMI2-NEXT:    movl %eax, %edx
699; X86-BMI2-NEXT:    xorl %eax, %eax
700; X86-BMI2-NEXT:  .LBB16_2:
701; X86-BMI2-NEXT:    andl 4(%esi), %edx
702; X86-BMI2-NEXT:    andl (%esi), %eax
703; X86-BMI2-NEXT:    popl %esi
704; X86-BMI2-NEXT:    retl
705;
706; X64-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext:
707; X64-NOBMI2:       # %bb.0:
708; X64-NOBMI2-NEXT:    movl %esi, %ecx
709; X64-NOBMI2-NEXT:    movq (%rdi), %rax
710; X64-NOBMI2-NEXT:    shrq %cl, %rax
711; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
712; X64-NOBMI2-NEXT:    shlq %cl, %rax
713; X64-NOBMI2-NEXT:    retq
714;
715; X64-BMI2-LABEL: clear_lowbits64_c3_load_indexzext:
716; X64-BMI2:       # %bb.0:
717; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
718; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
719; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
720; X64-BMI2-NEXT:    retq
721  %val = load i64, i64* %w
722  %sh_prom = zext i8 %numlowbits to i64
723  %mask = shl i64 -1, %sh_prom
724  %masked = and i64 %mask, %val
725  ret i64 %masked
726}
727
728define i64 @clear_lowbits64_c4_commutative(i64 %val, i64 %numlowbits) nounwind {
729; X86-NOBMI2-LABEL: clear_lowbits64_c4_commutative:
730; X86-NOBMI2:       # %bb.0:
731; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
732; X86-NOBMI2-NEXT:    movl $-1, %edx
733; X86-NOBMI2-NEXT:    movl $-1, %eax
734; X86-NOBMI2-NEXT:    shll %cl, %eax
735; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
736; X86-NOBMI2-NEXT:    testb $32, %cl
737; X86-NOBMI2-NEXT:    je .LBB17_2
738; X86-NOBMI2-NEXT:  # %bb.1:
739; X86-NOBMI2-NEXT:    movl %eax, %edx
740; X86-NOBMI2-NEXT:    xorl %eax, %eax
741; X86-NOBMI2-NEXT:  .LBB17_2:
742; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
743; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
744; X86-NOBMI2-NEXT:    retl
745;
746; X86-BMI2-LABEL: clear_lowbits64_c4_commutative:
747; X86-BMI2:       # %bb.0:
748; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
749; X86-BMI2-NEXT:    movl $-1, %edx
750; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
751; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
752; X86-BMI2-NEXT:    testb $32, %cl
753; X86-BMI2-NEXT:    je .LBB17_2
754; X86-BMI2-NEXT:  # %bb.1:
755; X86-BMI2-NEXT:    movl %eax, %edx
756; X86-BMI2-NEXT:    xorl %eax, %eax
757; X86-BMI2-NEXT:  .LBB17_2:
758; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
759; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
760; X86-BMI2-NEXT:    retl
761;
762; X64-NOBMI2-LABEL: clear_lowbits64_c4_commutative:
763; X64-NOBMI2:       # %bb.0:
764; X64-NOBMI2-NEXT:    movq %rsi, %rcx
765; X64-NOBMI2-NEXT:    movq %rdi, %rax
766; X64-NOBMI2-NEXT:    shrq %cl, %rax
767; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
768; X64-NOBMI2-NEXT:    shlq %cl, %rax
769; X64-NOBMI2-NEXT:    retq
770;
771; X64-BMI2-LABEL: clear_lowbits64_c4_commutative:
772; X64-BMI2:       # %bb.0:
773; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
774; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
775; X64-BMI2-NEXT:    retq
776  %mask = shl i64 -1, %numlowbits
777  %masked = and i64 %val, %mask ; swapped order
778  ret i64 %masked
779}
780
781; ---------------------------------------------------------------------------- ;
782; Pattern ic.
783; ---------------------------------------------------------------------------- ;
784
785; 8-bit
786
787define i8 @clear_lowbits8_ic0(i8 %val, i8 %numlowbits) nounwind {
788; X86-LABEL: clear_lowbits8_ic0:
789; X86:       # %bb.0:
790; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
791; X86-NEXT:    movb $8, %cl
792; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
793; X86-NEXT:    shrb %cl, %al
794; X86-NEXT:    shlb %cl, %al
795; X86-NEXT:    retl
796;
797; X64-LABEL: clear_lowbits8_ic0:
798; X64:       # %bb.0:
799; X64-NEXT:    movl %edi, %eax
800; X64-NEXT:    movb $8, %cl
801; X64-NEXT:    subb %sil, %cl
802; X64-NEXT:    shrb %cl, %al
803; X64-NEXT:    shlb %cl, %al
804; X64-NEXT:    # kill: def $al killed $al killed $eax
805; X64-NEXT:    retq
806  %numhighbits = sub i8 8, %numlowbits
807  %mask = shl i8 -1, %numhighbits
808  %masked = and i8 %mask, %val
809  ret i8 %masked
810}
811
812define i8 @clear_lowbits8_ic2_load(i8* %w, i8 %numlowbits) nounwind {
813; X86-LABEL: clear_lowbits8_ic2_load:
814; X86:       # %bb.0:
815; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
816; X86-NEXT:    movb (%eax), %al
817; X86-NEXT:    movb $8, %cl
818; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
819; X86-NEXT:    shrb %cl, %al
820; X86-NEXT:    shlb %cl, %al
821; X86-NEXT:    retl
822;
823; X64-LABEL: clear_lowbits8_ic2_load:
824; X64:       # %bb.0:
825; X64-NEXT:    movb (%rdi), %al
826; X64-NEXT:    movb $8, %cl
827; X64-NEXT:    subb %sil, %cl
828; X64-NEXT:    shrb %cl, %al
829; X64-NEXT:    shlb %cl, %al
830; X64-NEXT:    retq
831  %val = load i8, i8* %w
832  %numhighbits = sub i8 8, %numlowbits
833  %mask = shl i8 -1, %numhighbits
834  %masked = and i8 %mask, %val
835  ret i8 %masked
836}
837
838define i8 @clear_lowbits8_ic4_commutative(i8 %val, i8 %numlowbits) nounwind {
839; X86-LABEL: clear_lowbits8_ic4_commutative:
840; X86:       # %bb.0:
841; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
842; X86-NEXT:    movb $8, %cl
843; X86-NEXT:    subb {{[0-9]+}}(%esp), %cl
844; X86-NEXT:    shrb %cl, %al
845; X86-NEXT:    shlb %cl, %al
846; X86-NEXT:    retl
847;
848; X64-LABEL: clear_lowbits8_ic4_commutative:
849; X64:       # %bb.0:
850; X64-NEXT:    movl %edi, %eax
851; X64-NEXT:    movb $8, %cl
852; X64-NEXT:    subb %sil, %cl
853; X64-NEXT:    shrb %cl, %al
854; X64-NEXT:    shlb %cl, %al
855; X64-NEXT:    # kill: def $al killed $al killed $eax
856; X64-NEXT:    retq
857  %numhighbits = sub i8 8, %numlowbits
858  %mask = shl i8 -1, %numhighbits
859  %masked = and i8 %val, %mask ; swapped order
860  ret i8 %masked
861}
862
863; 16-bit
864
865define i16 @clear_lowbits16_ic0(i16 %val, i16 %numlowbits) nounwind {
866; X86-NOBMI2-LABEL: clear_lowbits16_ic0:
867; X86-NOBMI2:       # %bb.0:
868; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
869; X86-NOBMI2-NEXT:    movb $16, %cl
870; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
871; X86-NOBMI2-NEXT:    shrl %cl, %eax
872; X86-NOBMI2-NEXT:    shll %cl, %eax
873; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
874; X86-NOBMI2-NEXT:    retl
875;
876; X86-BMI2-LABEL: clear_lowbits16_ic0:
877; X86-BMI2:       # %bb.0:
878; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
879; X86-BMI2-NEXT:    movb $16, %cl
880; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
881; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
882; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
883; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
884; X86-BMI2-NEXT:    retl
885;
886; X64-NOBMI2-LABEL: clear_lowbits16_ic0:
887; X64-NOBMI2:       # %bb.0:
888; X64-NOBMI2-NEXT:    movzwl %di, %eax
889; X64-NOBMI2-NEXT:    movb $16, %cl
890; X64-NOBMI2-NEXT:    subb %sil, %cl
891; X64-NOBMI2-NEXT:    shrl %cl, %eax
892; X64-NOBMI2-NEXT:    shll %cl, %eax
893; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
894; X64-NOBMI2-NEXT:    retq
895;
896; X64-BMI2-LABEL: clear_lowbits16_ic0:
897; X64-BMI2:       # %bb.0:
898; X64-BMI2-NEXT:    movzwl %di, %eax
899; X64-BMI2-NEXT:    movb $16, %cl
900; X64-BMI2-NEXT:    subb %sil, %cl
901; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
902; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
903; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
904; X64-BMI2-NEXT:    retq
905  %numhighbits = sub i16 16, %numlowbits
906  %mask = shl i16 -1, %numhighbits
907  %masked = and i16 %mask, %val
908  ret i16 %masked
909}
910
911define i16 @clear_lowbits16_ic1_indexzext(i16 %val, i8 %numlowbits) nounwind {
912; X86-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext:
913; X86-NOBMI2:       # %bb.0:
914; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
915; X86-NOBMI2-NEXT:    movb $16, %cl
916; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
917; X86-NOBMI2-NEXT:    shrl %cl, %eax
918; X86-NOBMI2-NEXT:    shll %cl, %eax
919; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
920; X86-NOBMI2-NEXT:    retl
921;
922; X86-BMI2-LABEL: clear_lowbits16_ic1_indexzext:
923; X86-BMI2:       # %bb.0:
924; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
925; X86-BMI2-NEXT:    movb $16, %cl
926; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
927; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
928; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
929; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
930; X86-BMI2-NEXT:    retl
931;
932; X64-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext:
933; X64-NOBMI2:       # %bb.0:
934; X64-NOBMI2-NEXT:    movzwl %di, %eax
935; X64-NOBMI2-NEXT:    movb $16, %cl
936; X64-NOBMI2-NEXT:    subb %sil, %cl
937; X64-NOBMI2-NEXT:    shrl %cl, %eax
938; X64-NOBMI2-NEXT:    shll %cl, %eax
939; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
940; X64-NOBMI2-NEXT:    retq
941;
942; X64-BMI2-LABEL: clear_lowbits16_ic1_indexzext:
943; X64-BMI2:       # %bb.0:
944; X64-BMI2-NEXT:    movzwl %di, %eax
945; X64-BMI2-NEXT:    movb $16, %cl
946; X64-BMI2-NEXT:    subb %sil, %cl
947; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
948; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
949; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
950; X64-BMI2-NEXT:    retq
951  %numhighbits = sub i8 16, %numlowbits
952  %sh_prom = zext i8 %numhighbits to i16
953  %mask = shl i16 -1, %sh_prom
954  %masked = and i16 %mask, %val
955  ret i16 %masked
956}
957
958define i16 @clear_lowbits16_ic2_load(i16* %w, i16 %numlowbits) nounwind {
959; X86-NOBMI2-LABEL: clear_lowbits16_ic2_load:
960; X86-NOBMI2:       # %bb.0:
961; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
962; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
963; X86-NOBMI2-NEXT:    movb $16, %cl
964; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
965; X86-NOBMI2-NEXT:    shrl %cl, %eax
966; X86-NOBMI2-NEXT:    shll %cl, %eax
967; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
968; X86-NOBMI2-NEXT:    retl
969;
970; X86-BMI2-LABEL: clear_lowbits16_ic2_load:
971; X86-BMI2:       # %bb.0:
972; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
973; X86-BMI2-NEXT:    movzwl (%eax), %eax
974; X86-BMI2-NEXT:    movb $16, %cl
975; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
976; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
977; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
978; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
979; X86-BMI2-NEXT:    retl
980;
981; X64-NOBMI2-LABEL: clear_lowbits16_ic2_load:
982; X64-NOBMI2:       # %bb.0:
983; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
984; X64-NOBMI2-NEXT:    movb $16, %cl
985; X64-NOBMI2-NEXT:    subb %sil, %cl
986; X64-NOBMI2-NEXT:    shrl %cl, %eax
987; X64-NOBMI2-NEXT:    shll %cl, %eax
988; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
989; X64-NOBMI2-NEXT:    retq
990;
991; X64-BMI2-LABEL: clear_lowbits16_ic2_load:
992; X64-BMI2:       # %bb.0:
993; X64-BMI2-NEXT:    movzwl (%rdi), %eax
994; X64-BMI2-NEXT:    movb $16, %cl
995; X64-BMI2-NEXT:    subb %sil, %cl
996; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
997; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
998; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
999; X64-BMI2-NEXT:    retq
1000  %val = load i16, i16* %w
1001  %numhighbits = sub i16 16, %numlowbits
1002  %mask = shl i16 -1, %numhighbits
1003  %masked = and i16 %mask, %val
1004  ret i16 %masked
1005}
1006
1007define i16 @clear_lowbits16_ic3_load_indexzext(i16* %w, i8 %numlowbits) nounwind {
1008; X86-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1009; X86-NOBMI2:       # %bb.0:
1010; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1011; X86-NOBMI2-NEXT:    movzwl (%eax), %eax
1012; X86-NOBMI2-NEXT:    movb $16, %cl
1013; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1014; X86-NOBMI2-NEXT:    shrl %cl, %eax
1015; X86-NOBMI2-NEXT:    shll %cl, %eax
1016; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1017; X86-NOBMI2-NEXT:    retl
1018;
1019; X86-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1020; X86-BMI2:       # %bb.0:
1021; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1022; X86-BMI2-NEXT:    movzwl (%eax), %eax
1023; X86-BMI2-NEXT:    movb $16, %cl
1024; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1025; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1026; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1027; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1028; X86-BMI2-NEXT:    retl
1029;
1030; X64-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1031; X64-NOBMI2:       # %bb.0:
1032; X64-NOBMI2-NEXT:    movzwl (%rdi), %eax
1033; X64-NOBMI2-NEXT:    movb $16, %cl
1034; X64-NOBMI2-NEXT:    subb %sil, %cl
1035; X64-NOBMI2-NEXT:    shrl %cl, %eax
1036; X64-NOBMI2-NEXT:    shll %cl, %eax
1037; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1038; X64-NOBMI2-NEXT:    retq
1039;
1040; X64-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext:
1041; X64-BMI2:       # %bb.0:
1042; X64-BMI2-NEXT:    movzwl (%rdi), %eax
1043; X64-BMI2-NEXT:    movb $16, %cl
1044; X64-BMI2-NEXT:    subb %sil, %cl
1045; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1046; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1047; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1048; X64-BMI2-NEXT:    retq
1049  %val = load i16, i16* %w
1050  %numhighbits = sub i8 16, %numlowbits
1051  %sh_prom = zext i8 %numhighbits to i16
1052  %mask = shl i16 -1, %sh_prom
1053  %masked = and i16 %mask, %val
1054  ret i16 %masked
1055}
1056
1057define i16 @clear_lowbits16_ic4_commutative(i16 %val, i16 %numlowbits) nounwind {
1058; X86-NOBMI2-LABEL: clear_lowbits16_ic4_commutative:
1059; X86-NOBMI2:       # %bb.0:
1060; X86-NOBMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1061; X86-NOBMI2-NEXT:    movb $16, %cl
1062; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1063; X86-NOBMI2-NEXT:    shrl %cl, %eax
1064; X86-NOBMI2-NEXT:    shll %cl, %eax
1065; X86-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1066; X86-NOBMI2-NEXT:    retl
1067;
1068; X86-BMI2-LABEL: clear_lowbits16_ic4_commutative:
1069; X86-BMI2:       # %bb.0:
1070; X86-BMI2-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1071; X86-BMI2-NEXT:    movb $16, %cl
1072; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1073; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1074; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1075; X86-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1076; X86-BMI2-NEXT:    retl
1077;
1078; X64-NOBMI2-LABEL: clear_lowbits16_ic4_commutative:
1079; X64-NOBMI2:       # %bb.0:
1080; X64-NOBMI2-NEXT:    movzwl %di, %eax
1081; X64-NOBMI2-NEXT:    movb $16, %cl
1082; X64-NOBMI2-NEXT:    subb %sil, %cl
1083; X64-NOBMI2-NEXT:    shrl %cl, %eax
1084; X64-NOBMI2-NEXT:    shll %cl, %eax
1085; X64-NOBMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1086; X64-NOBMI2-NEXT:    retq
1087;
1088; X64-BMI2-LABEL: clear_lowbits16_ic4_commutative:
1089; X64-BMI2:       # %bb.0:
1090; X64-BMI2-NEXT:    movzwl %di, %eax
1091; X64-BMI2-NEXT:    movb $16, %cl
1092; X64-BMI2-NEXT:    subb %sil, %cl
1093; X64-BMI2-NEXT:    shrxl %ecx, %eax, %eax
1094; X64-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1095; X64-BMI2-NEXT:    # kill: def $ax killed $ax killed $eax
1096; X64-BMI2-NEXT:    retq
1097  %numhighbits = sub i16 16, %numlowbits
1098  %mask = shl i16 -1, %numhighbits
1099  %masked = and i16 %val, %mask ; swapped order
1100  ret i16 %masked
1101}
1102
1103; 32-bit
1104
1105define i32 @clear_lowbits32_ic0(i32 %val, i32 %numlowbits) nounwind {
1106; X86-NOBMI2-LABEL: clear_lowbits32_ic0:
1107; X86-NOBMI2:       # %bb.0:
1108; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1109; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1110; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1111; X86-NOBMI2-NEXT:    shrl %cl, %eax
1112; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1113; X86-NOBMI2-NEXT:    shll %cl, %eax
1114; X86-NOBMI2-NEXT:    retl
1115;
1116; X86-BMI2-LABEL: clear_lowbits32_ic0:
1117; X86-BMI2:       # %bb.0:
1118; X86-BMI2-NEXT:    xorl %eax, %eax
1119; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1120; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1121; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1122; X86-BMI2-NEXT:    retl
1123;
1124; X64-NOBMI2-LABEL: clear_lowbits32_ic0:
1125; X64-NOBMI2:       # %bb.0:
1126; X64-NOBMI2-NEXT:    movl %esi, %ecx
1127; X64-NOBMI2-NEXT:    movl %edi, %eax
1128; X64-NOBMI2-NEXT:    negb %cl
1129; X64-NOBMI2-NEXT:    shrl %cl, %eax
1130; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1131; X64-NOBMI2-NEXT:    shll %cl, %eax
1132; X64-NOBMI2-NEXT:    retq
1133;
1134; X64-BMI2-LABEL: clear_lowbits32_ic0:
1135; X64-BMI2:       # %bb.0:
1136; X64-BMI2-NEXT:    negb %sil
1137; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1138; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1139; X64-BMI2-NEXT:    retq
1140  %numhighbits = sub i32 32, %numlowbits
1141  %mask = shl i32 -1, %numhighbits
1142  %masked = and i32 %mask, %val
1143  ret i32 %masked
1144}
1145
1146define i32 @clear_lowbits32_ic1_indexzext(i32 %val, i8 %numlowbits) nounwind {
1147; X86-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext:
1148; X86-NOBMI2:       # %bb.0:
1149; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1150; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1151; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1152; X86-NOBMI2-NEXT:    shrl %cl, %eax
1153; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1154; X86-NOBMI2-NEXT:    shll %cl, %eax
1155; X86-NOBMI2-NEXT:    retl
1156;
1157; X86-BMI2-LABEL: clear_lowbits32_ic1_indexzext:
1158; X86-BMI2:       # %bb.0:
1159; X86-BMI2-NEXT:    xorl %eax, %eax
1160; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1161; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1162; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1163; X86-BMI2-NEXT:    retl
1164;
1165; X64-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext:
1166; X64-NOBMI2:       # %bb.0:
1167; X64-NOBMI2-NEXT:    movl %esi, %ecx
1168; X64-NOBMI2-NEXT:    movl %edi, %eax
1169; X64-NOBMI2-NEXT:    negb %cl
1170; X64-NOBMI2-NEXT:    shrl %cl, %eax
1171; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1172; X64-NOBMI2-NEXT:    shll %cl, %eax
1173; X64-NOBMI2-NEXT:    retq
1174;
1175; X64-BMI2-LABEL: clear_lowbits32_ic1_indexzext:
1176; X64-BMI2:       # %bb.0:
1177; X64-BMI2-NEXT:    negb %sil
1178; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1179; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1180; X64-BMI2-NEXT:    retq
1181  %numhighbits = sub i8 32, %numlowbits
1182  %sh_prom = zext i8 %numhighbits to i32
1183  %mask = shl i32 -1, %sh_prom
1184  %masked = and i32 %mask, %val
1185  ret i32 %masked
1186}
1187
1188define i32 @clear_lowbits32_ic2_load(i32* %w, i32 %numlowbits) nounwind {
1189; X86-NOBMI2-LABEL: clear_lowbits32_ic2_load:
1190; X86-NOBMI2:       # %bb.0:
1191; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1192; X86-NOBMI2-NEXT:    movl (%eax), %eax
1193; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1194; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1195; X86-NOBMI2-NEXT:    shrl %cl, %eax
1196; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1197; X86-NOBMI2-NEXT:    shll %cl, %eax
1198; X86-NOBMI2-NEXT:    retl
1199;
1200; X86-BMI2-LABEL: clear_lowbits32_ic2_load:
1201; X86-BMI2:       # %bb.0:
1202; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1203; X86-BMI2-NEXT:    xorl %ecx, %ecx
1204; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1205; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
1206; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1207; X86-BMI2-NEXT:    retl
1208;
1209; X64-NOBMI2-LABEL: clear_lowbits32_ic2_load:
1210; X64-NOBMI2:       # %bb.0:
1211; X64-NOBMI2-NEXT:    movl %esi, %ecx
1212; X64-NOBMI2-NEXT:    movl (%rdi), %eax
1213; X64-NOBMI2-NEXT:    negb %cl
1214; X64-NOBMI2-NEXT:    shrl %cl, %eax
1215; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1216; X64-NOBMI2-NEXT:    shll %cl, %eax
1217; X64-NOBMI2-NEXT:    retq
1218;
1219; X64-BMI2-LABEL: clear_lowbits32_ic2_load:
1220; X64-BMI2:       # %bb.0:
1221; X64-BMI2-NEXT:    negb %sil
1222; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1223; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1224; X64-BMI2-NEXT:    retq
1225  %val = load i32, i32* %w
1226  %numhighbits = sub i32 32, %numlowbits
1227  %mask = shl i32 -1, %numhighbits
1228  %masked = and i32 %mask, %val
1229  ret i32 %masked
1230}
1231
1232define i32 @clear_lowbits32_ic3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
1233; X86-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1234; X86-NOBMI2:       # %bb.0:
1235; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1236; X86-NOBMI2-NEXT:    movl (%eax), %eax
1237; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1238; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1239; X86-NOBMI2-NEXT:    shrl %cl, %eax
1240; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1241; X86-NOBMI2-NEXT:    shll %cl, %eax
1242; X86-NOBMI2-NEXT:    retl
1243;
1244; X86-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1245; X86-BMI2:       # %bb.0:
1246; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1247; X86-BMI2-NEXT:    xorl %ecx, %ecx
1248; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1249; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %eax
1250; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
1251; X86-BMI2-NEXT:    retl
1252;
1253; X64-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1254; X64-NOBMI2:       # %bb.0:
1255; X64-NOBMI2-NEXT:    movl %esi, %ecx
1256; X64-NOBMI2-NEXT:    movl (%rdi), %eax
1257; X64-NOBMI2-NEXT:    negb %cl
1258; X64-NOBMI2-NEXT:    shrl %cl, %eax
1259; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1260; X64-NOBMI2-NEXT:    shll %cl, %eax
1261; X64-NOBMI2-NEXT:    retq
1262;
1263; X64-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext:
1264; X64-BMI2:       # %bb.0:
1265; X64-BMI2-NEXT:    negb %sil
1266; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1267; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1268; X64-BMI2-NEXT:    retq
1269  %val = load i32, i32* %w
1270  %numhighbits = sub i8 32, %numlowbits
1271  %sh_prom = zext i8 %numhighbits to i32
1272  %mask = shl i32 -1, %sh_prom
1273  %masked = and i32 %mask, %val
1274  ret i32 %masked
1275}
1276
1277define i32 @clear_lowbits32_ic4_commutative(i32 %val, i32 %numlowbits) nounwind {
1278; X86-NOBMI2-LABEL: clear_lowbits32_ic4_commutative:
1279; X86-NOBMI2:       # %bb.0:
1280; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1281; X86-NOBMI2-NEXT:    xorl %ecx, %ecx
1282; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1283; X86-NOBMI2-NEXT:    shrl %cl, %eax
1284; X86-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1285; X86-NOBMI2-NEXT:    shll %cl, %eax
1286; X86-NOBMI2-NEXT:    retl
1287;
1288; X86-BMI2-LABEL: clear_lowbits32_ic4_commutative:
1289; X86-BMI2:       # %bb.0:
1290; X86-BMI2-NEXT:    xorl %eax, %eax
1291; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
1292; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %ecx
1293; X86-BMI2-NEXT:    shlxl %eax, %ecx, %eax
1294; X86-BMI2-NEXT:    retl
1295;
1296; X64-NOBMI2-LABEL: clear_lowbits32_ic4_commutative:
1297; X64-NOBMI2:       # %bb.0:
1298; X64-NOBMI2-NEXT:    movl %esi, %ecx
1299; X64-NOBMI2-NEXT:    movl %edi, %eax
1300; X64-NOBMI2-NEXT:    negb %cl
1301; X64-NOBMI2-NEXT:    shrl %cl, %eax
1302; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1303; X64-NOBMI2-NEXT:    shll %cl, %eax
1304; X64-NOBMI2-NEXT:    retq
1305;
1306; X64-BMI2-LABEL: clear_lowbits32_ic4_commutative:
1307; X64-BMI2:       # %bb.0:
1308; X64-BMI2-NEXT:    negb %sil
1309; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
1310; X64-BMI2-NEXT:    shlxl %esi, %eax, %eax
1311; X64-BMI2-NEXT:    retq
1312  %numhighbits = sub i32 32, %numlowbits
1313  %mask = shl i32 -1, %numhighbits
1314  %masked = and i32 %val, %mask ; swapped order
1315  ret i32 %masked
1316}
1317
1318; 64-bit
1319
1320define i64 @clear_lowbits64_ic0(i64 %val, i64 %numlowbits) nounwind {
1321; X86-NOBMI2-LABEL: clear_lowbits64_ic0:
1322; X86-NOBMI2:       # %bb.0:
1323; X86-NOBMI2-NEXT:    movb $64, %cl
1324; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1325; X86-NOBMI2-NEXT:    movl $-1, %edx
1326; X86-NOBMI2-NEXT:    movl $-1, %eax
1327; X86-NOBMI2-NEXT:    shll %cl, %eax
1328; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
1329; X86-NOBMI2-NEXT:    testb $32, %cl
1330; X86-NOBMI2-NEXT:    je .LBB31_2
1331; X86-NOBMI2-NEXT:  # %bb.1:
1332; X86-NOBMI2-NEXT:    movl %eax, %edx
1333; X86-NOBMI2-NEXT:    xorl %eax, %eax
1334; X86-NOBMI2-NEXT:  .LBB31_2:
1335; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1336; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1337; X86-NOBMI2-NEXT:    retl
1338;
1339; X86-BMI2-LABEL: clear_lowbits64_ic0:
1340; X86-BMI2:       # %bb.0:
1341; X86-BMI2-NEXT:    movb $64, %cl
1342; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1343; X86-BMI2-NEXT:    movl $-1, %edx
1344; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1345; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
1346; X86-BMI2-NEXT:    testb $32, %cl
1347; X86-BMI2-NEXT:    je .LBB31_2
1348; X86-BMI2-NEXT:  # %bb.1:
1349; X86-BMI2-NEXT:    movl %eax, %edx
1350; X86-BMI2-NEXT:    xorl %eax, %eax
1351; X86-BMI2-NEXT:  .LBB31_2:
1352; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1353; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1354; X86-BMI2-NEXT:    retl
1355;
1356; X64-NOBMI2-LABEL: clear_lowbits64_ic0:
1357; X64-NOBMI2:       # %bb.0:
1358; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1359; X64-NOBMI2-NEXT:    movq %rdi, %rax
1360; X64-NOBMI2-NEXT:    negb %cl
1361; X64-NOBMI2-NEXT:    shrq %cl, %rax
1362; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1363; X64-NOBMI2-NEXT:    shlq %cl, %rax
1364; X64-NOBMI2-NEXT:    retq
1365;
1366; X64-BMI2-LABEL: clear_lowbits64_ic0:
1367; X64-BMI2:       # %bb.0:
1368; X64-BMI2-NEXT:    negb %sil
1369; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1370; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1371; X64-BMI2-NEXT:    retq
1372  %numhighbits = sub i64 64, %numlowbits
1373  %mask = shl i64 -1, %numhighbits
1374  %masked = and i64 %mask, %val
1375  ret i64 %masked
1376}
1377
1378define i64 @clear_lowbits64_ic1_indexzext(i64 %val, i8 %numlowbits) nounwind {
1379; X86-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext:
1380; X86-NOBMI2:       # %bb.0:
1381; X86-NOBMI2-NEXT:    movb $64, %cl
1382; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1383; X86-NOBMI2-NEXT:    movl $-1, %edx
1384; X86-NOBMI2-NEXT:    movl $-1, %eax
1385; X86-NOBMI2-NEXT:    shll %cl, %eax
1386; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
1387; X86-NOBMI2-NEXT:    testb $32, %cl
1388; X86-NOBMI2-NEXT:    je .LBB32_2
1389; X86-NOBMI2-NEXT:  # %bb.1:
1390; X86-NOBMI2-NEXT:    movl %eax, %edx
1391; X86-NOBMI2-NEXT:    xorl %eax, %eax
1392; X86-NOBMI2-NEXT:  .LBB32_2:
1393; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1394; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1395; X86-NOBMI2-NEXT:    retl
1396;
1397; X86-BMI2-LABEL: clear_lowbits64_ic1_indexzext:
1398; X86-BMI2:       # %bb.0:
1399; X86-BMI2-NEXT:    movb $64, %cl
1400; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1401; X86-BMI2-NEXT:    movl $-1, %edx
1402; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1403; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
1404; X86-BMI2-NEXT:    testb $32, %cl
1405; X86-BMI2-NEXT:    je .LBB32_2
1406; X86-BMI2-NEXT:  # %bb.1:
1407; X86-BMI2-NEXT:    movl %eax, %edx
1408; X86-BMI2-NEXT:    xorl %eax, %eax
1409; X86-BMI2-NEXT:  .LBB32_2:
1410; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1411; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1412; X86-BMI2-NEXT:    retl
1413;
1414; X64-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext:
1415; X64-NOBMI2:       # %bb.0:
1416; X64-NOBMI2-NEXT:    movl %esi, %ecx
1417; X64-NOBMI2-NEXT:    movq %rdi, %rax
1418; X64-NOBMI2-NEXT:    negb %cl
1419; X64-NOBMI2-NEXT:    shrq %cl, %rax
1420; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1421; X64-NOBMI2-NEXT:    shlq %cl, %rax
1422; X64-NOBMI2-NEXT:    retq
1423;
1424; X64-BMI2-LABEL: clear_lowbits64_ic1_indexzext:
1425; X64-BMI2:       # %bb.0:
1426; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1427; X64-BMI2-NEXT:    negb %sil
1428; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1429; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1430; X64-BMI2-NEXT:    retq
1431  %numhighbits = sub i8 64, %numlowbits
1432  %sh_prom = zext i8 %numhighbits to i64
1433  %mask = shl i64 -1, %sh_prom
1434  %masked = and i64 %mask, %val
1435  ret i64 %masked
1436}
1437
1438define i64 @clear_lowbits64_ic2_load(i64* %w, i64 %numlowbits) nounwind {
1439; X86-NOBMI2-LABEL: clear_lowbits64_ic2_load:
1440; X86-NOBMI2:       # %bb.0:
1441; X86-NOBMI2-NEXT:    pushl %esi
1442; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1443; X86-NOBMI2-NEXT:    movb $64, %cl
1444; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1445; X86-NOBMI2-NEXT:    movl $-1, %edx
1446; X86-NOBMI2-NEXT:    movl $-1, %eax
1447; X86-NOBMI2-NEXT:    shll %cl, %eax
1448; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
1449; X86-NOBMI2-NEXT:    testb $32, %cl
1450; X86-NOBMI2-NEXT:    je .LBB33_2
1451; X86-NOBMI2-NEXT:  # %bb.1:
1452; X86-NOBMI2-NEXT:    movl %eax, %edx
1453; X86-NOBMI2-NEXT:    xorl %eax, %eax
1454; X86-NOBMI2-NEXT:  .LBB33_2:
1455; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
1456; X86-NOBMI2-NEXT:    andl (%esi), %eax
1457; X86-NOBMI2-NEXT:    popl %esi
1458; X86-NOBMI2-NEXT:    retl
1459;
1460; X86-BMI2-LABEL: clear_lowbits64_ic2_load:
1461; X86-BMI2:       # %bb.0:
1462; X86-BMI2-NEXT:    pushl %esi
1463; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1464; X86-BMI2-NEXT:    movb $64, %cl
1465; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1466; X86-BMI2-NEXT:    movl $-1, %edx
1467; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1468; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
1469; X86-BMI2-NEXT:    testb $32, %cl
1470; X86-BMI2-NEXT:    je .LBB33_2
1471; X86-BMI2-NEXT:  # %bb.1:
1472; X86-BMI2-NEXT:    movl %eax, %edx
1473; X86-BMI2-NEXT:    xorl %eax, %eax
1474; X86-BMI2-NEXT:  .LBB33_2:
1475; X86-BMI2-NEXT:    andl 4(%esi), %edx
1476; X86-BMI2-NEXT:    andl (%esi), %eax
1477; X86-BMI2-NEXT:    popl %esi
1478; X86-BMI2-NEXT:    retl
1479;
1480; X64-NOBMI2-LABEL: clear_lowbits64_ic2_load:
1481; X64-NOBMI2:       # %bb.0:
1482; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1483; X64-NOBMI2-NEXT:    movq (%rdi), %rax
1484; X64-NOBMI2-NEXT:    negb %cl
1485; X64-NOBMI2-NEXT:    shrq %cl, %rax
1486; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1487; X64-NOBMI2-NEXT:    shlq %cl, %rax
1488; X64-NOBMI2-NEXT:    retq
1489;
1490; X64-BMI2-LABEL: clear_lowbits64_ic2_load:
1491; X64-BMI2:       # %bb.0:
1492; X64-BMI2-NEXT:    negb %sil
1493; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1494; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1495; X64-BMI2-NEXT:    retq
1496  %val = load i64, i64* %w
1497  %numhighbits = sub i64 64, %numlowbits
1498  %mask = shl i64 -1, %numhighbits
1499  %masked = and i64 %mask, %val
1500  ret i64 %masked
1501}
1502
1503define i64 @clear_lowbits64_ic3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
1504; X86-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1505; X86-NOBMI2:       # %bb.0:
1506; X86-NOBMI2-NEXT:    pushl %esi
1507; X86-NOBMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1508; X86-NOBMI2-NEXT:    movb $64, %cl
1509; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1510; X86-NOBMI2-NEXT:    movl $-1, %edx
1511; X86-NOBMI2-NEXT:    movl $-1, %eax
1512; X86-NOBMI2-NEXT:    shll %cl, %eax
1513; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
1514; X86-NOBMI2-NEXT:    testb $32, %cl
1515; X86-NOBMI2-NEXT:    je .LBB34_2
1516; X86-NOBMI2-NEXT:  # %bb.1:
1517; X86-NOBMI2-NEXT:    movl %eax, %edx
1518; X86-NOBMI2-NEXT:    xorl %eax, %eax
1519; X86-NOBMI2-NEXT:  .LBB34_2:
1520; X86-NOBMI2-NEXT:    andl 4(%esi), %edx
1521; X86-NOBMI2-NEXT:    andl (%esi), %eax
1522; X86-NOBMI2-NEXT:    popl %esi
1523; X86-NOBMI2-NEXT:    retl
1524;
1525; X86-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1526; X86-BMI2:       # %bb.0:
1527; X86-BMI2-NEXT:    pushl %esi
1528; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1529; X86-BMI2-NEXT:    movb $64, %cl
1530; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1531; X86-BMI2-NEXT:    movl $-1, %edx
1532; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1533; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
1534; X86-BMI2-NEXT:    testb $32, %cl
1535; X86-BMI2-NEXT:    je .LBB34_2
1536; X86-BMI2-NEXT:  # %bb.1:
1537; X86-BMI2-NEXT:    movl %eax, %edx
1538; X86-BMI2-NEXT:    xorl %eax, %eax
1539; X86-BMI2-NEXT:  .LBB34_2:
1540; X86-BMI2-NEXT:    andl 4(%esi), %edx
1541; X86-BMI2-NEXT:    andl (%esi), %eax
1542; X86-BMI2-NEXT:    popl %esi
1543; X86-BMI2-NEXT:    retl
1544;
1545; X64-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1546; X64-NOBMI2:       # %bb.0:
1547; X64-NOBMI2-NEXT:    movl %esi, %ecx
1548; X64-NOBMI2-NEXT:    movq (%rdi), %rax
1549; X64-NOBMI2-NEXT:    negb %cl
1550; X64-NOBMI2-NEXT:    shrq %cl, %rax
1551; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1552; X64-NOBMI2-NEXT:    shlq %cl, %rax
1553; X64-NOBMI2-NEXT:    retq
1554;
1555; X64-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext:
1556; X64-BMI2:       # %bb.0:
1557; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1558; X64-BMI2-NEXT:    negb %sil
1559; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1560; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1561; X64-BMI2-NEXT:    retq
1562  %val = load i64, i64* %w
1563  %numhighbits = sub i8 64, %numlowbits
1564  %sh_prom = zext i8 %numhighbits to i64
1565  %mask = shl i64 -1, %sh_prom
1566  %masked = and i64 %mask, %val
1567  ret i64 %masked
1568}
1569
1570define i64 @clear_lowbits64_ic4_commutative(i64 %val, i64 %numlowbits) nounwind {
1571; X86-NOBMI2-LABEL: clear_lowbits64_ic4_commutative:
1572; X86-NOBMI2:       # %bb.0:
1573; X86-NOBMI2-NEXT:    movb $64, %cl
1574; X86-NOBMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1575; X86-NOBMI2-NEXT:    movl $-1, %edx
1576; X86-NOBMI2-NEXT:    movl $-1, %eax
1577; X86-NOBMI2-NEXT:    shll %cl, %eax
1578; X86-NOBMI2-NEXT:    shldl %cl, %edx, %edx
1579; X86-NOBMI2-NEXT:    testb $32, %cl
1580; X86-NOBMI2-NEXT:    je .LBB35_2
1581; X86-NOBMI2-NEXT:  # %bb.1:
1582; X86-NOBMI2-NEXT:    movl %eax, %edx
1583; X86-NOBMI2-NEXT:    xorl %eax, %eax
1584; X86-NOBMI2-NEXT:  .LBB35_2:
1585; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1586; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1587; X86-NOBMI2-NEXT:    retl
1588;
1589; X86-BMI2-LABEL: clear_lowbits64_ic4_commutative:
1590; X86-BMI2:       # %bb.0:
1591; X86-BMI2-NEXT:    movb $64, %cl
1592; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
1593; X86-BMI2-NEXT:    movl $-1, %edx
1594; X86-BMI2-NEXT:    shlxl %ecx, %edx, %eax
1595; X86-BMI2-NEXT:    shldl %cl, %edx, %edx
1596; X86-BMI2-NEXT:    testb $32, %cl
1597; X86-BMI2-NEXT:    je .LBB35_2
1598; X86-BMI2-NEXT:  # %bb.1:
1599; X86-BMI2-NEXT:    movl %eax, %edx
1600; X86-BMI2-NEXT:    xorl %eax, %eax
1601; X86-BMI2-NEXT:  .LBB35_2:
1602; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
1603; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
1604; X86-BMI2-NEXT:    retl
1605;
1606; X64-NOBMI2-LABEL: clear_lowbits64_ic4_commutative:
1607; X64-NOBMI2:       # %bb.0:
1608; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1609; X64-NOBMI2-NEXT:    movq %rdi, %rax
1610; X64-NOBMI2-NEXT:    negb %cl
1611; X64-NOBMI2-NEXT:    shrq %cl, %rax
1612; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1613; X64-NOBMI2-NEXT:    shlq %cl, %rax
1614; X64-NOBMI2-NEXT:    retq
1615;
1616; X64-BMI2-LABEL: clear_lowbits64_ic4_commutative:
1617; X64-BMI2:       # %bb.0:
1618; X64-BMI2-NEXT:    negb %sil
1619; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1620; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rax
1621; X64-BMI2-NEXT:    retq
1622  %numhighbits = sub i64 64, %numlowbits
1623  %mask = shl i64 -1, %numhighbits
1624  %masked = and i64 %val, %mask ; swapped order
1625  ret i64 %masked
1626}
1627
1628; ---------------------------------------------------------------------------- ;
1629; Multi-use tests
1630; ---------------------------------------------------------------------------- ;
1631
1632declare void @use32(i32)
1633declare void @use64(i64)
1634
1635define i32 @oneuse32(i32 %val, i32 %numlowbits) nounwind {
1636; X86-NOBMI2-LABEL: oneuse32:
1637; X86-NOBMI2:       # %bb.0:
1638; X86-NOBMI2-NEXT:    pushl %esi
1639; X86-NOBMI2-NEXT:    subl $8, %esp
1640; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1641; X86-NOBMI2-NEXT:    movl $-1, %esi
1642; X86-NOBMI2-NEXT:    shll %cl, %esi
1643; X86-NOBMI2-NEXT:    movl %esi, (%esp)
1644; X86-NOBMI2-NEXT:    calll use32
1645; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1646; X86-NOBMI2-NEXT:    movl %esi, %eax
1647; X86-NOBMI2-NEXT:    addl $8, %esp
1648; X86-NOBMI2-NEXT:    popl %esi
1649; X86-NOBMI2-NEXT:    retl
1650;
1651; X86-BMI2-LABEL: oneuse32:
1652; X86-BMI2:       # %bb.0:
1653; X86-BMI2-NEXT:    pushl %esi
1654; X86-BMI2-NEXT:    subl $8, %esp
1655; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1656; X86-BMI2-NEXT:    movl $-1, %ecx
1657; X86-BMI2-NEXT:    shlxl %eax, %ecx, %esi
1658; X86-BMI2-NEXT:    movl %esi, (%esp)
1659; X86-BMI2-NEXT:    calll use32
1660; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1661; X86-BMI2-NEXT:    movl %esi, %eax
1662; X86-BMI2-NEXT:    addl $8, %esp
1663; X86-BMI2-NEXT:    popl %esi
1664; X86-BMI2-NEXT:    retl
1665;
1666; X64-NOBMI2-LABEL: oneuse32:
1667; X64-NOBMI2:       # %bb.0:
1668; X64-NOBMI2-NEXT:    pushq %rbp
1669; X64-NOBMI2-NEXT:    pushq %rbx
1670; X64-NOBMI2-NEXT:    pushq %rax
1671; X64-NOBMI2-NEXT:    movl %esi, %ecx
1672; X64-NOBMI2-NEXT:    movl %edi, %ebx
1673; X64-NOBMI2-NEXT:    movl $-1, %ebp
1674; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $ecx
1675; X64-NOBMI2-NEXT:    shll %cl, %ebp
1676; X64-NOBMI2-NEXT:    movl %ebp, %edi
1677; X64-NOBMI2-NEXT:    callq use32
1678; X64-NOBMI2-NEXT:    andl %ebx, %ebp
1679; X64-NOBMI2-NEXT:    movl %ebp, %eax
1680; X64-NOBMI2-NEXT:    addq $8, %rsp
1681; X64-NOBMI2-NEXT:    popq %rbx
1682; X64-NOBMI2-NEXT:    popq %rbp
1683; X64-NOBMI2-NEXT:    retq
1684;
1685; X64-BMI2-LABEL: oneuse32:
1686; X64-BMI2:       # %bb.0:
1687; X64-BMI2-NEXT:    pushq %rbp
1688; X64-BMI2-NEXT:    pushq %rbx
1689; X64-BMI2-NEXT:    pushq %rax
1690; X64-BMI2-NEXT:    movl %edi, %ebx
1691; X64-BMI2-NEXT:    movl $-1, %eax
1692; X64-BMI2-NEXT:    shlxl %esi, %eax, %ebp
1693; X64-BMI2-NEXT:    movl %ebp, %edi
1694; X64-BMI2-NEXT:    callq use32
1695; X64-BMI2-NEXT:    andl %ebx, %ebp
1696; X64-BMI2-NEXT:    movl %ebp, %eax
1697; X64-BMI2-NEXT:    addq $8, %rsp
1698; X64-BMI2-NEXT:    popq %rbx
1699; X64-BMI2-NEXT:    popq %rbp
1700; X64-BMI2-NEXT:    retq
1701  %mask = shl i32 -1, %numlowbits
1702  call void @use32(i32 %mask)
1703  %masked = and i32 %mask, %val
1704  ret i32 %masked
1705}
1706
1707define i64 @oneuse64(i64 %val, i64 %numlowbits) nounwind {
1708; X86-NOBMI2-LABEL: oneuse64:
1709; X86-NOBMI2:       # %bb.0:
1710; X86-NOBMI2-NEXT:    pushl %edi
1711; X86-NOBMI2-NEXT:    pushl %esi
1712; X86-NOBMI2-NEXT:    pushl %eax
1713; X86-NOBMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1714; X86-NOBMI2-NEXT:    movl $-1, %esi
1715; X86-NOBMI2-NEXT:    movl $-1, %edi
1716; X86-NOBMI2-NEXT:    shll %cl, %edi
1717; X86-NOBMI2-NEXT:    shldl %cl, %esi, %esi
1718; X86-NOBMI2-NEXT:    testb $32, %cl
1719; X86-NOBMI2-NEXT:    je .LBB37_2
1720; X86-NOBMI2-NEXT:  # %bb.1:
1721; X86-NOBMI2-NEXT:    movl %edi, %esi
1722; X86-NOBMI2-NEXT:    xorl %edi, %edi
1723; X86-NOBMI2-NEXT:  .LBB37_2:
1724; X86-NOBMI2-NEXT:    subl $8, %esp
1725; X86-NOBMI2-NEXT:    pushl %esi
1726; X86-NOBMI2-NEXT:    pushl %edi
1727; X86-NOBMI2-NEXT:    calll use64
1728; X86-NOBMI2-NEXT:    addl $16, %esp
1729; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1730; X86-NOBMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
1731; X86-NOBMI2-NEXT:    movl %edi, %eax
1732; X86-NOBMI2-NEXT:    movl %esi, %edx
1733; X86-NOBMI2-NEXT:    addl $4, %esp
1734; X86-NOBMI2-NEXT:    popl %esi
1735; X86-NOBMI2-NEXT:    popl %edi
1736; X86-NOBMI2-NEXT:    retl
1737;
1738; X86-BMI2-LABEL: oneuse64:
1739; X86-BMI2:       # %bb.0:
1740; X86-BMI2-NEXT:    pushl %edi
1741; X86-BMI2-NEXT:    pushl %esi
1742; X86-BMI2-NEXT:    pushl %eax
1743; X86-BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1744; X86-BMI2-NEXT:    movl $-1, %esi
1745; X86-BMI2-NEXT:    shlxl %ecx, %esi, %edi
1746; X86-BMI2-NEXT:    shldl %cl, %esi, %esi
1747; X86-BMI2-NEXT:    testb $32, %cl
1748; X86-BMI2-NEXT:    je .LBB37_2
1749; X86-BMI2-NEXT:  # %bb.1:
1750; X86-BMI2-NEXT:    movl %edi, %esi
1751; X86-BMI2-NEXT:    xorl %edi, %edi
1752; X86-BMI2-NEXT:  .LBB37_2:
1753; X86-BMI2-NEXT:    subl $8, %esp
1754; X86-BMI2-NEXT:    pushl %esi
1755; X86-BMI2-NEXT:    pushl %edi
1756; X86-BMI2-NEXT:    calll use64
1757; X86-BMI2-NEXT:    addl $16, %esp
1758; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
1759; X86-BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
1760; X86-BMI2-NEXT:    movl %edi, %eax
1761; X86-BMI2-NEXT:    movl %esi, %edx
1762; X86-BMI2-NEXT:    addl $4, %esp
1763; X86-BMI2-NEXT:    popl %esi
1764; X86-BMI2-NEXT:    popl %edi
1765; X86-BMI2-NEXT:    retl
1766;
1767; X64-NOBMI2-LABEL: oneuse64:
1768; X64-NOBMI2:       # %bb.0:
1769; X64-NOBMI2-NEXT:    pushq %r14
1770; X64-NOBMI2-NEXT:    pushq %rbx
1771; X64-NOBMI2-NEXT:    pushq %rax
1772; X64-NOBMI2-NEXT:    movq %rsi, %rcx
1773; X64-NOBMI2-NEXT:    movq %rdi, %r14
1774; X64-NOBMI2-NEXT:    movq $-1, %rbx
1775; X64-NOBMI2-NEXT:    # kill: def $cl killed $cl killed $rcx
1776; X64-NOBMI2-NEXT:    shlq %cl, %rbx
1777; X64-NOBMI2-NEXT:    movq %rbx, %rdi
1778; X64-NOBMI2-NEXT:    callq use64
1779; X64-NOBMI2-NEXT:    andq %r14, %rbx
1780; X64-NOBMI2-NEXT:    movq %rbx, %rax
1781; X64-NOBMI2-NEXT:    addq $8, %rsp
1782; X64-NOBMI2-NEXT:    popq %rbx
1783; X64-NOBMI2-NEXT:    popq %r14
1784; X64-NOBMI2-NEXT:    retq
1785;
1786; X64-BMI2-LABEL: oneuse64:
1787; X64-BMI2:       # %bb.0:
1788; X64-BMI2-NEXT:    pushq %r14
1789; X64-BMI2-NEXT:    pushq %rbx
1790; X64-BMI2-NEXT:    pushq %rax
1791; X64-BMI2-NEXT:    movq %rdi, %r14
1792; X64-BMI2-NEXT:    movq $-1, %rax
1793; X64-BMI2-NEXT:    shlxq %rsi, %rax, %rbx
1794; X64-BMI2-NEXT:    movq %rbx, %rdi
1795; X64-BMI2-NEXT:    callq use64
1796; X64-BMI2-NEXT:    andq %r14, %rbx
1797; X64-BMI2-NEXT:    movq %rbx, %rax
1798; X64-BMI2-NEXT:    addq $8, %rsp
1799; X64-BMI2-NEXT:    popq %rbx
1800; X64-BMI2-NEXT:    popq %r14
1801; X64-BMI2-NEXT:    retq
1802  %mask = shl i64 -1, %numlowbits
1803  call void @use64(i64 %mask)
1804  %masked = and i64 %mask, %val
1805  ret i64 %masked
1806}
1807