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,NOBMI,X86-NOBMI
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1NOTBM,X86-BMI1NOTBM
4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1TBM,X86-BMI1TBM
5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1BMI2,X86-BMI1BMI2,BMI1TBM,X86-BMI1TBM,BMI1TBMBMI2,X86-BMI1TBMBMI2
6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1BMI2,X86-BMI1BMI2,BMI1NOTBMBMI2,X86-BMI1NOTBMBMI2
7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI,X64-NOBMI
8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1NOTBM,X64-BMI1NOTBM
9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1TBM,X64-BMI1TBM
10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1BMI2,X64-BMI1BMI2,BMI1TBM,X64-BMI1TBM,BMI1TBMBMI2,X64-BMI1TBMBMI2
11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1BMI2,X64-BMI1BMI2,BMI1NOTBMBMI2,X64-BMI1NOTBMBMI2
12
13; *Please* keep in sync with test/CodeGen/AArch64/extract-lowbits.ll
14
15; https://bugs.llvm.org/show_bug.cgi?id=36419
16; https://bugs.llvm.org/show_bug.cgi?id=37603
17; https://bugs.llvm.org/show_bug.cgi?id=37610
18
19; Patterns:
20;   a) x &  (1 << nbits) - 1
21;   b) x & ~(-1 << nbits)
22;   c) x &  (-1 >> (32 - y))
23;   d) x << (32 - y) >> (32 - y)
24; are equivalent.
25
26; ---------------------------------------------------------------------------- ;
27; Pattern a. 32-bit
28; ---------------------------------------------------------------------------- ;
29
30define i32 @bzhi32_a0(i32 %val, i32 %numlowbits) nounwind {
31; X86-NOBMI-LABEL: bzhi32_a0:
32; X86-NOBMI:       # %bb.0:
33; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
34; X86-NOBMI-NEXT:    movl $1, %eax
35; X86-NOBMI-NEXT:    shll %cl, %eax
36; X86-NOBMI-NEXT:    decl %eax
37; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
38; X86-NOBMI-NEXT:    retl
39;
40; X86-BMI1NOTBM-LABEL: bzhi32_a0:
41; X86-BMI1NOTBM:       # %bb.0:
42; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
43; X86-BMI1NOTBM-NEXT:    shll $8, %eax
44; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
45; X86-BMI1NOTBM-NEXT:    retl
46;
47; X86-BMI1BMI2-LABEL: bzhi32_a0:
48; X86-BMI1BMI2:       # %bb.0:
49; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
50; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
51; X86-BMI1BMI2-NEXT:    retl
52;
53; X64-NOBMI-LABEL: bzhi32_a0:
54; X64-NOBMI:       # %bb.0:
55; X64-NOBMI-NEXT:    movl %esi, %ecx
56; X64-NOBMI-NEXT:    movl $1, %eax
57; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
58; X64-NOBMI-NEXT:    shll %cl, %eax
59; X64-NOBMI-NEXT:    decl %eax
60; X64-NOBMI-NEXT:    andl %edi, %eax
61; X64-NOBMI-NEXT:    retq
62;
63; X64-BMI1NOTBM-LABEL: bzhi32_a0:
64; X64-BMI1NOTBM:       # %bb.0:
65; X64-BMI1NOTBM-NEXT:    shll $8, %esi
66; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
67; X64-BMI1NOTBM-NEXT:    retq
68;
69; X64-BMI1BMI2-LABEL: bzhi32_a0:
70; X64-BMI1BMI2:       # %bb.0:
71; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
72; X64-BMI1BMI2-NEXT:    retq
73  %onebit = shl i32 1, %numlowbits
74  %mask = add nsw i32 %onebit, -1
75  %masked = and i32 %mask, %val
76  ret i32 %masked
77}
78
79define i32 @bzhi32_a1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {
80; X86-NOBMI-LABEL: bzhi32_a1_indexzext:
81; X86-NOBMI:       # %bb.0:
82; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
83; X86-NOBMI-NEXT:    movl $1, %eax
84; X86-NOBMI-NEXT:    shll %cl, %eax
85; X86-NOBMI-NEXT:    decl %eax
86; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
87; X86-NOBMI-NEXT:    retl
88;
89; X86-BMI1NOTBM-LABEL: bzhi32_a1_indexzext:
90; X86-BMI1NOTBM:       # %bb.0:
91; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
92; X86-BMI1NOTBM-NEXT:    shll $8, %eax
93; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
94; X86-BMI1NOTBM-NEXT:    retl
95;
96; X86-BMI1BMI2-LABEL: bzhi32_a1_indexzext:
97; X86-BMI1BMI2:       # %bb.0:
98; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
99; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
100; X86-BMI1BMI2-NEXT:    retl
101;
102; X64-NOBMI-LABEL: bzhi32_a1_indexzext:
103; X64-NOBMI:       # %bb.0:
104; X64-NOBMI-NEXT:    movl %esi, %ecx
105; X64-NOBMI-NEXT:    movl $1, %eax
106; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
107; X64-NOBMI-NEXT:    shll %cl, %eax
108; X64-NOBMI-NEXT:    decl %eax
109; X64-NOBMI-NEXT:    andl %edi, %eax
110; X64-NOBMI-NEXT:    retq
111;
112; X64-BMI1NOTBM-LABEL: bzhi32_a1_indexzext:
113; X64-BMI1NOTBM:       # %bb.0:
114; X64-BMI1NOTBM-NEXT:    shll $8, %esi
115; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
116; X64-BMI1NOTBM-NEXT:    retq
117;
118; X64-BMI1BMI2-LABEL: bzhi32_a1_indexzext:
119; X64-BMI1BMI2:       # %bb.0:
120; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
121; X64-BMI1BMI2-NEXT:    retq
122  %conv = zext i8 %numlowbits to i32
123  %onebit = shl i32 1, %conv
124  %mask = add nsw i32 %onebit, -1
125  %masked = and i32 %mask, %val
126  ret i32 %masked
127}
128
129define i32 @bzhi32_a2_load(i32* %w, i32 %numlowbits) nounwind {
130; X86-NOBMI-LABEL: bzhi32_a2_load:
131; X86-NOBMI:       # %bb.0:
132; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
133; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
134; X86-NOBMI-NEXT:    movl $1, %eax
135; X86-NOBMI-NEXT:    shll %cl, %eax
136; X86-NOBMI-NEXT:    decl %eax
137; X86-NOBMI-NEXT:    andl (%edx), %eax
138; X86-NOBMI-NEXT:    retl
139;
140; X86-BMI1NOTBM-LABEL: bzhi32_a2_load:
141; X86-BMI1NOTBM:       # %bb.0:
142; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
143; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
144; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
145; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
146; X86-BMI1NOTBM-NEXT:    retl
147;
148; X86-BMI1BMI2-LABEL: bzhi32_a2_load:
149; X86-BMI1BMI2:       # %bb.0:
150; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
151; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
152; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
153; X86-BMI1BMI2-NEXT:    retl
154;
155; X64-NOBMI-LABEL: bzhi32_a2_load:
156; X64-NOBMI:       # %bb.0:
157; X64-NOBMI-NEXT:    movl %esi, %ecx
158; X64-NOBMI-NEXT:    movl $1, %eax
159; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
160; X64-NOBMI-NEXT:    shll %cl, %eax
161; X64-NOBMI-NEXT:    decl %eax
162; X64-NOBMI-NEXT:    andl (%rdi), %eax
163; X64-NOBMI-NEXT:    retq
164;
165; X64-BMI1NOTBM-LABEL: bzhi32_a2_load:
166; X64-BMI1NOTBM:       # %bb.0:
167; X64-BMI1NOTBM-NEXT:    shll $8, %esi
168; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
169; X64-BMI1NOTBM-NEXT:    retq
170;
171; X64-BMI1BMI2-LABEL: bzhi32_a2_load:
172; X64-BMI1BMI2:       # %bb.0:
173; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
174; X64-BMI1BMI2-NEXT:    retq
175  %val = load i32, i32* %w
176  %onebit = shl i32 1, %numlowbits
177  %mask = add nsw i32 %onebit, -1
178  %masked = and i32 %mask, %val
179  ret i32 %masked
180}
181
182define i32 @bzhi32_a3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind {
183; X86-NOBMI-LABEL: bzhi32_a3_load_indexzext:
184; X86-NOBMI:       # %bb.0:
185; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
186; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
187; X86-NOBMI-NEXT:    movl $1, %eax
188; X86-NOBMI-NEXT:    shll %cl, %eax
189; X86-NOBMI-NEXT:    decl %eax
190; X86-NOBMI-NEXT:    andl (%edx), %eax
191; X86-NOBMI-NEXT:    retl
192;
193; X86-BMI1NOTBM-LABEL: bzhi32_a3_load_indexzext:
194; X86-BMI1NOTBM:       # %bb.0:
195; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
196; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
197; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
198; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
199; X86-BMI1NOTBM-NEXT:    retl
200;
201; X86-BMI1BMI2-LABEL: bzhi32_a3_load_indexzext:
202; X86-BMI1BMI2:       # %bb.0:
203; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
204; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
205; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
206; X86-BMI1BMI2-NEXT:    retl
207;
208; X64-NOBMI-LABEL: bzhi32_a3_load_indexzext:
209; X64-NOBMI:       # %bb.0:
210; X64-NOBMI-NEXT:    movl %esi, %ecx
211; X64-NOBMI-NEXT:    movl $1, %eax
212; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
213; X64-NOBMI-NEXT:    shll %cl, %eax
214; X64-NOBMI-NEXT:    decl %eax
215; X64-NOBMI-NEXT:    andl (%rdi), %eax
216; X64-NOBMI-NEXT:    retq
217;
218; X64-BMI1NOTBM-LABEL: bzhi32_a3_load_indexzext:
219; X64-BMI1NOTBM:       # %bb.0:
220; X64-BMI1NOTBM-NEXT:    shll $8, %esi
221; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
222; X64-BMI1NOTBM-NEXT:    retq
223;
224; X64-BMI1BMI2-LABEL: bzhi32_a3_load_indexzext:
225; X64-BMI1BMI2:       # %bb.0:
226; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
227; X64-BMI1BMI2-NEXT:    retq
228  %val = load i32, i32* %w
229  %conv = zext i8 %numlowbits to i32
230  %onebit = shl i32 1, %conv
231  %mask = add nsw i32 %onebit, -1
232  %masked = and i32 %mask, %val
233  ret i32 %masked
234}
235
236define i32 @bzhi32_a4_commutative(i32 %val, i32 %numlowbits) nounwind {
237; X86-NOBMI-LABEL: bzhi32_a4_commutative:
238; X86-NOBMI:       # %bb.0:
239; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
240; X86-NOBMI-NEXT:    movl $1, %eax
241; X86-NOBMI-NEXT:    shll %cl, %eax
242; X86-NOBMI-NEXT:    decl %eax
243; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
244; X86-NOBMI-NEXT:    retl
245;
246; X86-BMI1NOTBM-LABEL: bzhi32_a4_commutative:
247; X86-BMI1NOTBM:       # %bb.0:
248; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
249; X86-BMI1NOTBM-NEXT:    shll $8, %eax
250; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
251; X86-BMI1NOTBM-NEXT:    retl
252;
253; X86-BMI1BMI2-LABEL: bzhi32_a4_commutative:
254; X86-BMI1BMI2:       # %bb.0:
255; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
256; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
257; X86-BMI1BMI2-NEXT:    retl
258;
259; X64-NOBMI-LABEL: bzhi32_a4_commutative:
260; X64-NOBMI:       # %bb.0:
261; X64-NOBMI-NEXT:    movl %esi, %ecx
262; X64-NOBMI-NEXT:    movl $1, %eax
263; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
264; X64-NOBMI-NEXT:    shll %cl, %eax
265; X64-NOBMI-NEXT:    decl %eax
266; X64-NOBMI-NEXT:    andl %edi, %eax
267; X64-NOBMI-NEXT:    retq
268;
269; X64-BMI1NOTBM-LABEL: bzhi32_a4_commutative:
270; X64-BMI1NOTBM:       # %bb.0:
271; X64-BMI1NOTBM-NEXT:    shll $8, %esi
272; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
273; X64-BMI1NOTBM-NEXT:    retq
274;
275; X64-BMI1BMI2-LABEL: bzhi32_a4_commutative:
276; X64-BMI1BMI2:       # %bb.0:
277; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
278; X64-BMI1BMI2-NEXT:    retq
279  %onebit = shl i32 1, %numlowbits
280  %mask = add nsw i32 %onebit, -1
281  %masked = and i32 %val, %mask ; swapped order
282  ret i32 %masked
283}
284
285; 64-bit
286
287define i64 @bzhi64_a0(i64 %val, i64 %numlowbits) nounwind {
288; X86-NOBMI-LABEL: bzhi64_a0:
289; X86-NOBMI:       # %bb.0:
290; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
291; X86-NOBMI-NEXT:    movl $1, %eax
292; X86-NOBMI-NEXT:    xorl %edx, %edx
293; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
294; X86-NOBMI-NEXT:    shll %cl, %eax
295; X86-NOBMI-NEXT:    testb $32, %cl
296; X86-NOBMI-NEXT:    je .LBB5_2
297; X86-NOBMI-NEXT:  # %bb.1:
298; X86-NOBMI-NEXT:    movl %eax, %edx
299; X86-NOBMI-NEXT:    xorl %eax, %eax
300; X86-NOBMI-NEXT:  .LBB5_2:
301; X86-NOBMI-NEXT:    addl $-1, %eax
302; X86-NOBMI-NEXT:    adcl $-1, %edx
303; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
304; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
305; X86-NOBMI-NEXT:    retl
306;
307; X86-BMI1NOTBM-LABEL: bzhi64_a0:
308; X86-BMI1NOTBM:       # %bb.0:
309; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
310; X86-BMI1NOTBM-NEXT:    movl $1, %eax
311; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
312; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
313; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
314; X86-BMI1NOTBM-NEXT:    testb $32, %cl
315; X86-BMI1NOTBM-NEXT:    je .LBB5_2
316; X86-BMI1NOTBM-NEXT:  # %bb.1:
317; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
318; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
319; X86-BMI1NOTBM-NEXT:  .LBB5_2:
320; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
321; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
322; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edx
323; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %eax
324; X86-BMI1NOTBM-NEXT:    retl
325;
326; X86-BMI1BMI2-LABEL: bzhi64_a0:
327; X86-BMI1BMI2:       # %bb.0:
328; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
329; X86-BMI1BMI2-NEXT:    movl $1, %eax
330; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
331; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
332; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
333; X86-BMI1BMI2-NEXT:    testb $32, %cl
334; X86-BMI1BMI2-NEXT:    je .LBB5_2
335; X86-BMI1BMI2-NEXT:  # %bb.1:
336; X86-BMI1BMI2-NEXT:    movl %eax, %edx
337; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
338; X86-BMI1BMI2-NEXT:  .LBB5_2:
339; X86-BMI1BMI2-NEXT:    addl $-1, %eax
340; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
341; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
342; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
343; X86-BMI1BMI2-NEXT:    retl
344;
345; X64-NOBMI-LABEL: bzhi64_a0:
346; X64-NOBMI:       # %bb.0:
347; X64-NOBMI-NEXT:    movq %rsi, %rcx
348; X64-NOBMI-NEXT:    movl $1, %eax
349; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
350; X64-NOBMI-NEXT:    shlq %cl, %rax
351; X64-NOBMI-NEXT:    decq %rax
352; X64-NOBMI-NEXT:    andq %rdi, %rax
353; X64-NOBMI-NEXT:    retq
354;
355; X64-BMI1NOTBM-LABEL: bzhi64_a0:
356; X64-BMI1NOTBM:       # %bb.0:
357; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
358; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
359; X64-BMI1NOTBM-NEXT:    retq
360;
361; X64-BMI1BMI2-LABEL: bzhi64_a0:
362; X64-BMI1BMI2:       # %bb.0:
363; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
364; X64-BMI1BMI2-NEXT:    retq
365  %onebit = shl i64 1, %numlowbits
366  %mask = add nsw i64 %onebit, -1
367  %masked = and i64 %mask, %val
368  ret i64 %masked
369}
370
371define i64 @bzhi64_a1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
372; X86-NOBMI-LABEL: bzhi64_a1_indexzext:
373; X86-NOBMI:       # %bb.0:
374; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
375; X86-NOBMI-NEXT:    movl $1, %eax
376; X86-NOBMI-NEXT:    xorl %edx, %edx
377; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
378; X86-NOBMI-NEXT:    shll %cl, %eax
379; X86-NOBMI-NEXT:    testb $32, %cl
380; X86-NOBMI-NEXT:    je .LBB6_2
381; X86-NOBMI-NEXT:  # %bb.1:
382; X86-NOBMI-NEXT:    movl %eax, %edx
383; X86-NOBMI-NEXT:    xorl %eax, %eax
384; X86-NOBMI-NEXT:  .LBB6_2:
385; X86-NOBMI-NEXT:    addl $-1, %eax
386; X86-NOBMI-NEXT:    adcl $-1, %edx
387; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
388; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
389; X86-NOBMI-NEXT:    retl
390;
391; X86-BMI1NOTBM-LABEL: bzhi64_a1_indexzext:
392; X86-BMI1NOTBM:       # %bb.0:
393; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
394; X86-BMI1NOTBM-NEXT:    movl $1, %eax
395; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
396; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
397; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
398; X86-BMI1NOTBM-NEXT:    testb $32, %cl
399; X86-BMI1NOTBM-NEXT:    je .LBB6_2
400; X86-BMI1NOTBM-NEXT:  # %bb.1:
401; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
402; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
403; X86-BMI1NOTBM-NEXT:  .LBB6_2:
404; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
405; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
406; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edx
407; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %eax
408; X86-BMI1NOTBM-NEXT:    retl
409;
410; X86-BMI1BMI2-LABEL: bzhi64_a1_indexzext:
411; X86-BMI1BMI2:       # %bb.0:
412; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
413; X86-BMI1BMI2-NEXT:    movl $1, %eax
414; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
415; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
416; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
417; X86-BMI1BMI2-NEXT:    testb $32, %cl
418; X86-BMI1BMI2-NEXT:    je .LBB6_2
419; X86-BMI1BMI2-NEXT:  # %bb.1:
420; X86-BMI1BMI2-NEXT:    movl %eax, %edx
421; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
422; X86-BMI1BMI2-NEXT:  .LBB6_2:
423; X86-BMI1BMI2-NEXT:    addl $-1, %eax
424; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
425; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
426; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
427; X86-BMI1BMI2-NEXT:    retl
428;
429; X64-NOBMI-LABEL: bzhi64_a1_indexzext:
430; X64-NOBMI:       # %bb.0:
431; X64-NOBMI-NEXT:    movl %esi, %ecx
432; X64-NOBMI-NEXT:    movl $1, %eax
433; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
434; X64-NOBMI-NEXT:    shlq %cl, %rax
435; X64-NOBMI-NEXT:    decq %rax
436; X64-NOBMI-NEXT:    andq %rdi, %rax
437; X64-NOBMI-NEXT:    retq
438;
439; X64-BMI1NOTBM-LABEL: bzhi64_a1_indexzext:
440; X64-BMI1NOTBM:       # %bb.0:
441; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
442; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
443; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
444; X64-BMI1NOTBM-NEXT:    retq
445;
446; X64-BMI1BMI2-LABEL: bzhi64_a1_indexzext:
447; X64-BMI1BMI2:       # %bb.0:
448; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
449; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
450; X64-BMI1BMI2-NEXT:    retq
451  %conv = zext i8 %numlowbits to i64
452  %onebit = shl i64 1, %conv
453  %mask = add nsw i64 %onebit, -1
454  %masked = and i64 %mask, %val
455  ret i64 %masked
456}
457
458define i64 @bzhi64_a2_load(i64* %w, i64 %numlowbits) nounwind {
459; X86-NOBMI-LABEL: bzhi64_a2_load:
460; X86-NOBMI:       # %bb.0:
461; X86-NOBMI-NEXT:    pushl %esi
462; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
463; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
464; X86-NOBMI-NEXT:    movl $1, %eax
465; X86-NOBMI-NEXT:    xorl %edx, %edx
466; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
467; X86-NOBMI-NEXT:    shll %cl, %eax
468; X86-NOBMI-NEXT:    testb $32, %cl
469; X86-NOBMI-NEXT:    je .LBB7_2
470; X86-NOBMI-NEXT:  # %bb.1:
471; X86-NOBMI-NEXT:    movl %eax, %edx
472; X86-NOBMI-NEXT:    xorl %eax, %eax
473; X86-NOBMI-NEXT:  .LBB7_2:
474; X86-NOBMI-NEXT:    addl $-1, %eax
475; X86-NOBMI-NEXT:    adcl $-1, %edx
476; X86-NOBMI-NEXT:    andl 4(%esi), %edx
477; X86-NOBMI-NEXT:    andl (%esi), %eax
478; X86-NOBMI-NEXT:    popl %esi
479; X86-NOBMI-NEXT:    retl
480;
481; X86-BMI1NOTBM-LABEL: bzhi64_a2_load:
482; X86-BMI1NOTBM:       # %bb.0:
483; X86-BMI1NOTBM-NEXT:    pushl %esi
484; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
485; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
486; X86-BMI1NOTBM-NEXT:    movl $1, %eax
487; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
488; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
489; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
490; X86-BMI1NOTBM-NEXT:    testb $32, %cl
491; X86-BMI1NOTBM-NEXT:    je .LBB7_2
492; X86-BMI1NOTBM-NEXT:  # %bb.1:
493; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
494; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
495; X86-BMI1NOTBM-NEXT:  .LBB7_2:
496; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
497; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
498; X86-BMI1NOTBM-NEXT:    andl 4(%esi), %edx
499; X86-BMI1NOTBM-NEXT:    andl (%esi), %eax
500; X86-BMI1NOTBM-NEXT:    popl %esi
501; X86-BMI1NOTBM-NEXT:    retl
502;
503; X86-BMI1BMI2-LABEL: bzhi64_a2_load:
504; X86-BMI1BMI2:       # %bb.0:
505; X86-BMI1BMI2-NEXT:    pushl %esi
506; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
507; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
508; X86-BMI1BMI2-NEXT:    movl $1, %eax
509; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
510; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
511; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
512; X86-BMI1BMI2-NEXT:    testb $32, %cl
513; X86-BMI1BMI2-NEXT:    je .LBB7_2
514; X86-BMI1BMI2-NEXT:  # %bb.1:
515; X86-BMI1BMI2-NEXT:    movl %eax, %edx
516; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
517; X86-BMI1BMI2-NEXT:  .LBB7_2:
518; X86-BMI1BMI2-NEXT:    addl $-1, %eax
519; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
520; X86-BMI1BMI2-NEXT:    andl 4(%esi), %edx
521; X86-BMI1BMI2-NEXT:    andl (%esi), %eax
522; X86-BMI1BMI2-NEXT:    popl %esi
523; X86-BMI1BMI2-NEXT:    retl
524;
525; X64-NOBMI-LABEL: bzhi64_a2_load:
526; X64-NOBMI:       # %bb.0:
527; X64-NOBMI-NEXT:    movq %rsi, %rcx
528; X64-NOBMI-NEXT:    movl $1, %eax
529; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
530; X64-NOBMI-NEXT:    shlq %cl, %rax
531; X64-NOBMI-NEXT:    decq %rax
532; X64-NOBMI-NEXT:    andq (%rdi), %rax
533; X64-NOBMI-NEXT:    retq
534;
535; X64-BMI1NOTBM-LABEL: bzhi64_a2_load:
536; X64-BMI1NOTBM:       # %bb.0:
537; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
538; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
539; X64-BMI1NOTBM-NEXT:    retq
540;
541; X64-BMI1BMI2-LABEL: bzhi64_a2_load:
542; X64-BMI1BMI2:       # %bb.0:
543; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
544; X64-BMI1BMI2-NEXT:    retq
545  %val = load i64, i64* %w
546  %onebit = shl i64 1, %numlowbits
547  %mask = add nsw i64 %onebit, -1
548  %masked = and i64 %mask, %val
549  ret i64 %masked
550}
551
552define i64 @bzhi64_a3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind {
553; X86-NOBMI-LABEL: bzhi64_a3_load_indexzext:
554; X86-NOBMI:       # %bb.0:
555; X86-NOBMI-NEXT:    pushl %esi
556; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
557; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
558; X86-NOBMI-NEXT:    movl $1, %eax
559; X86-NOBMI-NEXT:    xorl %edx, %edx
560; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
561; X86-NOBMI-NEXT:    shll %cl, %eax
562; X86-NOBMI-NEXT:    testb $32, %cl
563; X86-NOBMI-NEXT:    je .LBB8_2
564; X86-NOBMI-NEXT:  # %bb.1:
565; X86-NOBMI-NEXT:    movl %eax, %edx
566; X86-NOBMI-NEXT:    xorl %eax, %eax
567; X86-NOBMI-NEXT:  .LBB8_2:
568; X86-NOBMI-NEXT:    addl $-1, %eax
569; X86-NOBMI-NEXT:    adcl $-1, %edx
570; X86-NOBMI-NEXT:    andl 4(%esi), %edx
571; X86-NOBMI-NEXT:    andl (%esi), %eax
572; X86-NOBMI-NEXT:    popl %esi
573; X86-NOBMI-NEXT:    retl
574;
575; X86-BMI1NOTBM-LABEL: bzhi64_a3_load_indexzext:
576; X86-BMI1NOTBM:       # %bb.0:
577; X86-BMI1NOTBM-NEXT:    pushl %esi
578; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
579; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
580; X86-BMI1NOTBM-NEXT:    movl $1, %eax
581; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
582; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
583; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
584; X86-BMI1NOTBM-NEXT:    testb $32, %cl
585; X86-BMI1NOTBM-NEXT:    je .LBB8_2
586; X86-BMI1NOTBM-NEXT:  # %bb.1:
587; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
588; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
589; X86-BMI1NOTBM-NEXT:  .LBB8_2:
590; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
591; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
592; X86-BMI1NOTBM-NEXT:    andl 4(%esi), %edx
593; X86-BMI1NOTBM-NEXT:    andl (%esi), %eax
594; X86-BMI1NOTBM-NEXT:    popl %esi
595; X86-BMI1NOTBM-NEXT:    retl
596;
597; X86-BMI1BMI2-LABEL: bzhi64_a3_load_indexzext:
598; X86-BMI1BMI2:       # %bb.0:
599; X86-BMI1BMI2-NEXT:    pushl %esi
600; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
601; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
602; X86-BMI1BMI2-NEXT:    movl $1, %eax
603; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
604; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
605; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
606; X86-BMI1BMI2-NEXT:    testb $32, %cl
607; X86-BMI1BMI2-NEXT:    je .LBB8_2
608; X86-BMI1BMI2-NEXT:  # %bb.1:
609; X86-BMI1BMI2-NEXT:    movl %eax, %edx
610; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
611; X86-BMI1BMI2-NEXT:  .LBB8_2:
612; X86-BMI1BMI2-NEXT:    addl $-1, %eax
613; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
614; X86-BMI1BMI2-NEXT:    andl 4(%esi), %edx
615; X86-BMI1BMI2-NEXT:    andl (%esi), %eax
616; X86-BMI1BMI2-NEXT:    popl %esi
617; X86-BMI1BMI2-NEXT:    retl
618;
619; X64-NOBMI-LABEL: bzhi64_a3_load_indexzext:
620; X64-NOBMI:       # %bb.0:
621; X64-NOBMI-NEXT:    movl %esi, %ecx
622; X64-NOBMI-NEXT:    movl $1, %eax
623; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
624; X64-NOBMI-NEXT:    shlq %cl, %rax
625; X64-NOBMI-NEXT:    decq %rax
626; X64-NOBMI-NEXT:    andq (%rdi), %rax
627; X64-NOBMI-NEXT:    retq
628;
629; X64-BMI1NOTBM-LABEL: bzhi64_a3_load_indexzext:
630; X64-BMI1NOTBM:       # %bb.0:
631; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
632; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
633; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
634; X64-BMI1NOTBM-NEXT:    retq
635;
636; X64-BMI1BMI2-LABEL: bzhi64_a3_load_indexzext:
637; X64-BMI1BMI2:       # %bb.0:
638; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
639; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
640; X64-BMI1BMI2-NEXT:    retq
641  %val = load i64, i64* %w
642  %conv = zext i8 %numlowbits to i64
643  %onebit = shl i64 1, %conv
644  %mask = add nsw i64 %onebit, -1
645  %masked = and i64 %mask, %val
646  ret i64 %masked
647}
648
649define i64 @bzhi64_a4_commutative(i64 %val, i64 %numlowbits) nounwind {
650; X86-NOBMI-LABEL: bzhi64_a4_commutative:
651; X86-NOBMI:       # %bb.0:
652; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
653; X86-NOBMI-NEXT:    movl $1, %eax
654; X86-NOBMI-NEXT:    xorl %edx, %edx
655; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
656; X86-NOBMI-NEXT:    shll %cl, %eax
657; X86-NOBMI-NEXT:    testb $32, %cl
658; X86-NOBMI-NEXT:    je .LBB9_2
659; X86-NOBMI-NEXT:  # %bb.1:
660; X86-NOBMI-NEXT:    movl %eax, %edx
661; X86-NOBMI-NEXT:    xorl %eax, %eax
662; X86-NOBMI-NEXT:  .LBB9_2:
663; X86-NOBMI-NEXT:    addl $-1, %eax
664; X86-NOBMI-NEXT:    adcl $-1, %edx
665; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
666; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
667; X86-NOBMI-NEXT:    retl
668;
669; X86-BMI1NOTBM-LABEL: bzhi64_a4_commutative:
670; X86-BMI1NOTBM:       # %bb.0:
671; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
672; X86-BMI1NOTBM-NEXT:    movl $1, %eax
673; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
674; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
675; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
676; X86-BMI1NOTBM-NEXT:    testb $32, %cl
677; X86-BMI1NOTBM-NEXT:    je .LBB9_2
678; X86-BMI1NOTBM-NEXT:  # %bb.1:
679; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
680; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
681; X86-BMI1NOTBM-NEXT:  .LBB9_2:
682; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
683; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
684; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edx
685; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %eax
686; X86-BMI1NOTBM-NEXT:    retl
687;
688; X86-BMI1BMI2-LABEL: bzhi64_a4_commutative:
689; X86-BMI1BMI2:       # %bb.0:
690; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
691; X86-BMI1BMI2-NEXT:    movl $1, %eax
692; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
693; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
694; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
695; X86-BMI1BMI2-NEXT:    testb $32, %cl
696; X86-BMI1BMI2-NEXT:    je .LBB9_2
697; X86-BMI1BMI2-NEXT:  # %bb.1:
698; X86-BMI1BMI2-NEXT:    movl %eax, %edx
699; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
700; X86-BMI1BMI2-NEXT:  .LBB9_2:
701; X86-BMI1BMI2-NEXT:    addl $-1, %eax
702; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
703; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edx
704; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %eax
705; X86-BMI1BMI2-NEXT:    retl
706;
707; X64-NOBMI-LABEL: bzhi64_a4_commutative:
708; X64-NOBMI:       # %bb.0:
709; X64-NOBMI-NEXT:    movq %rsi, %rcx
710; X64-NOBMI-NEXT:    movl $1, %eax
711; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
712; X64-NOBMI-NEXT:    shlq %cl, %rax
713; X64-NOBMI-NEXT:    decq %rax
714; X64-NOBMI-NEXT:    andq %rdi, %rax
715; X64-NOBMI-NEXT:    retq
716;
717; X64-BMI1NOTBM-LABEL: bzhi64_a4_commutative:
718; X64-BMI1NOTBM:       # %bb.0:
719; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
720; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
721; X64-BMI1NOTBM-NEXT:    retq
722;
723; X64-BMI1BMI2-LABEL: bzhi64_a4_commutative:
724; X64-BMI1BMI2:       # %bb.0:
725; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
726; X64-BMI1BMI2-NEXT:    retq
727  %onebit = shl i64 1, %numlowbits
728  %mask = add nsw i64 %onebit, -1
729  %masked = and i64 %val, %mask ; swapped order
730  ret i64 %masked
731}
732
733; ---------------------------------------------------------------------------- ;
734; Pattern b. 32-bit
735; ---------------------------------------------------------------------------- ;
736
737define i32 @bzhi32_b0(i32 %val, i32 %numlowbits) nounwind {
738; X86-NOBMI-LABEL: bzhi32_b0:
739; X86-NOBMI:       # %bb.0:
740; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
741; X86-NOBMI-NEXT:    movl $-1, %eax
742; X86-NOBMI-NEXT:    shll %cl, %eax
743; X86-NOBMI-NEXT:    notl %eax
744; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
745; X86-NOBMI-NEXT:    retl
746;
747; X86-BMI1NOTBM-LABEL: bzhi32_b0:
748; X86-BMI1NOTBM:       # %bb.0:
749; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
750; X86-BMI1NOTBM-NEXT:    shll $8, %eax
751; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
752; X86-BMI1NOTBM-NEXT:    retl
753;
754; X86-BMI1BMI2-LABEL: bzhi32_b0:
755; X86-BMI1BMI2:       # %bb.0:
756; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
757; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
758; X86-BMI1BMI2-NEXT:    retl
759;
760; X64-NOBMI-LABEL: bzhi32_b0:
761; X64-NOBMI:       # %bb.0:
762; X64-NOBMI-NEXT:    movl %esi, %ecx
763; X64-NOBMI-NEXT:    movl $-1, %eax
764; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
765; X64-NOBMI-NEXT:    shll %cl, %eax
766; X64-NOBMI-NEXT:    notl %eax
767; X64-NOBMI-NEXT:    andl %edi, %eax
768; X64-NOBMI-NEXT:    retq
769;
770; X64-BMI1NOTBM-LABEL: bzhi32_b0:
771; X64-BMI1NOTBM:       # %bb.0:
772; X64-BMI1NOTBM-NEXT:    shll $8, %esi
773; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
774; X64-BMI1NOTBM-NEXT:    retq
775;
776; X64-BMI1BMI2-LABEL: bzhi32_b0:
777; X64-BMI1BMI2:       # %bb.0:
778; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
779; X64-BMI1BMI2-NEXT:    retq
780  %notmask = shl i32 -1, %numlowbits
781  %mask = xor i32 %notmask, -1
782  %masked = and i32 %mask, %val
783  ret i32 %masked
784}
785
786define i32 @bzhi32_b1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {
787; X86-NOBMI-LABEL: bzhi32_b1_indexzext:
788; X86-NOBMI:       # %bb.0:
789; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
790; X86-NOBMI-NEXT:    movl $-1, %eax
791; X86-NOBMI-NEXT:    shll %cl, %eax
792; X86-NOBMI-NEXT:    notl %eax
793; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
794; X86-NOBMI-NEXT:    retl
795;
796; X86-BMI1NOTBM-LABEL: bzhi32_b1_indexzext:
797; X86-BMI1NOTBM:       # %bb.0:
798; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
799; X86-BMI1NOTBM-NEXT:    shll $8, %eax
800; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
801; X86-BMI1NOTBM-NEXT:    retl
802;
803; X86-BMI1BMI2-LABEL: bzhi32_b1_indexzext:
804; X86-BMI1BMI2:       # %bb.0:
805; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
806; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
807; X86-BMI1BMI2-NEXT:    retl
808;
809; X64-NOBMI-LABEL: bzhi32_b1_indexzext:
810; X64-NOBMI:       # %bb.0:
811; X64-NOBMI-NEXT:    movl %esi, %ecx
812; X64-NOBMI-NEXT:    movl $-1, %eax
813; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
814; X64-NOBMI-NEXT:    shll %cl, %eax
815; X64-NOBMI-NEXT:    notl %eax
816; X64-NOBMI-NEXT:    andl %edi, %eax
817; X64-NOBMI-NEXT:    retq
818;
819; X64-BMI1NOTBM-LABEL: bzhi32_b1_indexzext:
820; X64-BMI1NOTBM:       # %bb.0:
821; X64-BMI1NOTBM-NEXT:    shll $8, %esi
822; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
823; X64-BMI1NOTBM-NEXT:    retq
824;
825; X64-BMI1BMI2-LABEL: bzhi32_b1_indexzext:
826; X64-BMI1BMI2:       # %bb.0:
827; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
828; X64-BMI1BMI2-NEXT:    retq
829  %conv = zext i8 %numlowbits to i32
830  %notmask = shl i32 -1, %conv
831  %mask = xor i32 %notmask, -1
832  %masked = and i32 %mask, %val
833  ret i32 %masked
834}
835
836define i32 @bzhi32_b2_load(i32* %w, i32 %numlowbits) nounwind {
837; X86-NOBMI-LABEL: bzhi32_b2_load:
838; X86-NOBMI:       # %bb.0:
839; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
840; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
841; X86-NOBMI-NEXT:    movl $-1, %eax
842; X86-NOBMI-NEXT:    shll %cl, %eax
843; X86-NOBMI-NEXT:    notl %eax
844; X86-NOBMI-NEXT:    andl (%edx), %eax
845; X86-NOBMI-NEXT:    retl
846;
847; X86-BMI1NOTBM-LABEL: bzhi32_b2_load:
848; X86-BMI1NOTBM:       # %bb.0:
849; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
850; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
851; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
852; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
853; X86-BMI1NOTBM-NEXT:    retl
854;
855; X86-BMI1BMI2-LABEL: bzhi32_b2_load:
856; X86-BMI1BMI2:       # %bb.0:
857; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
858; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
859; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
860; X86-BMI1BMI2-NEXT:    retl
861;
862; X64-NOBMI-LABEL: bzhi32_b2_load:
863; X64-NOBMI:       # %bb.0:
864; X64-NOBMI-NEXT:    movl %esi, %ecx
865; X64-NOBMI-NEXT:    movl $-1, %eax
866; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
867; X64-NOBMI-NEXT:    shll %cl, %eax
868; X64-NOBMI-NEXT:    notl %eax
869; X64-NOBMI-NEXT:    andl (%rdi), %eax
870; X64-NOBMI-NEXT:    retq
871;
872; X64-BMI1NOTBM-LABEL: bzhi32_b2_load:
873; X64-BMI1NOTBM:       # %bb.0:
874; X64-BMI1NOTBM-NEXT:    shll $8, %esi
875; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
876; X64-BMI1NOTBM-NEXT:    retq
877;
878; X64-BMI1BMI2-LABEL: bzhi32_b2_load:
879; X64-BMI1BMI2:       # %bb.0:
880; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
881; X64-BMI1BMI2-NEXT:    retq
882  %val = load i32, i32* %w
883  %notmask = shl i32 -1, %numlowbits
884  %mask = xor i32 %notmask, -1
885  %masked = and i32 %mask, %val
886  ret i32 %masked
887}
888
889define i32 @bzhi32_b3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind {
890; X86-NOBMI-LABEL: bzhi32_b3_load_indexzext:
891; X86-NOBMI:       # %bb.0:
892; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
893; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
894; X86-NOBMI-NEXT:    movl $-1, %eax
895; X86-NOBMI-NEXT:    shll %cl, %eax
896; X86-NOBMI-NEXT:    notl %eax
897; X86-NOBMI-NEXT:    andl (%edx), %eax
898; X86-NOBMI-NEXT:    retl
899;
900; X86-BMI1NOTBM-LABEL: bzhi32_b3_load_indexzext:
901; X86-BMI1NOTBM:       # %bb.0:
902; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
903; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
904; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
905; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
906; X86-BMI1NOTBM-NEXT:    retl
907;
908; X86-BMI1BMI2-LABEL: bzhi32_b3_load_indexzext:
909; X86-BMI1BMI2:       # %bb.0:
910; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
911; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
912; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
913; X86-BMI1BMI2-NEXT:    retl
914;
915; X64-NOBMI-LABEL: bzhi32_b3_load_indexzext:
916; X64-NOBMI:       # %bb.0:
917; X64-NOBMI-NEXT:    movl %esi, %ecx
918; X64-NOBMI-NEXT:    movl $-1, %eax
919; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
920; X64-NOBMI-NEXT:    shll %cl, %eax
921; X64-NOBMI-NEXT:    notl %eax
922; X64-NOBMI-NEXT:    andl (%rdi), %eax
923; X64-NOBMI-NEXT:    retq
924;
925; X64-BMI1NOTBM-LABEL: bzhi32_b3_load_indexzext:
926; X64-BMI1NOTBM:       # %bb.0:
927; X64-BMI1NOTBM-NEXT:    shll $8, %esi
928; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
929; X64-BMI1NOTBM-NEXT:    retq
930;
931; X64-BMI1BMI2-LABEL: bzhi32_b3_load_indexzext:
932; X64-BMI1BMI2:       # %bb.0:
933; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
934; X64-BMI1BMI2-NEXT:    retq
935  %val = load i32, i32* %w
936  %conv = zext i8 %numlowbits to i32
937  %notmask = shl i32 -1, %conv
938  %mask = xor i32 %notmask, -1
939  %masked = and i32 %mask, %val
940  ret i32 %masked
941}
942
943define i32 @bzhi32_b4_commutative(i32 %val, i32 %numlowbits) nounwind {
944; X86-NOBMI-LABEL: bzhi32_b4_commutative:
945; X86-NOBMI:       # %bb.0:
946; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
947; X86-NOBMI-NEXT:    movl $-1, %eax
948; X86-NOBMI-NEXT:    shll %cl, %eax
949; X86-NOBMI-NEXT:    notl %eax
950; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
951; X86-NOBMI-NEXT:    retl
952;
953; X86-BMI1NOTBM-LABEL: bzhi32_b4_commutative:
954; X86-BMI1NOTBM:       # %bb.0:
955; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
956; X86-BMI1NOTBM-NEXT:    shll $8, %eax
957; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
958; X86-BMI1NOTBM-NEXT:    retl
959;
960; X86-BMI1BMI2-LABEL: bzhi32_b4_commutative:
961; X86-BMI1BMI2:       # %bb.0:
962; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
963; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
964; X86-BMI1BMI2-NEXT:    retl
965;
966; X64-NOBMI-LABEL: bzhi32_b4_commutative:
967; X64-NOBMI:       # %bb.0:
968; X64-NOBMI-NEXT:    movl %esi, %ecx
969; X64-NOBMI-NEXT:    movl $-1, %eax
970; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
971; X64-NOBMI-NEXT:    shll %cl, %eax
972; X64-NOBMI-NEXT:    notl %eax
973; X64-NOBMI-NEXT:    andl %edi, %eax
974; X64-NOBMI-NEXT:    retq
975;
976; X64-BMI1NOTBM-LABEL: bzhi32_b4_commutative:
977; X64-BMI1NOTBM:       # %bb.0:
978; X64-BMI1NOTBM-NEXT:    shll $8, %esi
979; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
980; X64-BMI1NOTBM-NEXT:    retq
981;
982; X64-BMI1BMI2-LABEL: bzhi32_b4_commutative:
983; X64-BMI1BMI2:       # %bb.0:
984; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
985; X64-BMI1BMI2-NEXT:    retq
986  %notmask = shl i32 -1, %numlowbits
987  %mask = xor i32 %notmask, -1
988  %masked = and i32 %val, %mask ; swapped order
989  ret i32 %masked
990}
991
992; 64-bit
993
994define i64 @bzhi64_b0(i64 %val, i64 %numlowbits) nounwind {
995; X86-NOBMI-LABEL: bzhi64_b0:
996; X86-NOBMI:       # %bb.0:
997; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
998; X86-NOBMI-NEXT:    movl $-1, %edx
999; X86-NOBMI-NEXT:    movl $-1, %eax
1000; X86-NOBMI-NEXT:    shll %cl, %eax
1001; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
1002; X86-NOBMI-NEXT:    testb $32, %cl
1003; X86-NOBMI-NEXT:    je .LBB15_2
1004; X86-NOBMI-NEXT:  # %bb.1:
1005; X86-NOBMI-NEXT:    movl %eax, %edx
1006; X86-NOBMI-NEXT:    xorl %eax, %eax
1007; X86-NOBMI-NEXT:  .LBB15_2:
1008; X86-NOBMI-NEXT:    notl %edx
1009; X86-NOBMI-NEXT:    notl %eax
1010; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
1011; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
1012; X86-NOBMI-NEXT:    retl
1013;
1014; X86-BMI1NOTBM-LABEL: bzhi64_b0:
1015; X86-BMI1NOTBM:       # %bb.0:
1016; X86-BMI1NOTBM-NEXT:    pushl %esi
1017; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1018; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
1019; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1020; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1021; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %eax
1022; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1023; X86-BMI1NOTBM-NEXT:    je .LBB15_2
1024; X86-BMI1NOTBM-NEXT:  # %bb.1:
1025; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1026; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1027; X86-BMI1NOTBM-NEXT:  .LBB15_2:
1028; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1029; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1030; X86-BMI1NOTBM-NEXT:    popl %esi
1031; X86-BMI1NOTBM-NEXT:    retl
1032;
1033; X86-BMI1BMI2-LABEL: bzhi64_b0:
1034; X86-BMI1BMI2:       # %bb.0:
1035; X86-BMI1BMI2-NEXT:    pushl %esi
1036; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1037; X86-BMI1BMI2-NEXT:    movl $-1, %eax
1038; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %esi
1039; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %eax
1040; X86-BMI1BMI2-NEXT:    testb $32, %cl
1041; X86-BMI1BMI2-NEXT:    je .LBB15_2
1042; X86-BMI1BMI2-NEXT:  # %bb.1:
1043; X86-BMI1BMI2-NEXT:    movl %esi, %eax
1044; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1045; X86-BMI1BMI2-NEXT:  .LBB15_2:
1046; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1047; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1048; X86-BMI1BMI2-NEXT:    popl %esi
1049; X86-BMI1BMI2-NEXT:    retl
1050;
1051; X64-NOBMI-LABEL: bzhi64_b0:
1052; X64-NOBMI:       # %bb.0:
1053; X64-NOBMI-NEXT:    movq %rsi, %rcx
1054; X64-NOBMI-NEXT:    movq $-1, %rax
1055; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1056; X64-NOBMI-NEXT:    shlq %cl, %rax
1057; X64-NOBMI-NEXT:    notq %rax
1058; X64-NOBMI-NEXT:    andq %rdi, %rax
1059; X64-NOBMI-NEXT:    retq
1060;
1061; X64-BMI1NOTBM-LABEL: bzhi64_b0:
1062; X64-BMI1NOTBM:       # %bb.0:
1063; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
1064; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
1065; X64-BMI1NOTBM-NEXT:    retq
1066;
1067; X64-BMI1BMI2-LABEL: bzhi64_b0:
1068; X64-BMI1BMI2:       # %bb.0:
1069; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
1070; X64-BMI1BMI2-NEXT:    retq
1071  %notmask = shl i64 -1, %numlowbits
1072  %mask = xor i64 %notmask, -1
1073  %masked = and i64 %mask, %val
1074  ret i64 %masked
1075}
1076
1077define i64 @bzhi64_b1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
1078; X86-NOBMI-LABEL: bzhi64_b1_indexzext:
1079; X86-NOBMI:       # %bb.0:
1080; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1081; X86-NOBMI-NEXT:    movl $-1, %edx
1082; X86-NOBMI-NEXT:    movl $-1, %eax
1083; X86-NOBMI-NEXT:    shll %cl, %eax
1084; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
1085; X86-NOBMI-NEXT:    testb $32, %cl
1086; X86-NOBMI-NEXT:    je .LBB16_2
1087; X86-NOBMI-NEXT:  # %bb.1:
1088; X86-NOBMI-NEXT:    movl %eax, %edx
1089; X86-NOBMI-NEXT:    xorl %eax, %eax
1090; X86-NOBMI-NEXT:  .LBB16_2:
1091; X86-NOBMI-NEXT:    notl %edx
1092; X86-NOBMI-NEXT:    notl %eax
1093; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
1094; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
1095; X86-NOBMI-NEXT:    retl
1096;
1097; X86-BMI1NOTBM-LABEL: bzhi64_b1_indexzext:
1098; X86-BMI1NOTBM:       # %bb.0:
1099; X86-BMI1NOTBM-NEXT:    pushl %esi
1100; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1101; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
1102; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1103; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1104; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %eax
1105; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1106; X86-BMI1NOTBM-NEXT:    je .LBB16_2
1107; X86-BMI1NOTBM-NEXT:  # %bb.1:
1108; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1109; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1110; X86-BMI1NOTBM-NEXT:  .LBB16_2:
1111; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1112; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1113; X86-BMI1NOTBM-NEXT:    popl %esi
1114; X86-BMI1NOTBM-NEXT:    retl
1115;
1116; X86-BMI1BMI2-LABEL: bzhi64_b1_indexzext:
1117; X86-BMI1BMI2:       # %bb.0:
1118; X86-BMI1BMI2-NEXT:    pushl %esi
1119; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1120; X86-BMI1BMI2-NEXT:    movl $-1, %eax
1121; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %esi
1122; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %eax
1123; X86-BMI1BMI2-NEXT:    testb $32, %cl
1124; X86-BMI1BMI2-NEXT:    je .LBB16_2
1125; X86-BMI1BMI2-NEXT:  # %bb.1:
1126; X86-BMI1BMI2-NEXT:    movl %esi, %eax
1127; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1128; X86-BMI1BMI2-NEXT:  .LBB16_2:
1129; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1130; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1131; X86-BMI1BMI2-NEXT:    popl %esi
1132; X86-BMI1BMI2-NEXT:    retl
1133;
1134; X64-NOBMI-LABEL: bzhi64_b1_indexzext:
1135; X64-NOBMI:       # %bb.0:
1136; X64-NOBMI-NEXT:    movl %esi, %ecx
1137; X64-NOBMI-NEXT:    movq $-1, %rax
1138; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1139; X64-NOBMI-NEXT:    shlq %cl, %rax
1140; X64-NOBMI-NEXT:    notq %rax
1141; X64-NOBMI-NEXT:    andq %rdi, %rax
1142; X64-NOBMI-NEXT:    retq
1143;
1144; X64-BMI1NOTBM-LABEL: bzhi64_b1_indexzext:
1145; X64-BMI1NOTBM:       # %bb.0:
1146; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
1147; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
1148; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
1149; X64-BMI1NOTBM-NEXT:    retq
1150;
1151; X64-BMI1BMI2-LABEL: bzhi64_b1_indexzext:
1152; X64-BMI1BMI2:       # %bb.0:
1153; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1154; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
1155; X64-BMI1BMI2-NEXT:    retq
1156  %conv = zext i8 %numlowbits to i64
1157  %notmask = shl i64 -1, %conv
1158  %mask = xor i64 %notmask, -1
1159  %masked = and i64 %mask, %val
1160  ret i64 %masked
1161}
1162
1163define i64 @bzhi64_b2_load(i64* %w, i64 %numlowbits) nounwind {
1164; X86-NOBMI-LABEL: bzhi64_b2_load:
1165; X86-NOBMI:       # %bb.0:
1166; X86-NOBMI-NEXT:    pushl %esi
1167; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1168; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1169; X86-NOBMI-NEXT:    movl $-1, %edx
1170; X86-NOBMI-NEXT:    movl $-1, %eax
1171; X86-NOBMI-NEXT:    shll %cl, %eax
1172; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
1173; X86-NOBMI-NEXT:    testb $32, %cl
1174; X86-NOBMI-NEXT:    je .LBB17_2
1175; X86-NOBMI-NEXT:  # %bb.1:
1176; X86-NOBMI-NEXT:    movl %eax, %edx
1177; X86-NOBMI-NEXT:    xorl %eax, %eax
1178; X86-NOBMI-NEXT:  .LBB17_2:
1179; X86-NOBMI-NEXT:    notl %edx
1180; X86-NOBMI-NEXT:    notl %eax
1181; X86-NOBMI-NEXT:    andl 4(%esi), %edx
1182; X86-NOBMI-NEXT:    andl (%esi), %eax
1183; X86-NOBMI-NEXT:    popl %esi
1184; X86-NOBMI-NEXT:    retl
1185;
1186; X86-BMI1NOTBM-LABEL: bzhi64_b2_load:
1187; X86-BMI1NOTBM:       # %bb.0:
1188; X86-BMI1NOTBM-NEXT:    pushl %esi
1189; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1190; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1191; X86-BMI1NOTBM-NEXT:    movl $-1, %edx
1192; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1193; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1194; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %edx
1195; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1196; X86-BMI1NOTBM-NEXT:    je .LBB17_2
1197; X86-BMI1NOTBM-NEXT:  # %bb.1:
1198; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
1199; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1200; X86-BMI1NOTBM-NEXT:  .LBB17_2:
1201; X86-BMI1NOTBM-NEXT:    andnl 4(%eax), %edx, %edx
1202; X86-BMI1NOTBM-NEXT:    andnl (%eax), %esi, %eax
1203; X86-BMI1NOTBM-NEXT:    popl %esi
1204; X86-BMI1NOTBM-NEXT:    retl
1205;
1206; X86-BMI1BMI2-LABEL: bzhi64_b2_load:
1207; X86-BMI1BMI2:       # %bb.0:
1208; X86-BMI1BMI2-NEXT:    pushl %esi
1209; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1210; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1211; X86-BMI1BMI2-NEXT:    movl $-1, %edx
1212; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edx, %esi
1213; X86-BMI1BMI2-NEXT:    shldl %cl, %edx, %edx
1214; X86-BMI1BMI2-NEXT:    testb $32, %cl
1215; X86-BMI1BMI2-NEXT:    je .LBB17_2
1216; X86-BMI1BMI2-NEXT:  # %bb.1:
1217; X86-BMI1BMI2-NEXT:    movl %esi, %edx
1218; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1219; X86-BMI1BMI2-NEXT:  .LBB17_2:
1220; X86-BMI1BMI2-NEXT:    andnl 4(%eax), %edx, %edx
1221; X86-BMI1BMI2-NEXT:    andnl (%eax), %esi, %eax
1222; X86-BMI1BMI2-NEXT:    popl %esi
1223; X86-BMI1BMI2-NEXT:    retl
1224;
1225; X64-NOBMI-LABEL: bzhi64_b2_load:
1226; X64-NOBMI:       # %bb.0:
1227; X64-NOBMI-NEXT:    movq %rsi, %rcx
1228; X64-NOBMI-NEXT:    movq $-1, %rax
1229; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1230; X64-NOBMI-NEXT:    shlq %cl, %rax
1231; X64-NOBMI-NEXT:    notq %rax
1232; X64-NOBMI-NEXT:    andq (%rdi), %rax
1233; X64-NOBMI-NEXT:    retq
1234;
1235; X64-BMI1NOTBM-LABEL: bzhi64_b2_load:
1236; X64-BMI1NOTBM:       # %bb.0:
1237; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
1238; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
1239; X64-BMI1NOTBM-NEXT:    retq
1240;
1241; X64-BMI1BMI2-LABEL: bzhi64_b2_load:
1242; X64-BMI1BMI2:       # %bb.0:
1243; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
1244; X64-BMI1BMI2-NEXT:    retq
1245  %val = load i64, i64* %w
1246  %notmask = shl i64 -1, %numlowbits
1247  %mask = xor i64 %notmask, -1
1248  %masked = and i64 %mask, %val
1249  ret i64 %masked
1250}
1251
1252define i64 @bzhi64_b3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind {
1253; X86-NOBMI-LABEL: bzhi64_b3_load_indexzext:
1254; X86-NOBMI:       # %bb.0:
1255; X86-NOBMI-NEXT:    pushl %esi
1256; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1257; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1258; X86-NOBMI-NEXT:    movl $-1, %edx
1259; X86-NOBMI-NEXT:    movl $-1, %eax
1260; X86-NOBMI-NEXT:    shll %cl, %eax
1261; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
1262; X86-NOBMI-NEXT:    testb $32, %cl
1263; X86-NOBMI-NEXT:    je .LBB18_2
1264; X86-NOBMI-NEXT:  # %bb.1:
1265; X86-NOBMI-NEXT:    movl %eax, %edx
1266; X86-NOBMI-NEXT:    xorl %eax, %eax
1267; X86-NOBMI-NEXT:  .LBB18_2:
1268; X86-NOBMI-NEXT:    notl %edx
1269; X86-NOBMI-NEXT:    notl %eax
1270; X86-NOBMI-NEXT:    andl 4(%esi), %edx
1271; X86-NOBMI-NEXT:    andl (%esi), %eax
1272; X86-NOBMI-NEXT:    popl %esi
1273; X86-NOBMI-NEXT:    retl
1274;
1275; X86-BMI1NOTBM-LABEL: bzhi64_b3_load_indexzext:
1276; X86-BMI1NOTBM:       # %bb.0:
1277; X86-BMI1NOTBM-NEXT:    pushl %esi
1278; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1279; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1280; X86-BMI1NOTBM-NEXT:    movl $-1, %edx
1281; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1282; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1283; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %edx
1284; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1285; X86-BMI1NOTBM-NEXT:    je .LBB18_2
1286; X86-BMI1NOTBM-NEXT:  # %bb.1:
1287; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
1288; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1289; X86-BMI1NOTBM-NEXT:  .LBB18_2:
1290; X86-BMI1NOTBM-NEXT:    andnl 4(%eax), %edx, %edx
1291; X86-BMI1NOTBM-NEXT:    andnl (%eax), %esi, %eax
1292; X86-BMI1NOTBM-NEXT:    popl %esi
1293; X86-BMI1NOTBM-NEXT:    retl
1294;
1295; X86-BMI1BMI2-LABEL: bzhi64_b3_load_indexzext:
1296; X86-BMI1BMI2:       # %bb.0:
1297; X86-BMI1BMI2-NEXT:    pushl %esi
1298; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1299; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1300; X86-BMI1BMI2-NEXT:    movl $-1, %edx
1301; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edx, %esi
1302; X86-BMI1BMI2-NEXT:    shldl %cl, %edx, %edx
1303; X86-BMI1BMI2-NEXT:    testb $32, %cl
1304; X86-BMI1BMI2-NEXT:    je .LBB18_2
1305; X86-BMI1BMI2-NEXT:  # %bb.1:
1306; X86-BMI1BMI2-NEXT:    movl %esi, %edx
1307; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1308; X86-BMI1BMI2-NEXT:  .LBB18_2:
1309; X86-BMI1BMI2-NEXT:    andnl 4(%eax), %edx, %edx
1310; X86-BMI1BMI2-NEXT:    andnl (%eax), %esi, %eax
1311; X86-BMI1BMI2-NEXT:    popl %esi
1312; X86-BMI1BMI2-NEXT:    retl
1313;
1314; X64-NOBMI-LABEL: bzhi64_b3_load_indexzext:
1315; X64-NOBMI:       # %bb.0:
1316; X64-NOBMI-NEXT:    movl %esi, %ecx
1317; X64-NOBMI-NEXT:    movq $-1, %rax
1318; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1319; X64-NOBMI-NEXT:    shlq %cl, %rax
1320; X64-NOBMI-NEXT:    notq %rax
1321; X64-NOBMI-NEXT:    andq (%rdi), %rax
1322; X64-NOBMI-NEXT:    retq
1323;
1324; X64-BMI1NOTBM-LABEL: bzhi64_b3_load_indexzext:
1325; X64-BMI1NOTBM:       # %bb.0:
1326; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
1327; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
1328; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
1329; X64-BMI1NOTBM-NEXT:    retq
1330;
1331; X64-BMI1BMI2-LABEL: bzhi64_b3_load_indexzext:
1332; X64-BMI1BMI2:       # %bb.0:
1333; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1334; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
1335; X64-BMI1BMI2-NEXT:    retq
1336  %val = load i64, i64* %w
1337  %conv = zext i8 %numlowbits to i64
1338  %notmask = shl i64 -1, %conv
1339  %mask = xor i64 %notmask, -1
1340  %masked = and i64 %mask, %val
1341  ret i64 %masked
1342}
1343
1344define i64 @bzhi64_b4_commutative(i64 %val, i64 %numlowbits) nounwind {
1345; X86-NOBMI-LABEL: bzhi64_b4_commutative:
1346; X86-NOBMI:       # %bb.0:
1347; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1348; X86-NOBMI-NEXT:    movl $-1, %edx
1349; X86-NOBMI-NEXT:    movl $-1, %eax
1350; X86-NOBMI-NEXT:    shll %cl, %eax
1351; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
1352; X86-NOBMI-NEXT:    testb $32, %cl
1353; X86-NOBMI-NEXT:    je .LBB19_2
1354; X86-NOBMI-NEXT:  # %bb.1:
1355; X86-NOBMI-NEXT:    movl %eax, %edx
1356; X86-NOBMI-NEXT:    xorl %eax, %eax
1357; X86-NOBMI-NEXT:  .LBB19_2:
1358; X86-NOBMI-NEXT:    notl %edx
1359; X86-NOBMI-NEXT:    notl %eax
1360; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
1361; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
1362; X86-NOBMI-NEXT:    retl
1363;
1364; X86-BMI1NOTBM-LABEL: bzhi64_b4_commutative:
1365; X86-BMI1NOTBM:       # %bb.0:
1366; X86-BMI1NOTBM-NEXT:    pushl %esi
1367; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1368; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
1369; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1370; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1371; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %eax
1372; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1373; X86-BMI1NOTBM-NEXT:    je .LBB19_2
1374; X86-BMI1NOTBM-NEXT:  # %bb.1:
1375; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1376; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1377; X86-BMI1NOTBM-NEXT:  .LBB19_2:
1378; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1379; X86-BMI1NOTBM-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1380; X86-BMI1NOTBM-NEXT:    popl %esi
1381; X86-BMI1NOTBM-NEXT:    retl
1382;
1383; X86-BMI1BMI2-LABEL: bzhi64_b4_commutative:
1384; X86-BMI1BMI2:       # %bb.0:
1385; X86-BMI1BMI2-NEXT:    pushl %esi
1386; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1387; X86-BMI1BMI2-NEXT:    movl $-1, %eax
1388; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %esi
1389; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %eax
1390; X86-BMI1BMI2-NEXT:    testb $32, %cl
1391; X86-BMI1BMI2-NEXT:    je .LBB19_2
1392; X86-BMI1BMI2-NEXT:  # %bb.1:
1393; X86-BMI1BMI2-NEXT:    movl %esi, %eax
1394; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1395; X86-BMI1BMI2-NEXT:  .LBB19_2:
1396; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %edx
1397; X86-BMI1BMI2-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %eax
1398; X86-BMI1BMI2-NEXT:    popl %esi
1399; X86-BMI1BMI2-NEXT:    retl
1400;
1401; X64-NOBMI-LABEL: bzhi64_b4_commutative:
1402; X64-NOBMI:       # %bb.0:
1403; X64-NOBMI-NEXT:    movq %rsi, %rcx
1404; X64-NOBMI-NEXT:    movq $-1, %rax
1405; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1406; X64-NOBMI-NEXT:    shlq %cl, %rax
1407; X64-NOBMI-NEXT:    notq %rax
1408; X64-NOBMI-NEXT:    andq %rdi, %rax
1409; X64-NOBMI-NEXT:    retq
1410;
1411; X64-BMI1NOTBM-LABEL: bzhi64_b4_commutative:
1412; X64-BMI1NOTBM:       # %bb.0:
1413; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
1414; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
1415; X64-BMI1NOTBM-NEXT:    retq
1416;
1417; X64-BMI1BMI2-LABEL: bzhi64_b4_commutative:
1418; X64-BMI1BMI2:       # %bb.0:
1419; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
1420; X64-BMI1BMI2-NEXT:    retq
1421  %notmask = shl i64 -1, %numlowbits
1422  %mask = xor i64 %notmask, -1
1423  %masked = and i64 %val, %mask ; swapped order
1424  ret i64 %masked
1425}
1426
1427; ---------------------------------------------------------------------------- ;
1428; Pattern c. 32-bit
1429; ---------------------------------------------------------------------------- ;
1430
1431declare void @use32(i32)
1432
1433define i32 @bzhi32_c0(i32 %val, i32 %numlowbits) nounwind {
1434; X86-NOBMI-LABEL: bzhi32_c0:
1435; X86-NOBMI:       # %bb.0:
1436; X86-NOBMI-NEXT:    pushl %esi
1437; X86-NOBMI-NEXT:    subl $8, %esp
1438; X86-NOBMI-NEXT:    xorl %ecx, %ecx
1439; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
1440; X86-NOBMI-NEXT:    movl $-1, %esi
1441; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1442; X86-NOBMI-NEXT:    shrl %cl, %esi
1443; X86-NOBMI-NEXT:    movl %esi, (%esp)
1444; X86-NOBMI-NEXT:    calll use32
1445; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
1446; X86-NOBMI-NEXT:    movl %esi, %eax
1447; X86-NOBMI-NEXT:    addl $8, %esp
1448; X86-NOBMI-NEXT:    popl %esi
1449; X86-NOBMI-NEXT:    retl
1450;
1451; X86-BMI1NOTBM-LABEL: bzhi32_c0:
1452; X86-BMI1NOTBM:       # %bb.0:
1453; X86-BMI1NOTBM-NEXT:    pushl %esi
1454; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1455; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
1456; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
1457; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1458; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1459; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
1460; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
1461; X86-BMI1NOTBM-NEXT:    calll use32
1462; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
1463; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1464; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1465; X86-BMI1NOTBM-NEXT:    popl %esi
1466; X86-BMI1NOTBM-NEXT:    retl
1467;
1468; X86-BMI1BMI2-LABEL: bzhi32_c0:
1469; X86-BMI1BMI2:       # %bb.0:
1470; X86-BMI1BMI2-NEXT:    pushl %ebx
1471; X86-BMI1BMI2-NEXT:    subl $8, %esp
1472; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1473; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
1474; X86-BMI1BMI2-NEXT:    negb %al
1475; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
1476; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
1477; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
1478; X86-BMI1BMI2-NEXT:    calll use32
1479; X86-BMI1BMI2-NEXT:    bzhil %ebx, {{[0-9]+}}(%esp), %eax
1480; X86-BMI1BMI2-NEXT:    addl $8, %esp
1481; X86-BMI1BMI2-NEXT:    popl %ebx
1482; X86-BMI1BMI2-NEXT:    retl
1483;
1484; X64-NOBMI-LABEL: bzhi32_c0:
1485; X64-NOBMI:       # %bb.0:
1486; X64-NOBMI-NEXT:    pushq %rbp
1487; X64-NOBMI-NEXT:    pushq %rbx
1488; X64-NOBMI-NEXT:    pushq %rax
1489; X64-NOBMI-NEXT:    movl %esi, %ecx
1490; X64-NOBMI-NEXT:    movl %edi, %ebx
1491; X64-NOBMI-NEXT:    negb %cl
1492; X64-NOBMI-NEXT:    movl $-1, %ebp
1493; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1494; X64-NOBMI-NEXT:    shrl %cl, %ebp
1495; X64-NOBMI-NEXT:    movl %ebp, %edi
1496; X64-NOBMI-NEXT:    callq use32
1497; X64-NOBMI-NEXT:    andl %ebx, %ebp
1498; X64-NOBMI-NEXT:    movl %ebp, %eax
1499; X64-NOBMI-NEXT:    addq $8, %rsp
1500; X64-NOBMI-NEXT:    popq %rbx
1501; X64-NOBMI-NEXT:    popq %rbp
1502; X64-NOBMI-NEXT:    retq
1503;
1504; X64-BMI1NOTBM-LABEL: bzhi32_c0:
1505; X64-BMI1NOTBM:       # %bb.0:
1506; X64-BMI1NOTBM-NEXT:    pushq %rbp
1507; X64-BMI1NOTBM-NEXT:    pushq %rbx
1508; X64-BMI1NOTBM-NEXT:    pushq %rax
1509; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
1510; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
1511; X64-BMI1NOTBM-NEXT:    negb %cl
1512; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
1513; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1514; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
1515; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
1516; X64-BMI1NOTBM-NEXT:    callq use32
1517; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
1518; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
1519; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
1520; X64-BMI1NOTBM-NEXT:    popq %rbx
1521; X64-BMI1NOTBM-NEXT:    popq %rbp
1522; X64-BMI1NOTBM-NEXT:    retq
1523;
1524; X64-BMI1BMI2-LABEL: bzhi32_c0:
1525; X64-BMI1BMI2:       # %bb.0:
1526; X64-BMI1BMI2-NEXT:    pushq %rbp
1527; X64-BMI1BMI2-NEXT:    pushq %rbx
1528; X64-BMI1BMI2-NEXT:    pushq %rax
1529; X64-BMI1BMI2-NEXT:    movl %esi, %ebx
1530; X64-BMI1BMI2-NEXT:    movl %edi, %ebp
1531; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
1532; X64-BMI1BMI2-NEXT:    negb %al
1533; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
1534; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
1535; X64-BMI1BMI2-NEXT:    callq use32
1536; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
1537; X64-BMI1BMI2-NEXT:    addq $8, %rsp
1538; X64-BMI1BMI2-NEXT:    popq %rbx
1539; X64-BMI1BMI2-NEXT:    popq %rbp
1540; X64-BMI1BMI2-NEXT:    retq
1541  %numhighbits = sub i32 32, %numlowbits
1542  %mask = lshr i32 -1, %numhighbits
1543  call void @use32(i32 %mask)
1544  %masked = and i32 %mask, %val
1545  ret i32 %masked
1546}
1547
1548define i32 @bzhi32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind {
1549; X86-NOBMI-LABEL: bzhi32_c1_indexzext:
1550; X86-NOBMI:       # %bb.0:
1551; X86-NOBMI-NEXT:    pushl %esi
1552; X86-NOBMI-NEXT:    subl $8, %esp
1553; X86-NOBMI-NEXT:    xorl %ecx, %ecx
1554; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
1555; X86-NOBMI-NEXT:    movl $-1, %esi
1556; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1557; X86-NOBMI-NEXT:    shrl %cl, %esi
1558; X86-NOBMI-NEXT:    movl %esi, (%esp)
1559; X86-NOBMI-NEXT:    calll use32
1560; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
1561; X86-NOBMI-NEXT:    movl %esi, %eax
1562; X86-NOBMI-NEXT:    addl $8, %esp
1563; X86-NOBMI-NEXT:    popl %esi
1564; X86-NOBMI-NEXT:    retl
1565;
1566; X86-BMI1NOTBM-LABEL: bzhi32_c1_indexzext:
1567; X86-BMI1NOTBM:       # %bb.0:
1568; X86-BMI1NOTBM-NEXT:    pushl %esi
1569; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1570; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
1571; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
1572; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1573; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1574; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
1575; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
1576; X86-BMI1NOTBM-NEXT:    calll use32
1577; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
1578; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1579; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1580; X86-BMI1NOTBM-NEXT:    popl %esi
1581; X86-BMI1NOTBM-NEXT:    retl
1582;
1583; X86-BMI1BMI2-LABEL: bzhi32_c1_indexzext:
1584; X86-BMI1BMI2:       # %bb.0:
1585; X86-BMI1BMI2-NEXT:    pushl %ebx
1586; X86-BMI1BMI2-NEXT:    subl $8, %esp
1587; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1588; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
1589; X86-BMI1BMI2-NEXT:    negb %al
1590; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
1591; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
1592; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
1593; X86-BMI1BMI2-NEXT:    calll use32
1594; X86-BMI1BMI2-NEXT:    bzhil %ebx, {{[0-9]+}}(%esp), %eax
1595; X86-BMI1BMI2-NEXT:    addl $8, %esp
1596; X86-BMI1BMI2-NEXT:    popl %ebx
1597; X86-BMI1BMI2-NEXT:    retl
1598;
1599; X64-NOBMI-LABEL: bzhi32_c1_indexzext:
1600; X64-NOBMI:       # %bb.0:
1601; X64-NOBMI-NEXT:    pushq %rbp
1602; X64-NOBMI-NEXT:    pushq %rbx
1603; X64-NOBMI-NEXT:    pushq %rax
1604; X64-NOBMI-NEXT:    movl %esi, %ecx
1605; X64-NOBMI-NEXT:    movl %edi, %ebx
1606; X64-NOBMI-NEXT:    negb %cl
1607; X64-NOBMI-NEXT:    movl $-1, %ebp
1608; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1609; X64-NOBMI-NEXT:    shrl %cl, %ebp
1610; X64-NOBMI-NEXT:    movl %ebp, %edi
1611; X64-NOBMI-NEXT:    callq use32
1612; X64-NOBMI-NEXT:    andl %ebx, %ebp
1613; X64-NOBMI-NEXT:    movl %ebp, %eax
1614; X64-NOBMI-NEXT:    addq $8, %rsp
1615; X64-NOBMI-NEXT:    popq %rbx
1616; X64-NOBMI-NEXT:    popq %rbp
1617; X64-NOBMI-NEXT:    retq
1618;
1619; X64-BMI1NOTBM-LABEL: bzhi32_c1_indexzext:
1620; X64-BMI1NOTBM:       # %bb.0:
1621; X64-BMI1NOTBM-NEXT:    pushq %rbp
1622; X64-BMI1NOTBM-NEXT:    pushq %rbx
1623; X64-BMI1NOTBM-NEXT:    pushq %rax
1624; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
1625; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
1626; X64-BMI1NOTBM-NEXT:    negb %cl
1627; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
1628; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1629; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
1630; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
1631; X64-BMI1NOTBM-NEXT:    callq use32
1632; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
1633; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
1634; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
1635; X64-BMI1NOTBM-NEXT:    popq %rbx
1636; X64-BMI1NOTBM-NEXT:    popq %rbp
1637; X64-BMI1NOTBM-NEXT:    retq
1638;
1639; X64-BMI1BMI2-LABEL: bzhi32_c1_indexzext:
1640; X64-BMI1BMI2:       # %bb.0:
1641; X64-BMI1BMI2-NEXT:    pushq %rbp
1642; X64-BMI1BMI2-NEXT:    pushq %rbx
1643; X64-BMI1BMI2-NEXT:    pushq %rax
1644; X64-BMI1BMI2-NEXT:    movl %esi, %ebx
1645; X64-BMI1BMI2-NEXT:    movl %edi, %ebp
1646; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
1647; X64-BMI1BMI2-NEXT:    negb %al
1648; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
1649; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
1650; X64-BMI1BMI2-NEXT:    callq use32
1651; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
1652; X64-BMI1BMI2-NEXT:    addq $8, %rsp
1653; X64-BMI1BMI2-NEXT:    popq %rbx
1654; X64-BMI1BMI2-NEXT:    popq %rbp
1655; X64-BMI1BMI2-NEXT:    retq
1656  %numhighbits = sub i8 32, %numlowbits
1657  %sh_prom = zext i8 %numhighbits to i32
1658  %mask = lshr i32 -1, %sh_prom
1659  call void @use32(i32 %mask)
1660  %masked = and i32 %mask, %val
1661  ret i32 %masked
1662}
1663
1664define i32 @bzhi32_c2_load(i32* %w, i32 %numlowbits) nounwind {
1665; X86-NOBMI-LABEL: bzhi32_c2_load:
1666; X86-NOBMI:       # %bb.0:
1667; X86-NOBMI-NEXT:    pushl %esi
1668; X86-NOBMI-NEXT:    subl $8, %esp
1669; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1670; X86-NOBMI-NEXT:    xorl %ecx, %ecx
1671; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
1672; X86-NOBMI-NEXT:    movl $-1, %edx
1673; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1674; X86-NOBMI-NEXT:    shrl %cl, %edx
1675; X86-NOBMI-NEXT:    movl (%eax), %esi
1676; X86-NOBMI-NEXT:    andl %edx, %esi
1677; X86-NOBMI-NEXT:    movl %edx, (%esp)
1678; X86-NOBMI-NEXT:    calll use32
1679; X86-NOBMI-NEXT:    movl %esi, %eax
1680; X86-NOBMI-NEXT:    addl $8, %esp
1681; X86-NOBMI-NEXT:    popl %esi
1682; X86-NOBMI-NEXT:    retl
1683;
1684; X86-BMI1NOTBM-LABEL: bzhi32_c2_load:
1685; X86-BMI1NOTBM:       # %bb.0:
1686; X86-BMI1NOTBM-NEXT:    pushl %esi
1687; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1688; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1689; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
1690; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
1691; X86-BMI1NOTBM-NEXT:    movl $-1, %edx
1692; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1693; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
1694; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
1695; X86-BMI1NOTBM-NEXT:    andl %edx, %esi
1696; X86-BMI1NOTBM-NEXT:    movl %edx, (%esp)
1697; X86-BMI1NOTBM-NEXT:    calll use32
1698; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1699; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1700; X86-BMI1NOTBM-NEXT:    popl %esi
1701; X86-BMI1NOTBM-NEXT:    retl
1702;
1703; X86-BMI1BMI2-LABEL: bzhi32_c2_load:
1704; X86-BMI1BMI2:       # %bb.0:
1705; X86-BMI1BMI2-NEXT:    pushl %esi
1706; X86-BMI1BMI2-NEXT:    subl $8, %esp
1707; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1708; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1709; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %esi
1710; X86-BMI1BMI2-NEXT:    # kill: def $cl killed $cl killed $ecx def $ecx
1711; X86-BMI1BMI2-NEXT:    negb %cl
1712; X86-BMI1BMI2-NEXT:    movl $-1, %eax
1713; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %eax
1714; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
1715; X86-BMI1BMI2-NEXT:    calll use32
1716; X86-BMI1BMI2-NEXT:    movl %esi, %eax
1717; X86-BMI1BMI2-NEXT:    addl $8, %esp
1718; X86-BMI1BMI2-NEXT:    popl %esi
1719; X86-BMI1BMI2-NEXT:    retl
1720;
1721; X64-NOBMI-LABEL: bzhi32_c2_load:
1722; X64-NOBMI:       # %bb.0:
1723; X64-NOBMI-NEXT:    pushq %rbx
1724; X64-NOBMI-NEXT:    movl %esi, %ecx
1725; X64-NOBMI-NEXT:    negb %cl
1726; X64-NOBMI-NEXT:    movl $-1, %eax
1727; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1728; X64-NOBMI-NEXT:    shrl %cl, %eax
1729; X64-NOBMI-NEXT:    movl (%rdi), %ebx
1730; X64-NOBMI-NEXT:    andl %eax, %ebx
1731; X64-NOBMI-NEXT:    movl %eax, %edi
1732; X64-NOBMI-NEXT:    callq use32
1733; X64-NOBMI-NEXT:    movl %ebx, %eax
1734; X64-NOBMI-NEXT:    popq %rbx
1735; X64-NOBMI-NEXT:    retq
1736;
1737; X64-BMI1NOTBM-LABEL: bzhi32_c2_load:
1738; X64-BMI1NOTBM:       # %bb.0:
1739; X64-BMI1NOTBM-NEXT:    pushq %rbx
1740; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
1741; X64-BMI1NOTBM-NEXT:    negb %cl
1742; X64-BMI1NOTBM-NEXT:    movl $-1, %eax
1743; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1744; X64-BMI1NOTBM-NEXT:    shrl %cl, %eax
1745; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebx
1746; X64-BMI1NOTBM-NEXT:    andl %eax, %ebx
1747; X64-BMI1NOTBM-NEXT:    movl %eax, %edi
1748; X64-BMI1NOTBM-NEXT:    callq use32
1749; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
1750; X64-BMI1NOTBM-NEXT:    popq %rbx
1751; X64-BMI1NOTBM-NEXT:    retq
1752;
1753; X64-BMI1BMI2-LABEL: bzhi32_c2_load:
1754; X64-BMI1BMI2:       # %bb.0:
1755; X64-BMI1BMI2-NEXT:    pushq %rbx
1756; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %ebx
1757; X64-BMI1BMI2-NEXT:    # kill: def $sil killed $sil killed $esi def $esi
1758; X64-BMI1BMI2-NEXT:    negb %sil
1759; X64-BMI1BMI2-NEXT:    movl $-1, %eax
1760; X64-BMI1BMI2-NEXT:    shrxl %esi, %eax, %edi
1761; X64-BMI1BMI2-NEXT:    callq use32
1762; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
1763; X64-BMI1BMI2-NEXT:    popq %rbx
1764; X64-BMI1BMI2-NEXT:    retq
1765  %val = load i32, i32* %w
1766  %numhighbits = sub i32 32, %numlowbits
1767  %mask = lshr i32 -1, %numhighbits
1768  call void @use32(i32 %mask)
1769  %masked = and i32 %mask, %val
1770  ret i32 %masked
1771}
1772
1773define i32 @bzhi32_c3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
1774; X86-NOBMI-LABEL: bzhi32_c3_load_indexzext:
1775; X86-NOBMI:       # %bb.0:
1776; X86-NOBMI-NEXT:    pushl %esi
1777; X86-NOBMI-NEXT:    subl $8, %esp
1778; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1779; X86-NOBMI-NEXT:    xorl %ecx, %ecx
1780; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
1781; X86-NOBMI-NEXT:    movl $-1, %edx
1782; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1783; X86-NOBMI-NEXT:    shrl %cl, %edx
1784; X86-NOBMI-NEXT:    movl (%eax), %esi
1785; X86-NOBMI-NEXT:    andl %edx, %esi
1786; X86-NOBMI-NEXT:    movl %edx, (%esp)
1787; X86-NOBMI-NEXT:    calll use32
1788; X86-NOBMI-NEXT:    movl %esi, %eax
1789; X86-NOBMI-NEXT:    addl $8, %esp
1790; X86-NOBMI-NEXT:    popl %esi
1791; X86-NOBMI-NEXT:    retl
1792;
1793; X86-BMI1NOTBM-LABEL: bzhi32_c3_load_indexzext:
1794; X86-BMI1NOTBM:       # %bb.0:
1795; X86-BMI1NOTBM-NEXT:    pushl %esi
1796; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1797; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1798; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
1799; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
1800; X86-BMI1NOTBM-NEXT:    movl $-1, %edx
1801; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1802; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
1803; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
1804; X86-BMI1NOTBM-NEXT:    andl %edx, %esi
1805; X86-BMI1NOTBM-NEXT:    movl %edx, (%esp)
1806; X86-BMI1NOTBM-NEXT:    calll use32
1807; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1808; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1809; X86-BMI1NOTBM-NEXT:    popl %esi
1810; X86-BMI1NOTBM-NEXT:    retl
1811;
1812; X86-BMI1BMI2-LABEL: bzhi32_c3_load_indexzext:
1813; X86-BMI1BMI2:       # %bb.0:
1814; X86-BMI1BMI2-NEXT:    pushl %esi
1815; X86-BMI1BMI2-NEXT:    subl $8, %esp
1816; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1817; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1818; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %esi
1819; X86-BMI1BMI2-NEXT:    # kill: def $cl killed $cl killed $ecx def $ecx
1820; X86-BMI1BMI2-NEXT:    negb %cl
1821; X86-BMI1BMI2-NEXT:    movl $-1, %eax
1822; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %eax
1823; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
1824; X86-BMI1BMI2-NEXT:    calll use32
1825; X86-BMI1BMI2-NEXT:    movl %esi, %eax
1826; X86-BMI1BMI2-NEXT:    addl $8, %esp
1827; X86-BMI1BMI2-NEXT:    popl %esi
1828; X86-BMI1BMI2-NEXT:    retl
1829;
1830; X64-NOBMI-LABEL: bzhi32_c3_load_indexzext:
1831; X64-NOBMI:       # %bb.0:
1832; X64-NOBMI-NEXT:    pushq %rbx
1833; X64-NOBMI-NEXT:    movl %esi, %ecx
1834; X64-NOBMI-NEXT:    negb %cl
1835; X64-NOBMI-NEXT:    movl $-1, %eax
1836; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1837; X64-NOBMI-NEXT:    shrl %cl, %eax
1838; X64-NOBMI-NEXT:    movl (%rdi), %ebx
1839; X64-NOBMI-NEXT:    andl %eax, %ebx
1840; X64-NOBMI-NEXT:    movl %eax, %edi
1841; X64-NOBMI-NEXT:    callq use32
1842; X64-NOBMI-NEXT:    movl %ebx, %eax
1843; X64-NOBMI-NEXT:    popq %rbx
1844; X64-NOBMI-NEXT:    retq
1845;
1846; X64-BMI1NOTBM-LABEL: bzhi32_c3_load_indexzext:
1847; X64-BMI1NOTBM:       # %bb.0:
1848; X64-BMI1NOTBM-NEXT:    pushq %rbx
1849; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
1850; X64-BMI1NOTBM-NEXT:    negb %cl
1851; X64-BMI1NOTBM-NEXT:    movl $-1, %eax
1852; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1853; X64-BMI1NOTBM-NEXT:    shrl %cl, %eax
1854; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebx
1855; X64-BMI1NOTBM-NEXT:    andl %eax, %ebx
1856; X64-BMI1NOTBM-NEXT:    movl %eax, %edi
1857; X64-BMI1NOTBM-NEXT:    callq use32
1858; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
1859; X64-BMI1NOTBM-NEXT:    popq %rbx
1860; X64-BMI1NOTBM-NEXT:    retq
1861;
1862; X64-BMI1BMI2-LABEL: bzhi32_c3_load_indexzext:
1863; X64-BMI1BMI2:       # %bb.0:
1864; X64-BMI1BMI2-NEXT:    pushq %rbx
1865; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %ebx
1866; X64-BMI1BMI2-NEXT:    # kill: def $sil killed $sil killed $esi def $esi
1867; X64-BMI1BMI2-NEXT:    negb %sil
1868; X64-BMI1BMI2-NEXT:    movl $-1, %eax
1869; X64-BMI1BMI2-NEXT:    shrxl %esi, %eax, %edi
1870; X64-BMI1BMI2-NEXT:    callq use32
1871; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
1872; X64-BMI1BMI2-NEXT:    popq %rbx
1873; X64-BMI1BMI2-NEXT:    retq
1874  %val = load i32, i32* %w
1875  %numhighbits = sub i8 32, %numlowbits
1876  %sh_prom = zext i8 %numhighbits to i32
1877  %mask = lshr i32 -1, %sh_prom
1878  call void @use32(i32 %mask)
1879  %masked = and i32 %mask, %val
1880  ret i32 %masked
1881}
1882
1883define i32 @bzhi32_c4_commutative(i32 %val, i32 %numlowbits) nounwind {
1884; X86-NOBMI-LABEL: bzhi32_c4_commutative:
1885; X86-NOBMI:       # %bb.0:
1886; X86-NOBMI-NEXT:    pushl %esi
1887; X86-NOBMI-NEXT:    subl $8, %esp
1888; X86-NOBMI-NEXT:    xorl %ecx, %ecx
1889; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
1890; X86-NOBMI-NEXT:    movl $-1, %esi
1891; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1892; X86-NOBMI-NEXT:    shrl %cl, %esi
1893; X86-NOBMI-NEXT:    movl %esi, (%esp)
1894; X86-NOBMI-NEXT:    calll use32
1895; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
1896; X86-NOBMI-NEXT:    movl %esi, %eax
1897; X86-NOBMI-NEXT:    addl $8, %esp
1898; X86-NOBMI-NEXT:    popl %esi
1899; X86-NOBMI-NEXT:    retl
1900;
1901; X86-BMI1NOTBM-LABEL: bzhi32_c4_commutative:
1902; X86-BMI1NOTBM:       # %bb.0:
1903; X86-BMI1NOTBM-NEXT:    pushl %esi
1904; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1905; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
1906; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
1907; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
1908; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1909; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
1910; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
1911; X86-BMI1NOTBM-NEXT:    calll use32
1912; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
1913; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1914; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1915; X86-BMI1NOTBM-NEXT:    popl %esi
1916; X86-BMI1NOTBM-NEXT:    retl
1917;
1918; X86-BMI1BMI2-LABEL: bzhi32_c4_commutative:
1919; X86-BMI1BMI2:       # %bb.0:
1920; X86-BMI1BMI2-NEXT:    pushl %ebx
1921; X86-BMI1BMI2-NEXT:    subl $8, %esp
1922; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1923; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
1924; X86-BMI1BMI2-NEXT:    negb %al
1925; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
1926; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
1927; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
1928; X86-BMI1BMI2-NEXT:    calll use32
1929; X86-BMI1BMI2-NEXT:    bzhil %ebx, {{[0-9]+}}(%esp), %eax
1930; X86-BMI1BMI2-NEXT:    addl $8, %esp
1931; X86-BMI1BMI2-NEXT:    popl %ebx
1932; X86-BMI1BMI2-NEXT:    retl
1933;
1934; X64-NOBMI-LABEL: bzhi32_c4_commutative:
1935; X64-NOBMI:       # %bb.0:
1936; X64-NOBMI-NEXT:    pushq %rbp
1937; X64-NOBMI-NEXT:    pushq %rbx
1938; X64-NOBMI-NEXT:    pushq %rax
1939; X64-NOBMI-NEXT:    movl %esi, %ecx
1940; X64-NOBMI-NEXT:    movl %edi, %ebx
1941; X64-NOBMI-NEXT:    negb %cl
1942; X64-NOBMI-NEXT:    movl $-1, %ebp
1943; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1944; X64-NOBMI-NEXT:    shrl %cl, %ebp
1945; X64-NOBMI-NEXT:    movl %ebp, %edi
1946; X64-NOBMI-NEXT:    callq use32
1947; X64-NOBMI-NEXT:    andl %ebx, %ebp
1948; X64-NOBMI-NEXT:    movl %ebp, %eax
1949; X64-NOBMI-NEXT:    addq $8, %rsp
1950; X64-NOBMI-NEXT:    popq %rbx
1951; X64-NOBMI-NEXT:    popq %rbp
1952; X64-NOBMI-NEXT:    retq
1953;
1954; X64-BMI1NOTBM-LABEL: bzhi32_c4_commutative:
1955; X64-BMI1NOTBM:       # %bb.0:
1956; X64-BMI1NOTBM-NEXT:    pushq %rbp
1957; X64-BMI1NOTBM-NEXT:    pushq %rbx
1958; X64-BMI1NOTBM-NEXT:    pushq %rax
1959; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
1960; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
1961; X64-BMI1NOTBM-NEXT:    negb %cl
1962; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
1963; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
1964; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
1965; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
1966; X64-BMI1NOTBM-NEXT:    callq use32
1967; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
1968; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
1969; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
1970; X64-BMI1NOTBM-NEXT:    popq %rbx
1971; X64-BMI1NOTBM-NEXT:    popq %rbp
1972; X64-BMI1NOTBM-NEXT:    retq
1973;
1974; X64-BMI1BMI2-LABEL: bzhi32_c4_commutative:
1975; X64-BMI1BMI2:       # %bb.0:
1976; X64-BMI1BMI2-NEXT:    pushq %rbp
1977; X64-BMI1BMI2-NEXT:    pushq %rbx
1978; X64-BMI1BMI2-NEXT:    pushq %rax
1979; X64-BMI1BMI2-NEXT:    movl %esi, %ebx
1980; X64-BMI1BMI2-NEXT:    movl %edi, %ebp
1981; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
1982; X64-BMI1BMI2-NEXT:    negb %al
1983; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
1984; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
1985; X64-BMI1BMI2-NEXT:    callq use32
1986; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
1987; X64-BMI1BMI2-NEXT:    addq $8, %rsp
1988; X64-BMI1BMI2-NEXT:    popq %rbx
1989; X64-BMI1BMI2-NEXT:    popq %rbp
1990; X64-BMI1BMI2-NEXT:    retq
1991  %numhighbits = sub i32 32, %numlowbits
1992  %mask = lshr i32 -1, %numhighbits
1993  call void @use32(i32 %mask)
1994  %masked = and i32 %val, %mask ; swapped order
1995  ret i32 %masked
1996}
1997
1998; 64-bit
1999
2000declare void @use64(i64)
2001
2002define i64 @bzhi64_c0(i64 %val, i64 %numlowbits) nounwind {
2003; X86-NOBMI-LABEL: bzhi64_c0:
2004; X86-NOBMI:       # %bb.0:
2005; X86-NOBMI-NEXT:    pushl %edi
2006; X86-NOBMI-NEXT:    pushl %esi
2007; X86-NOBMI-NEXT:    pushl %eax
2008; X86-NOBMI-NEXT:    movb $64, %cl
2009; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2010; X86-NOBMI-NEXT:    movl $-1, %esi
2011; X86-NOBMI-NEXT:    movl $-1, %edi
2012; X86-NOBMI-NEXT:    shrl %cl, %edi
2013; X86-NOBMI-NEXT:    shrdl %cl, %esi, %esi
2014; X86-NOBMI-NEXT:    testb $32, %cl
2015; X86-NOBMI-NEXT:    je .LBB25_2
2016; X86-NOBMI-NEXT:  # %bb.1:
2017; X86-NOBMI-NEXT:    movl %edi, %esi
2018; X86-NOBMI-NEXT:    xorl %edi, %edi
2019; X86-NOBMI-NEXT:  .LBB25_2:
2020; X86-NOBMI-NEXT:    subl $8, %esp
2021; X86-NOBMI-NEXT:    pushl %edi
2022; X86-NOBMI-NEXT:    pushl %esi
2023; X86-NOBMI-NEXT:    calll use64
2024; X86-NOBMI-NEXT:    addl $16, %esp
2025; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
2026; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edi
2027; X86-NOBMI-NEXT:    movl %esi, %eax
2028; X86-NOBMI-NEXT:    movl %edi, %edx
2029; X86-NOBMI-NEXT:    addl $4, %esp
2030; X86-NOBMI-NEXT:    popl %esi
2031; X86-NOBMI-NEXT:    popl %edi
2032; X86-NOBMI-NEXT:    retl
2033;
2034; X86-BMI1NOTBM-LABEL: bzhi64_c0:
2035; X86-BMI1NOTBM:       # %bb.0:
2036; X86-BMI1NOTBM-NEXT:    pushl %edi
2037; X86-BMI1NOTBM-NEXT:    pushl %esi
2038; X86-BMI1NOTBM-NEXT:    pushl %eax
2039; X86-BMI1NOTBM-NEXT:    movb $64, %cl
2040; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
2041; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
2042; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2043; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
2044; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %esi
2045; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2046; X86-BMI1NOTBM-NEXT:    je .LBB25_2
2047; X86-BMI1NOTBM-NEXT:  # %bb.1:
2048; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
2049; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
2050; X86-BMI1NOTBM-NEXT:  .LBB25_2:
2051; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2052; X86-BMI1NOTBM-NEXT:    pushl %edi
2053; X86-BMI1NOTBM-NEXT:    pushl %esi
2054; X86-BMI1NOTBM-NEXT:    calll use64
2055; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2056; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
2057; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edi
2058; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2059; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2060; X86-BMI1NOTBM-NEXT:    addl $4, %esp
2061; X86-BMI1NOTBM-NEXT:    popl %esi
2062; X86-BMI1NOTBM-NEXT:    popl %edi
2063; X86-BMI1NOTBM-NEXT:    retl
2064;
2065; X86-BMI1BMI2-LABEL: bzhi64_c0:
2066; X86-BMI1BMI2:       # %bb.0:
2067; X86-BMI1BMI2-NEXT:    pushl %edi
2068; X86-BMI1BMI2-NEXT:    pushl %esi
2069; X86-BMI1BMI2-NEXT:    pushl %eax
2070; X86-BMI1BMI2-NEXT:    movb $64, %cl
2071; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
2072; X86-BMI1BMI2-NEXT:    movl $-1, %esi
2073; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edi
2074; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %esi
2075; X86-BMI1BMI2-NEXT:    testb $32, %cl
2076; X86-BMI1BMI2-NEXT:    je .LBB25_2
2077; X86-BMI1BMI2-NEXT:  # %bb.1:
2078; X86-BMI1BMI2-NEXT:    movl %edi, %esi
2079; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
2080; X86-BMI1BMI2-NEXT:  .LBB25_2:
2081; X86-BMI1BMI2-NEXT:    subl $8, %esp
2082; X86-BMI1BMI2-NEXT:    pushl %edi
2083; X86-BMI1BMI2-NEXT:    pushl %esi
2084; X86-BMI1BMI2-NEXT:    calll use64
2085; X86-BMI1BMI2-NEXT:    addl $16, %esp
2086; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
2087; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
2088; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2089; X86-BMI1BMI2-NEXT:    movl %edi, %edx
2090; X86-BMI1BMI2-NEXT:    addl $4, %esp
2091; X86-BMI1BMI2-NEXT:    popl %esi
2092; X86-BMI1BMI2-NEXT:    popl %edi
2093; X86-BMI1BMI2-NEXT:    retl
2094;
2095; X64-NOBMI-LABEL: bzhi64_c0:
2096; X64-NOBMI:       # %bb.0:
2097; X64-NOBMI-NEXT:    pushq %r14
2098; X64-NOBMI-NEXT:    pushq %rbx
2099; X64-NOBMI-NEXT:    pushq %rax
2100; X64-NOBMI-NEXT:    movq %rsi, %rcx
2101; X64-NOBMI-NEXT:    movq %rdi, %r14
2102; X64-NOBMI-NEXT:    negb %cl
2103; X64-NOBMI-NEXT:    movq $-1, %rbx
2104; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2105; X64-NOBMI-NEXT:    shrq %cl, %rbx
2106; X64-NOBMI-NEXT:    movq %rbx, %rdi
2107; X64-NOBMI-NEXT:    callq use64
2108; X64-NOBMI-NEXT:    andq %r14, %rbx
2109; X64-NOBMI-NEXT:    movq %rbx, %rax
2110; X64-NOBMI-NEXT:    addq $8, %rsp
2111; X64-NOBMI-NEXT:    popq %rbx
2112; X64-NOBMI-NEXT:    popq %r14
2113; X64-NOBMI-NEXT:    retq
2114;
2115; X64-BMI1NOTBM-LABEL: bzhi64_c0:
2116; X64-BMI1NOTBM:       # %bb.0:
2117; X64-BMI1NOTBM-NEXT:    pushq %r14
2118; X64-BMI1NOTBM-NEXT:    pushq %rbx
2119; X64-BMI1NOTBM-NEXT:    pushq %rax
2120; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
2121; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
2122; X64-BMI1NOTBM-NEXT:    negb %cl
2123; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
2124; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
2125; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
2126; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
2127; X64-BMI1NOTBM-NEXT:    callq use64
2128; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
2129; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2130; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
2131; X64-BMI1NOTBM-NEXT:    popq %rbx
2132; X64-BMI1NOTBM-NEXT:    popq %r14
2133; X64-BMI1NOTBM-NEXT:    retq
2134;
2135; X64-BMI1BMI2-LABEL: bzhi64_c0:
2136; X64-BMI1BMI2:       # %bb.0:
2137; X64-BMI1BMI2-NEXT:    pushq %r14
2138; X64-BMI1BMI2-NEXT:    pushq %rbx
2139; X64-BMI1BMI2-NEXT:    pushq %rax
2140; X64-BMI1BMI2-NEXT:    movq %rsi, %rbx
2141; X64-BMI1BMI2-NEXT:    movq %rdi, %r14
2142; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
2143; X64-BMI1BMI2-NEXT:    negb %al
2144; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
2145; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
2146; X64-BMI1BMI2-NEXT:    callq use64
2147; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
2148; X64-BMI1BMI2-NEXT:    addq $8, %rsp
2149; X64-BMI1BMI2-NEXT:    popq %rbx
2150; X64-BMI1BMI2-NEXT:    popq %r14
2151; X64-BMI1BMI2-NEXT:    retq
2152  %numhighbits = sub i64 64, %numlowbits
2153  %mask = lshr i64 -1, %numhighbits
2154  call void @use64(i64 %mask)
2155  %masked = and i64 %mask, %val
2156  ret i64 %masked
2157}
2158
2159define i64 @bzhi64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind {
2160; X86-NOBMI-LABEL: bzhi64_c1_indexzext:
2161; X86-NOBMI:       # %bb.0:
2162; X86-NOBMI-NEXT:    pushl %edi
2163; X86-NOBMI-NEXT:    pushl %esi
2164; X86-NOBMI-NEXT:    pushl %eax
2165; X86-NOBMI-NEXT:    movb $64, %cl
2166; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2167; X86-NOBMI-NEXT:    movl $-1, %esi
2168; X86-NOBMI-NEXT:    movl $-1, %edi
2169; X86-NOBMI-NEXT:    shrl %cl, %edi
2170; X86-NOBMI-NEXT:    shrdl %cl, %esi, %esi
2171; X86-NOBMI-NEXT:    testb $32, %cl
2172; X86-NOBMI-NEXT:    je .LBB26_2
2173; X86-NOBMI-NEXT:  # %bb.1:
2174; X86-NOBMI-NEXT:    movl %edi, %esi
2175; X86-NOBMI-NEXT:    xorl %edi, %edi
2176; X86-NOBMI-NEXT:  .LBB26_2:
2177; X86-NOBMI-NEXT:    subl $8, %esp
2178; X86-NOBMI-NEXT:    pushl %edi
2179; X86-NOBMI-NEXT:    pushl %esi
2180; X86-NOBMI-NEXT:    calll use64
2181; X86-NOBMI-NEXT:    addl $16, %esp
2182; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
2183; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edi
2184; X86-NOBMI-NEXT:    movl %esi, %eax
2185; X86-NOBMI-NEXT:    movl %edi, %edx
2186; X86-NOBMI-NEXT:    addl $4, %esp
2187; X86-NOBMI-NEXT:    popl %esi
2188; X86-NOBMI-NEXT:    popl %edi
2189; X86-NOBMI-NEXT:    retl
2190;
2191; X86-BMI1NOTBM-LABEL: bzhi64_c1_indexzext:
2192; X86-BMI1NOTBM:       # %bb.0:
2193; X86-BMI1NOTBM-NEXT:    pushl %edi
2194; X86-BMI1NOTBM-NEXT:    pushl %esi
2195; X86-BMI1NOTBM-NEXT:    pushl %eax
2196; X86-BMI1NOTBM-NEXT:    movb $64, %cl
2197; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
2198; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
2199; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2200; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
2201; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %esi
2202; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2203; X86-BMI1NOTBM-NEXT:    je .LBB26_2
2204; X86-BMI1NOTBM-NEXT:  # %bb.1:
2205; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
2206; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
2207; X86-BMI1NOTBM-NEXT:  .LBB26_2:
2208; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2209; X86-BMI1NOTBM-NEXT:    pushl %edi
2210; X86-BMI1NOTBM-NEXT:    pushl %esi
2211; X86-BMI1NOTBM-NEXT:    calll use64
2212; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2213; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
2214; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edi
2215; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2216; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2217; X86-BMI1NOTBM-NEXT:    addl $4, %esp
2218; X86-BMI1NOTBM-NEXT:    popl %esi
2219; X86-BMI1NOTBM-NEXT:    popl %edi
2220; X86-BMI1NOTBM-NEXT:    retl
2221;
2222; X86-BMI1BMI2-LABEL: bzhi64_c1_indexzext:
2223; X86-BMI1BMI2:       # %bb.0:
2224; X86-BMI1BMI2-NEXT:    pushl %edi
2225; X86-BMI1BMI2-NEXT:    pushl %esi
2226; X86-BMI1BMI2-NEXT:    pushl %eax
2227; X86-BMI1BMI2-NEXT:    movb $64, %cl
2228; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
2229; X86-BMI1BMI2-NEXT:    movl $-1, %esi
2230; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edi
2231; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %esi
2232; X86-BMI1BMI2-NEXT:    testb $32, %cl
2233; X86-BMI1BMI2-NEXT:    je .LBB26_2
2234; X86-BMI1BMI2-NEXT:  # %bb.1:
2235; X86-BMI1BMI2-NEXT:    movl %edi, %esi
2236; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
2237; X86-BMI1BMI2-NEXT:  .LBB26_2:
2238; X86-BMI1BMI2-NEXT:    subl $8, %esp
2239; X86-BMI1BMI2-NEXT:    pushl %edi
2240; X86-BMI1BMI2-NEXT:    pushl %esi
2241; X86-BMI1BMI2-NEXT:    calll use64
2242; X86-BMI1BMI2-NEXT:    addl $16, %esp
2243; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
2244; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
2245; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2246; X86-BMI1BMI2-NEXT:    movl %edi, %edx
2247; X86-BMI1BMI2-NEXT:    addl $4, %esp
2248; X86-BMI1BMI2-NEXT:    popl %esi
2249; X86-BMI1BMI2-NEXT:    popl %edi
2250; X86-BMI1BMI2-NEXT:    retl
2251;
2252; X64-NOBMI-LABEL: bzhi64_c1_indexzext:
2253; X64-NOBMI:       # %bb.0:
2254; X64-NOBMI-NEXT:    pushq %r14
2255; X64-NOBMI-NEXT:    pushq %rbx
2256; X64-NOBMI-NEXT:    pushq %rax
2257; X64-NOBMI-NEXT:    movl %esi, %ecx
2258; X64-NOBMI-NEXT:    movq %rdi, %r14
2259; X64-NOBMI-NEXT:    negb %cl
2260; X64-NOBMI-NEXT:    movq $-1, %rbx
2261; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2262; X64-NOBMI-NEXT:    shrq %cl, %rbx
2263; X64-NOBMI-NEXT:    movq %rbx, %rdi
2264; X64-NOBMI-NEXT:    callq use64
2265; X64-NOBMI-NEXT:    andq %r14, %rbx
2266; X64-NOBMI-NEXT:    movq %rbx, %rax
2267; X64-NOBMI-NEXT:    addq $8, %rsp
2268; X64-NOBMI-NEXT:    popq %rbx
2269; X64-NOBMI-NEXT:    popq %r14
2270; X64-NOBMI-NEXT:    retq
2271;
2272; X64-BMI1NOTBM-LABEL: bzhi64_c1_indexzext:
2273; X64-BMI1NOTBM:       # %bb.0:
2274; X64-BMI1NOTBM-NEXT:    pushq %r14
2275; X64-BMI1NOTBM-NEXT:    pushq %rbx
2276; X64-BMI1NOTBM-NEXT:    pushq %rax
2277; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
2278; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
2279; X64-BMI1NOTBM-NEXT:    negb %cl
2280; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
2281; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
2282; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
2283; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
2284; X64-BMI1NOTBM-NEXT:    callq use64
2285; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
2286; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2287; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
2288; X64-BMI1NOTBM-NEXT:    popq %rbx
2289; X64-BMI1NOTBM-NEXT:    popq %r14
2290; X64-BMI1NOTBM-NEXT:    retq
2291;
2292; X64-BMI1BMI2-LABEL: bzhi64_c1_indexzext:
2293; X64-BMI1BMI2:       # %bb.0:
2294; X64-BMI1BMI2-NEXT:    pushq %r14
2295; X64-BMI1BMI2-NEXT:    pushq %rbx
2296; X64-BMI1BMI2-NEXT:    pushq %rax
2297; X64-BMI1BMI2-NEXT:    movl %esi, %ebx
2298; X64-BMI1BMI2-NEXT:    movq %rdi, %r14
2299; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
2300; X64-BMI1BMI2-NEXT:    negb %al
2301; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
2302; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
2303; X64-BMI1BMI2-NEXT:    callq use64
2304; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
2305; X64-BMI1BMI2-NEXT:    addq $8, %rsp
2306; X64-BMI1BMI2-NEXT:    popq %rbx
2307; X64-BMI1BMI2-NEXT:    popq %r14
2308; X64-BMI1BMI2-NEXT:    retq
2309  %numhighbits = sub i8 64, %numlowbits
2310  %sh_prom = zext i8 %numhighbits to i64
2311  %mask = lshr i64 -1, %sh_prom
2312  call void @use64(i64 %mask)
2313  %masked = and i64 %mask, %val
2314  ret i64 %masked
2315}
2316
2317define i64 @bzhi64_c2_load(i64* %w, i64 %numlowbits) nounwind {
2318; X86-NOBMI-LABEL: bzhi64_c2_load:
2319; X86-NOBMI:       # %bb.0:
2320; X86-NOBMI-NEXT:    pushl %ebx
2321; X86-NOBMI-NEXT:    pushl %edi
2322; X86-NOBMI-NEXT:    pushl %esi
2323; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
2324; X86-NOBMI-NEXT:    movb $64, %cl
2325; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2326; X86-NOBMI-NEXT:    movl $-1, %eax
2327; X86-NOBMI-NEXT:    movl $-1, %ebx
2328; X86-NOBMI-NEXT:    shrl %cl, %ebx
2329; X86-NOBMI-NEXT:    shrdl %cl, %eax, %eax
2330; X86-NOBMI-NEXT:    testb $32, %cl
2331; X86-NOBMI-NEXT:    je .LBB27_2
2332; X86-NOBMI-NEXT:  # %bb.1:
2333; X86-NOBMI-NEXT:    movl %ebx, %eax
2334; X86-NOBMI-NEXT:    xorl %ebx, %ebx
2335; X86-NOBMI-NEXT:  .LBB27_2:
2336; X86-NOBMI-NEXT:    movl (%edx), %esi
2337; X86-NOBMI-NEXT:    andl %eax, %esi
2338; X86-NOBMI-NEXT:    movl 4(%edx), %edi
2339; X86-NOBMI-NEXT:    andl %ebx, %edi
2340; X86-NOBMI-NEXT:    subl $8, %esp
2341; X86-NOBMI-NEXT:    pushl %ebx
2342; X86-NOBMI-NEXT:    pushl %eax
2343; X86-NOBMI-NEXT:    calll use64
2344; X86-NOBMI-NEXT:    addl $16, %esp
2345; X86-NOBMI-NEXT:    movl %esi, %eax
2346; X86-NOBMI-NEXT:    movl %edi, %edx
2347; X86-NOBMI-NEXT:    popl %esi
2348; X86-NOBMI-NEXT:    popl %edi
2349; X86-NOBMI-NEXT:    popl %ebx
2350; X86-NOBMI-NEXT:    retl
2351;
2352; X86-BMI1NOTBM-LABEL: bzhi64_c2_load:
2353; X86-BMI1NOTBM:       # %bb.0:
2354; X86-BMI1NOTBM-NEXT:    pushl %ebx
2355; X86-BMI1NOTBM-NEXT:    pushl %edi
2356; X86-BMI1NOTBM-NEXT:    pushl %esi
2357; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2358; X86-BMI1NOTBM-NEXT:    movb $64, %cl
2359; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
2360; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
2361; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2362; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
2363; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %eax
2364; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2365; X86-BMI1NOTBM-NEXT:    je .LBB27_2
2366; X86-BMI1NOTBM-NEXT:  # %bb.1:
2367; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
2368; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2369; X86-BMI1NOTBM-NEXT:  .LBB27_2:
2370; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2371; X86-BMI1NOTBM-NEXT:    andl %eax, %esi
2372; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2373; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
2374; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2375; X86-BMI1NOTBM-NEXT:    pushl %ebx
2376; X86-BMI1NOTBM-NEXT:    pushl %eax
2377; X86-BMI1NOTBM-NEXT:    calll use64
2378; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2379; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2380; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2381; X86-BMI1NOTBM-NEXT:    popl %esi
2382; X86-BMI1NOTBM-NEXT:    popl %edi
2383; X86-BMI1NOTBM-NEXT:    popl %ebx
2384; X86-BMI1NOTBM-NEXT:    retl
2385;
2386; X86-BMI1BMI2-LABEL: bzhi64_c2_load:
2387; X86-BMI1BMI2:       # %bb.0:
2388; X86-BMI1BMI2-NEXT:    pushl %ebx
2389; X86-BMI1BMI2-NEXT:    pushl %edi
2390; X86-BMI1BMI2-NEXT:    pushl %esi
2391; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2392; X86-BMI1BMI2-NEXT:    movb $64, %cl
2393; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
2394; X86-BMI1BMI2-NEXT:    movl $-1, %eax
2395; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %ebx
2396; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %eax
2397; X86-BMI1BMI2-NEXT:    testb $32, %cl
2398; X86-BMI1BMI2-NEXT:    je .LBB27_2
2399; X86-BMI1BMI2-NEXT:  # %bb.1:
2400; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
2401; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2402; X86-BMI1BMI2-NEXT:  .LBB27_2:
2403; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2404; X86-BMI1BMI2-NEXT:    andl %eax, %esi
2405; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2406; X86-BMI1BMI2-NEXT:    andl %ebx, %edi
2407; X86-BMI1BMI2-NEXT:    subl $8, %esp
2408; X86-BMI1BMI2-NEXT:    pushl %ebx
2409; X86-BMI1BMI2-NEXT:    pushl %eax
2410; X86-BMI1BMI2-NEXT:    calll use64
2411; X86-BMI1BMI2-NEXT:    addl $16, %esp
2412; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2413; X86-BMI1BMI2-NEXT:    movl %edi, %edx
2414; X86-BMI1BMI2-NEXT:    popl %esi
2415; X86-BMI1BMI2-NEXT:    popl %edi
2416; X86-BMI1BMI2-NEXT:    popl %ebx
2417; X86-BMI1BMI2-NEXT:    retl
2418;
2419; X64-NOBMI-LABEL: bzhi64_c2_load:
2420; X64-NOBMI:       # %bb.0:
2421; X64-NOBMI-NEXT:    pushq %rbx
2422; X64-NOBMI-NEXT:    movq %rsi, %rcx
2423; X64-NOBMI-NEXT:    negb %cl
2424; X64-NOBMI-NEXT:    movq $-1, %rax
2425; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2426; X64-NOBMI-NEXT:    shrq %cl, %rax
2427; X64-NOBMI-NEXT:    movq (%rdi), %rbx
2428; X64-NOBMI-NEXT:    andq %rax, %rbx
2429; X64-NOBMI-NEXT:    movq %rax, %rdi
2430; X64-NOBMI-NEXT:    callq use64
2431; X64-NOBMI-NEXT:    movq %rbx, %rax
2432; X64-NOBMI-NEXT:    popq %rbx
2433; X64-NOBMI-NEXT:    retq
2434;
2435; X64-BMI1NOTBM-LABEL: bzhi64_c2_load:
2436; X64-BMI1NOTBM:       # %bb.0:
2437; X64-BMI1NOTBM-NEXT:    pushq %rbx
2438; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
2439; X64-BMI1NOTBM-NEXT:    negb %cl
2440; X64-BMI1NOTBM-NEXT:    movq $-1, %rax
2441; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
2442; X64-BMI1NOTBM-NEXT:    shrq %cl, %rax
2443; X64-BMI1NOTBM-NEXT:    movq (%rdi), %rbx
2444; X64-BMI1NOTBM-NEXT:    andq %rax, %rbx
2445; X64-BMI1NOTBM-NEXT:    movq %rax, %rdi
2446; X64-BMI1NOTBM-NEXT:    callq use64
2447; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2448; X64-BMI1NOTBM-NEXT:    popq %rbx
2449; X64-BMI1NOTBM-NEXT:    retq
2450;
2451; X64-BMI1BMI2-LABEL: bzhi64_c2_load:
2452; X64-BMI1BMI2:       # %bb.0:
2453; X64-BMI1BMI2-NEXT:    pushq %rbx
2454; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rbx
2455; X64-BMI1BMI2-NEXT:    # kill: def $sil killed $sil killed $rsi def $rsi
2456; X64-BMI1BMI2-NEXT:    negb %sil
2457; X64-BMI1BMI2-NEXT:    movq $-1, %rax
2458; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rax, %rdi
2459; X64-BMI1BMI2-NEXT:    callq use64
2460; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
2461; X64-BMI1BMI2-NEXT:    popq %rbx
2462; X64-BMI1BMI2-NEXT:    retq
2463  %val = load i64, i64* %w
2464  %numhighbits = sub i64 64, %numlowbits
2465  %mask = lshr i64 -1, %numhighbits
2466  call void @use64(i64 %mask)
2467  %masked = and i64 %mask, %val
2468  ret i64 %masked
2469}
2470
2471define i64 @bzhi64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
2472; X86-NOBMI-LABEL: bzhi64_c3_load_indexzext:
2473; X86-NOBMI:       # %bb.0:
2474; X86-NOBMI-NEXT:    pushl %ebx
2475; X86-NOBMI-NEXT:    pushl %edi
2476; X86-NOBMI-NEXT:    pushl %esi
2477; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
2478; X86-NOBMI-NEXT:    movb $64, %cl
2479; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2480; X86-NOBMI-NEXT:    movl $-1, %eax
2481; X86-NOBMI-NEXT:    movl $-1, %ebx
2482; X86-NOBMI-NEXT:    shrl %cl, %ebx
2483; X86-NOBMI-NEXT:    shrdl %cl, %eax, %eax
2484; X86-NOBMI-NEXT:    testb $32, %cl
2485; X86-NOBMI-NEXT:    je .LBB28_2
2486; X86-NOBMI-NEXT:  # %bb.1:
2487; X86-NOBMI-NEXT:    movl %ebx, %eax
2488; X86-NOBMI-NEXT:    xorl %ebx, %ebx
2489; X86-NOBMI-NEXT:  .LBB28_2:
2490; X86-NOBMI-NEXT:    movl (%edx), %esi
2491; X86-NOBMI-NEXT:    andl %eax, %esi
2492; X86-NOBMI-NEXT:    movl 4(%edx), %edi
2493; X86-NOBMI-NEXT:    andl %ebx, %edi
2494; X86-NOBMI-NEXT:    subl $8, %esp
2495; X86-NOBMI-NEXT:    pushl %ebx
2496; X86-NOBMI-NEXT:    pushl %eax
2497; X86-NOBMI-NEXT:    calll use64
2498; X86-NOBMI-NEXT:    addl $16, %esp
2499; X86-NOBMI-NEXT:    movl %esi, %eax
2500; X86-NOBMI-NEXT:    movl %edi, %edx
2501; X86-NOBMI-NEXT:    popl %esi
2502; X86-NOBMI-NEXT:    popl %edi
2503; X86-NOBMI-NEXT:    popl %ebx
2504; X86-NOBMI-NEXT:    retl
2505;
2506; X86-BMI1NOTBM-LABEL: bzhi64_c3_load_indexzext:
2507; X86-BMI1NOTBM:       # %bb.0:
2508; X86-BMI1NOTBM-NEXT:    pushl %ebx
2509; X86-BMI1NOTBM-NEXT:    pushl %edi
2510; X86-BMI1NOTBM-NEXT:    pushl %esi
2511; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2512; X86-BMI1NOTBM-NEXT:    movb $64, %cl
2513; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
2514; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
2515; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2516; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
2517; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %eax
2518; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2519; X86-BMI1NOTBM-NEXT:    je .LBB28_2
2520; X86-BMI1NOTBM-NEXT:  # %bb.1:
2521; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
2522; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2523; X86-BMI1NOTBM-NEXT:  .LBB28_2:
2524; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2525; X86-BMI1NOTBM-NEXT:    andl %eax, %esi
2526; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2527; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
2528; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2529; X86-BMI1NOTBM-NEXT:    pushl %ebx
2530; X86-BMI1NOTBM-NEXT:    pushl %eax
2531; X86-BMI1NOTBM-NEXT:    calll use64
2532; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2533; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2534; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2535; X86-BMI1NOTBM-NEXT:    popl %esi
2536; X86-BMI1NOTBM-NEXT:    popl %edi
2537; X86-BMI1NOTBM-NEXT:    popl %ebx
2538; X86-BMI1NOTBM-NEXT:    retl
2539;
2540; X86-BMI1BMI2-LABEL: bzhi64_c3_load_indexzext:
2541; X86-BMI1BMI2:       # %bb.0:
2542; X86-BMI1BMI2-NEXT:    pushl %ebx
2543; X86-BMI1BMI2-NEXT:    pushl %edi
2544; X86-BMI1BMI2-NEXT:    pushl %esi
2545; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2546; X86-BMI1BMI2-NEXT:    movb $64, %cl
2547; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
2548; X86-BMI1BMI2-NEXT:    movl $-1, %eax
2549; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %ebx
2550; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %eax
2551; X86-BMI1BMI2-NEXT:    testb $32, %cl
2552; X86-BMI1BMI2-NEXT:    je .LBB28_2
2553; X86-BMI1BMI2-NEXT:  # %bb.1:
2554; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
2555; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2556; X86-BMI1BMI2-NEXT:  .LBB28_2:
2557; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2558; X86-BMI1BMI2-NEXT:    andl %eax, %esi
2559; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2560; X86-BMI1BMI2-NEXT:    andl %ebx, %edi
2561; X86-BMI1BMI2-NEXT:    subl $8, %esp
2562; X86-BMI1BMI2-NEXT:    pushl %ebx
2563; X86-BMI1BMI2-NEXT:    pushl %eax
2564; X86-BMI1BMI2-NEXT:    calll use64
2565; X86-BMI1BMI2-NEXT:    addl $16, %esp
2566; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2567; X86-BMI1BMI2-NEXT:    movl %edi, %edx
2568; X86-BMI1BMI2-NEXT:    popl %esi
2569; X86-BMI1BMI2-NEXT:    popl %edi
2570; X86-BMI1BMI2-NEXT:    popl %ebx
2571; X86-BMI1BMI2-NEXT:    retl
2572;
2573; X64-NOBMI-LABEL: bzhi64_c3_load_indexzext:
2574; X64-NOBMI:       # %bb.0:
2575; X64-NOBMI-NEXT:    pushq %rbx
2576; X64-NOBMI-NEXT:    movl %esi, %ecx
2577; X64-NOBMI-NEXT:    negb %cl
2578; X64-NOBMI-NEXT:    movq $-1, %rax
2579; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2580; X64-NOBMI-NEXT:    shrq %cl, %rax
2581; X64-NOBMI-NEXT:    movq (%rdi), %rbx
2582; X64-NOBMI-NEXT:    andq %rax, %rbx
2583; X64-NOBMI-NEXT:    movq %rax, %rdi
2584; X64-NOBMI-NEXT:    callq use64
2585; X64-NOBMI-NEXT:    movq %rbx, %rax
2586; X64-NOBMI-NEXT:    popq %rbx
2587; X64-NOBMI-NEXT:    retq
2588;
2589; X64-BMI1NOTBM-LABEL: bzhi64_c3_load_indexzext:
2590; X64-BMI1NOTBM:       # %bb.0:
2591; X64-BMI1NOTBM-NEXT:    pushq %rbx
2592; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
2593; X64-BMI1NOTBM-NEXT:    negb %cl
2594; X64-BMI1NOTBM-NEXT:    movq $-1, %rax
2595; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
2596; X64-BMI1NOTBM-NEXT:    shrq %cl, %rax
2597; X64-BMI1NOTBM-NEXT:    movq (%rdi), %rbx
2598; X64-BMI1NOTBM-NEXT:    andq %rax, %rbx
2599; X64-BMI1NOTBM-NEXT:    movq %rax, %rdi
2600; X64-BMI1NOTBM-NEXT:    callq use64
2601; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2602; X64-BMI1NOTBM-NEXT:    popq %rbx
2603; X64-BMI1NOTBM-NEXT:    retq
2604;
2605; X64-BMI1BMI2-LABEL: bzhi64_c3_load_indexzext:
2606; X64-BMI1BMI2:       # %bb.0:
2607; X64-BMI1BMI2-NEXT:    pushq %rbx
2608; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2609; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rbx
2610; X64-BMI1BMI2-NEXT:    # kill: def $sil killed $sil killed $rsi def $rsi
2611; X64-BMI1BMI2-NEXT:    negb %sil
2612; X64-BMI1BMI2-NEXT:    movq $-1, %rax
2613; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rax, %rdi
2614; X64-BMI1BMI2-NEXT:    callq use64
2615; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
2616; X64-BMI1BMI2-NEXT:    popq %rbx
2617; X64-BMI1BMI2-NEXT:    retq
2618  %val = load i64, i64* %w
2619  %numhighbits = sub i8 64, %numlowbits
2620  %sh_prom = zext i8 %numhighbits to i64
2621  %mask = lshr i64 -1, %sh_prom
2622  call void @use64(i64 %mask)
2623  %masked = and i64 %mask, %val
2624  ret i64 %masked
2625}
2626
2627define i64 @bzhi64_c4_commutative(i64 %val, i64 %numlowbits) nounwind {
2628; X86-NOBMI-LABEL: bzhi64_c4_commutative:
2629; X86-NOBMI:       # %bb.0:
2630; X86-NOBMI-NEXT:    pushl %edi
2631; X86-NOBMI-NEXT:    pushl %esi
2632; X86-NOBMI-NEXT:    pushl %eax
2633; X86-NOBMI-NEXT:    movb $64, %cl
2634; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2635; X86-NOBMI-NEXT:    movl $-1, %esi
2636; X86-NOBMI-NEXT:    movl $-1, %edi
2637; X86-NOBMI-NEXT:    shrl %cl, %edi
2638; X86-NOBMI-NEXT:    shrdl %cl, %esi, %esi
2639; X86-NOBMI-NEXT:    testb $32, %cl
2640; X86-NOBMI-NEXT:    je .LBB29_2
2641; X86-NOBMI-NEXT:  # %bb.1:
2642; X86-NOBMI-NEXT:    movl %edi, %esi
2643; X86-NOBMI-NEXT:    xorl %edi, %edi
2644; X86-NOBMI-NEXT:  .LBB29_2:
2645; X86-NOBMI-NEXT:    subl $8, %esp
2646; X86-NOBMI-NEXT:    pushl %edi
2647; X86-NOBMI-NEXT:    pushl %esi
2648; X86-NOBMI-NEXT:    calll use64
2649; X86-NOBMI-NEXT:    addl $16, %esp
2650; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
2651; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edi
2652; X86-NOBMI-NEXT:    movl %esi, %eax
2653; X86-NOBMI-NEXT:    movl %edi, %edx
2654; X86-NOBMI-NEXT:    addl $4, %esp
2655; X86-NOBMI-NEXT:    popl %esi
2656; X86-NOBMI-NEXT:    popl %edi
2657; X86-NOBMI-NEXT:    retl
2658;
2659; X86-BMI1NOTBM-LABEL: bzhi64_c4_commutative:
2660; X86-BMI1NOTBM:       # %bb.0:
2661; X86-BMI1NOTBM-NEXT:    pushl %edi
2662; X86-BMI1NOTBM-NEXT:    pushl %esi
2663; X86-BMI1NOTBM-NEXT:    pushl %eax
2664; X86-BMI1NOTBM-NEXT:    movb $64, %cl
2665; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
2666; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
2667; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2668; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
2669; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %esi
2670; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2671; X86-BMI1NOTBM-NEXT:    je .LBB29_2
2672; X86-BMI1NOTBM-NEXT:  # %bb.1:
2673; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
2674; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
2675; X86-BMI1NOTBM-NEXT:  .LBB29_2:
2676; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2677; X86-BMI1NOTBM-NEXT:    pushl %edi
2678; X86-BMI1NOTBM-NEXT:    pushl %esi
2679; X86-BMI1NOTBM-NEXT:    calll use64
2680; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2681; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %esi
2682; X86-BMI1NOTBM-NEXT:    andl {{[0-9]+}}(%esp), %edi
2683; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2684; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2685; X86-BMI1NOTBM-NEXT:    addl $4, %esp
2686; X86-BMI1NOTBM-NEXT:    popl %esi
2687; X86-BMI1NOTBM-NEXT:    popl %edi
2688; X86-BMI1NOTBM-NEXT:    retl
2689;
2690; X86-BMI1BMI2-LABEL: bzhi64_c4_commutative:
2691; X86-BMI1BMI2:       # %bb.0:
2692; X86-BMI1BMI2-NEXT:    pushl %edi
2693; X86-BMI1BMI2-NEXT:    pushl %esi
2694; X86-BMI1BMI2-NEXT:    pushl %eax
2695; X86-BMI1BMI2-NEXT:    movb $64, %cl
2696; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
2697; X86-BMI1BMI2-NEXT:    movl $-1, %esi
2698; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edi
2699; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %esi
2700; X86-BMI1BMI2-NEXT:    testb $32, %cl
2701; X86-BMI1BMI2-NEXT:    je .LBB29_2
2702; X86-BMI1BMI2-NEXT:  # %bb.1:
2703; X86-BMI1BMI2-NEXT:    movl %edi, %esi
2704; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
2705; X86-BMI1BMI2-NEXT:  .LBB29_2:
2706; X86-BMI1BMI2-NEXT:    subl $8, %esp
2707; X86-BMI1BMI2-NEXT:    pushl %edi
2708; X86-BMI1BMI2-NEXT:    pushl %esi
2709; X86-BMI1BMI2-NEXT:    calll use64
2710; X86-BMI1BMI2-NEXT:    addl $16, %esp
2711; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %esi
2712; X86-BMI1BMI2-NEXT:    andl {{[0-9]+}}(%esp), %edi
2713; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2714; X86-BMI1BMI2-NEXT:    movl %edi, %edx
2715; X86-BMI1BMI2-NEXT:    addl $4, %esp
2716; X86-BMI1BMI2-NEXT:    popl %esi
2717; X86-BMI1BMI2-NEXT:    popl %edi
2718; X86-BMI1BMI2-NEXT:    retl
2719;
2720; X64-NOBMI-LABEL: bzhi64_c4_commutative:
2721; X64-NOBMI:       # %bb.0:
2722; X64-NOBMI-NEXT:    pushq %r14
2723; X64-NOBMI-NEXT:    pushq %rbx
2724; X64-NOBMI-NEXT:    pushq %rax
2725; X64-NOBMI-NEXT:    movq %rsi, %rcx
2726; X64-NOBMI-NEXT:    movq %rdi, %r14
2727; X64-NOBMI-NEXT:    negb %cl
2728; X64-NOBMI-NEXT:    movq $-1, %rbx
2729; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2730; X64-NOBMI-NEXT:    shrq %cl, %rbx
2731; X64-NOBMI-NEXT:    movq %rbx, %rdi
2732; X64-NOBMI-NEXT:    callq use64
2733; X64-NOBMI-NEXT:    andq %r14, %rbx
2734; X64-NOBMI-NEXT:    movq %rbx, %rax
2735; X64-NOBMI-NEXT:    addq $8, %rsp
2736; X64-NOBMI-NEXT:    popq %rbx
2737; X64-NOBMI-NEXT:    popq %r14
2738; X64-NOBMI-NEXT:    retq
2739;
2740; X64-BMI1NOTBM-LABEL: bzhi64_c4_commutative:
2741; X64-BMI1NOTBM:       # %bb.0:
2742; X64-BMI1NOTBM-NEXT:    pushq %r14
2743; X64-BMI1NOTBM-NEXT:    pushq %rbx
2744; X64-BMI1NOTBM-NEXT:    pushq %rax
2745; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
2746; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
2747; X64-BMI1NOTBM-NEXT:    negb %cl
2748; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
2749; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
2750; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
2751; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
2752; X64-BMI1NOTBM-NEXT:    callq use64
2753; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
2754; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2755; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
2756; X64-BMI1NOTBM-NEXT:    popq %rbx
2757; X64-BMI1NOTBM-NEXT:    popq %r14
2758; X64-BMI1NOTBM-NEXT:    retq
2759;
2760; X64-BMI1BMI2-LABEL: bzhi64_c4_commutative:
2761; X64-BMI1BMI2:       # %bb.0:
2762; X64-BMI1BMI2-NEXT:    pushq %r14
2763; X64-BMI1BMI2-NEXT:    pushq %rbx
2764; X64-BMI1BMI2-NEXT:    pushq %rax
2765; X64-BMI1BMI2-NEXT:    movq %rsi, %rbx
2766; X64-BMI1BMI2-NEXT:    movq %rdi, %r14
2767; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
2768; X64-BMI1BMI2-NEXT:    negb %al
2769; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
2770; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
2771; X64-BMI1BMI2-NEXT:    callq use64
2772; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
2773; X64-BMI1BMI2-NEXT:    addq $8, %rsp
2774; X64-BMI1BMI2-NEXT:    popq %rbx
2775; X64-BMI1BMI2-NEXT:    popq %r14
2776; X64-BMI1BMI2-NEXT:    retq
2777  %numhighbits = sub i64 64, %numlowbits
2778  %mask = lshr i64 -1, %numhighbits
2779  call void @use64(i64 %mask)
2780  %masked = and i64 %val, %mask ; swapped order
2781  ret i64 %masked
2782}
2783
2784; ---------------------------------------------------------------------------- ;
2785; Pattern d. 32-bit.
2786; ---------------------------------------------------------------------------- ;
2787
2788define i32 @bzhi32_d0(i32 %val, i32 %numlowbits) nounwind {
2789; X86-NOBMI-LABEL: bzhi32_d0:
2790; X86-NOBMI:       # %bb.0:
2791; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2792; X86-NOBMI-NEXT:    xorl %ecx, %ecx
2793; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2794; X86-NOBMI-NEXT:    shll %cl, %eax
2795; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2796; X86-NOBMI-NEXT:    shrl %cl, %eax
2797; X86-NOBMI-NEXT:    retl
2798;
2799; X86-BMI1NOTBM-LABEL: bzhi32_d0:
2800; X86-BMI1NOTBM:       # %bb.0:
2801; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2802; X86-BMI1NOTBM-NEXT:    shll $8, %eax
2803; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
2804; X86-BMI1NOTBM-NEXT:    retl
2805;
2806; X86-BMI1BMI2-LABEL: bzhi32_d0:
2807; X86-BMI1BMI2:       # %bb.0:
2808; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2809; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
2810; X86-BMI1BMI2-NEXT:    retl
2811;
2812; X64-NOBMI-LABEL: bzhi32_d0:
2813; X64-NOBMI:       # %bb.0:
2814; X64-NOBMI-NEXT:    movl %esi, %ecx
2815; X64-NOBMI-NEXT:    movl %edi, %eax
2816; X64-NOBMI-NEXT:    negb %cl
2817; X64-NOBMI-NEXT:    shll %cl, %eax
2818; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2819; X64-NOBMI-NEXT:    shrl %cl, %eax
2820; X64-NOBMI-NEXT:    retq
2821;
2822; X64-BMI1NOTBM-LABEL: bzhi32_d0:
2823; X64-BMI1NOTBM:       # %bb.0:
2824; X64-BMI1NOTBM-NEXT:    shll $8, %esi
2825; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
2826; X64-BMI1NOTBM-NEXT:    retq
2827;
2828; X64-BMI1BMI2-LABEL: bzhi32_d0:
2829; X64-BMI1BMI2:       # %bb.0:
2830; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
2831; X64-BMI1BMI2-NEXT:    retq
2832  %numhighbits = sub i32 32, %numlowbits
2833  %highbitscleared = shl i32 %val, %numhighbits
2834  %masked = lshr i32 %highbitscleared, %numhighbits
2835  ret i32 %masked
2836}
2837
2838define i32 @bzhi32_d1_indexzext(i32 %val, i8 %numlowbits) nounwind {
2839; X86-NOBMI-LABEL: bzhi32_d1_indexzext:
2840; X86-NOBMI:       # %bb.0:
2841; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2842; X86-NOBMI-NEXT:    xorl %ecx, %ecx
2843; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2844; X86-NOBMI-NEXT:    shll %cl, %eax
2845; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2846; X86-NOBMI-NEXT:    shrl %cl, %eax
2847; X86-NOBMI-NEXT:    retl
2848;
2849; X86-BMI1NOTBM-LABEL: bzhi32_d1_indexzext:
2850; X86-BMI1NOTBM:       # %bb.0:
2851; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2852; X86-BMI1NOTBM-NEXT:    shll $8, %eax
2853; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
2854; X86-BMI1NOTBM-NEXT:    retl
2855;
2856; X86-BMI1BMI2-LABEL: bzhi32_d1_indexzext:
2857; X86-BMI1BMI2:       # %bb.0:
2858; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2859; X86-BMI1BMI2-NEXT:    bzhil %eax, {{[0-9]+}}(%esp), %eax
2860; X86-BMI1BMI2-NEXT:    retl
2861;
2862; X64-NOBMI-LABEL: bzhi32_d1_indexzext:
2863; X64-NOBMI:       # %bb.0:
2864; X64-NOBMI-NEXT:    movl %esi, %ecx
2865; X64-NOBMI-NEXT:    movl %edi, %eax
2866; X64-NOBMI-NEXT:    negb %cl
2867; X64-NOBMI-NEXT:    shll %cl, %eax
2868; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2869; X64-NOBMI-NEXT:    shrl %cl, %eax
2870; X64-NOBMI-NEXT:    retq
2871;
2872; X64-BMI1NOTBM-LABEL: bzhi32_d1_indexzext:
2873; X64-BMI1NOTBM:       # %bb.0:
2874; X64-BMI1NOTBM-NEXT:    shll $8, %esi
2875; X64-BMI1NOTBM-NEXT:    bextrl %esi, %edi, %eax
2876; X64-BMI1NOTBM-NEXT:    retq
2877;
2878; X64-BMI1BMI2-LABEL: bzhi32_d1_indexzext:
2879; X64-BMI1BMI2:       # %bb.0:
2880; X64-BMI1BMI2-NEXT:    bzhil %esi, %edi, %eax
2881; X64-BMI1BMI2-NEXT:    retq
2882  %numhighbits = sub i8 32, %numlowbits
2883  %sh_prom = zext i8 %numhighbits to i32
2884  %highbitscleared = shl i32 %val, %sh_prom
2885  %masked = lshr i32 %highbitscleared, %sh_prom
2886  ret i32 %masked
2887}
2888
2889define i32 @bzhi32_d2_load(i32* %w, i32 %numlowbits) nounwind {
2890; X86-NOBMI-LABEL: bzhi32_d2_load:
2891; X86-NOBMI:       # %bb.0:
2892; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2893; X86-NOBMI-NEXT:    movl (%eax), %eax
2894; X86-NOBMI-NEXT:    xorl %ecx, %ecx
2895; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2896; X86-NOBMI-NEXT:    shll %cl, %eax
2897; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2898; X86-NOBMI-NEXT:    shrl %cl, %eax
2899; X86-NOBMI-NEXT:    retl
2900;
2901; X86-BMI1NOTBM-LABEL: bzhi32_d2_load:
2902; X86-BMI1NOTBM:       # %bb.0:
2903; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2904; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2905; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
2906; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
2907; X86-BMI1NOTBM-NEXT:    retl
2908;
2909; X86-BMI1BMI2-LABEL: bzhi32_d2_load:
2910; X86-BMI1BMI2:       # %bb.0:
2911; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2912; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2913; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
2914; X86-BMI1BMI2-NEXT:    retl
2915;
2916; X64-NOBMI-LABEL: bzhi32_d2_load:
2917; X64-NOBMI:       # %bb.0:
2918; X64-NOBMI-NEXT:    movl %esi, %ecx
2919; X64-NOBMI-NEXT:    movl (%rdi), %eax
2920; X64-NOBMI-NEXT:    negb %cl
2921; X64-NOBMI-NEXT:    shll %cl, %eax
2922; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2923; X64-NOBMI-NEXT:    shrl %cl, %eax
2924; X64-NOBMI-NEXT:    retq
2925;
2926; X64-BMI1NOTBM-LABEL: bzhi32_d2_load:
2927; X64-BMI1NOTBM:       # %bb.0:
2928; X64-BMI1NOTBM-NEXT:    shll $8, %esi
2929; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
2930; X64-BMI1NOTBM-NEXT:    retq
2931;
2932; X64-BMI1BMI2-LABEL: bzhi32_d2_load:
2933; X64-BMI1BMI2:       # %bb.0:
2934; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
2935; X64-BMI1BMI2-NEXT:    retq
2936  %val = load i32, i32* %w
2937  %numhighbits = sub i32 32, %numlowbits
2938  %highbitscleared = shl i32 %val, %numhighbits
2939  %masked = lshr i32 %highbitscleared, %numhighbits
2940  ret i32 %masked
2941}
2942
2943define i32 @bzhi32_d3_load_indexzext(i32* %w, i8 %numlowbits) nounwind {
2944; X86-NOBMI-LABEL: bzhi32_d3_load_indexzext:
2945; X86-NOBMI:       # %bb.0:
2946; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2947; X86-NOBMI-NEXT:    movl (%eax), %eax
2948; X86-NOBMI-NEXT:    xorl %ecx, %ecx
2949; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2950; X86-NOBMI-NEXT:    shll %cl, %eax
2951; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2952; X86-NOBMI-NEXT:    shrl %cl, %eax
2953; X86-NOBMI-NEXT:    retl
2954;
2955; X86-BMI1NOTBM-LABEL: bzhi32_d3_load_indexzext:
2956; X86-BMI1NOTBM:       # %bb.0:
2957; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2958; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2959; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
2960; X86-BMI1NOTBM-NEXT:    bextrl %ecx, (%eax), %eax
2961; X86-BMI1NOTBM-NEXT:    retl
2962;
2963; X86-BMI1BMI2-LABEL: bzhi32_d3_load_indexzext:
2964; X86-BMI1BMI2:       # %bb.0:
2965; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2966; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2967; X86-BMI1BMI2-NEXT:    bzhil %ecx, (%eax), %eax
2968; X86-BMI1BMI2-NEXT:    retl
2969;
2970; X64-NOBMI-LABEL: bzhi32_d3_load_indexzext:
2971; X64-NOBMI:       # %bb.0:
2972; X64-NOBMI-NEXT:    movl %esi, %ecx
2973; X64-NOBMI-NEXT:    movl (%rdi), %eax
2974; X64-NOBMI-NEXT:    negb %cl
2975; X64-NOBMI-NEXT:    shll %cl, %eax
2976; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2977; X64-NOBMI-NEXT:    shrl %cl, %eax
2978; X64-NOBMI-NEXT:    retq
2979;
2980; X64-BMI1NOTBM-LABEL: bzhi32_d3_load_indexzext:
2981; X64-BMI1NOTBM:       # %bb.0:
2982; X64-BMI1NOTBM-NEXT:    shll $8, %esi
2983; X64-BMI1NOTBM-NEXT:    bextrl %esi, (%rdi), %eax
2984; X64-BMI1NOTBM-NEXT:    retq
2985;
2986; X64-BMI1BMI2-LABEL: bzhi32_d3_load_indexzext:
2987; X64-BMI1BMI2:       # %bb.0:
2988; X64-BMI1BMI2-NEXT:    bzhil %esi, (%rdi), %eax
2989; X64-BMI1BMI2-NEXT:    retq
2990  %val = load i32, i32* %w
2991  %numhighbits = sub i8 32, %numlowbits
2992  %sh_prom = zext i8 %numhighbits to i32
2993  %highbitscleared = shl i32 %val, %sh_prom
2994  %masked = lshr i32 %highbitscleared, %sh_prom
2995  ret i32 %masked
2996}
2997
2998; 64-bit.
2999
3000define i64 @bzhi64_d0(i64 %val, i64 %numlowbits) nounwind {
3001; X86-NOBMI-LABEL: bzhi64_d0:
3002; X86-NOBMI:       # %bb.0:
3003; X86-NOBMI-NEXT:    pushl %ebx
3004; X86-NOBMI-NEXT:    pushl %edi
3005; X86-NOBMI-NEXT:    pushl %esi
3006; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
3007; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3008; X86-NOBMI-NEXT:    movb $64, %cl
3009; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3010; X86-NOBMI-NEXT:    movl %edx, %esi
3011; X86-NOBMI-NEXT:    shll %cl, %esi
3012; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
3013; X86-NOBMI-NEXT:    testb $32, %cl
3014; X86-NOBMI-NEXT:    movl %esi, %edi
3015; X86-NOBMI-NEXT:    jne .LBB34_2
3016; X86-NOBMI-NEXT:  # %bb.1:
3017; X86-NOBMI-NEXT:    movl %eax, %edi
3018; X86-NOBMI-NEXT:  .LBB34_2:
3019; X86-NOBMI-NEXT:    movl %edi, %eax
3020; X86-NOBMI-NEXT:    shrl %cl, %eax
3021; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3022; X86-NOBMI-NEXT:    testb $32, %cl
3023; X86-NOBMI-NEXT:    movl $0, %edx
3024; X86-NOBMI-NEXT:    jne .LBB34_4
3025; X86-NOBMI-NEXT:  # %bb.3:
3026; X86-NOBMI-NEXT:    movl %esi, %ebx
3027; X86-NOBMI-NEXT:    movl %eax, %edx
3028; X86-NOBMI-NEXT:  .LBB34_4:
3029; X86-NOBMI-NEXT:    shrdl %cl, %edi, %ebx
3030; X86-NOBMI-NEXT:    testb $32, %cl
3031; X86-NOBMI-NEXT:    jne .LBB34_6
3032; X86-NOBMI-NEXT:  # %bb.5:
3033; X86-NOBMI-NEXT:    movl %ebx, %eax
3034; X86-NOBMI-NEXT:  .LBB34_6:
3035; X86-NOBMI-NEXT:    popl %esi
3036; X86-NOBMI-NEXT:    popl %edi
3037; X86-NOBMI-NEXT:    popl %ebx
3038; X86-NOBMI-NEXT:    retl
3039;
3040; X86-BMI1NOTBM-LABEL: bzhi64_d0:
3041; X86-BMI1NOTBM:       # %bb.0:
3042; X86-BMI1NOTBM-NEXT:    pushl %ebx
3043; X86-BMI1NOTBM-NEXT:    pushl %edi
3044; X86-BMI1NOTBM-NEXT:    pushl %esi
3045; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
3046; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3047; X86-BMI1NOTBM-NEXT:    movb $64, %cl
3048; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3049; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
3050; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
3051; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %eax
3052; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3053; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
3054; X86-BMI1NOTBM-NEXT:    jne .LBB34_2
3055; X86-BMI1NOTBM-NEXT:  # %bb.1:
3056; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
3057; X86-BMI1NOTBM-NEXT:  .LBB34_2:
3058; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
3059; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
3060; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3061; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3062; X86-BMI1NOTBM-NEXT:    movl $0, %edx
3063; X86-BMI1NOTBM-NEXT:    jne .LBB34_4
3064; X86-BMI1NOTBM-NEXT:  # %bb.3:
3065; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
3066; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
3067; X86-BMI1NOTBM-NEXT:  .LBB34_4:
3068; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %ebx
3069; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3070; X86-BMI1NOTBM-NEXT:    jne .LBB34_6
3071; X86-BMI1NOTBM-NEXT:  # %bb.5:
3072; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
3073; X86-BMI1NOTBM-NEXT:  .LBB34_6:
3074; X86-BMI1NOTBM-NEXT:    popl %esi
3075; X86-BMI1NOTBM-NEXT:    popl %edi
3076; X86-BMI1NOTBM-NEXT:    popl %ebx
3077; X86-BMI1NOTBM-NEXT:    retl
3078;
3079; X86-BMI1BMI2-LABEL: bzhi64_d0:
3080; X86-BMI1BMI2:       # %bb.0:
3081; X86-BMI1BMI2-NEXT:    pushl %edi
3082; X86-BMI1BMI2-NEXT:    pushl %esi
3083; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3084; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3085; X86-BMI1BMI2-NEXT:    movb $64, %cl
3086; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
3087; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
3088; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
3089; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
3090; X86-BMI1BMI2-NEXT:    testb $32, %cl
3091; X86-BMI1BMI2-NEXT:    je .LBB34_2
3092; X86-BMI1BMI2-NEXT:  # %bb.1:
3093; X86-BMI1BMI2-NEXT:    movl %edi, %esi
3094; X86-BMI1BMI2-NEXT:    movl $0, %edi
3095; X86-BMI1BMI2-NEXT:  .LBB34_2:
3096; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
3097; X86-BMI1BMI2-NEXT:    jne .LBB34_4
3098; X86-BMI1BMI2-NEXT:  # %bb.3:
3099; X86-BMI1BMI2-NEXT:    movl %eax, %edx
3100; X86-BMI1BMI2-NEXT:  .LBB34_4:
3101; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
3102; X86-BMI1BMI2-NEXT:    testb $32, %cl
3103; X86-BMI1BMI2-NEXT:    jne .LBB34_6
3104; X86-BMI1BMI2-NEXT:  # %bb.5:
3105; X86-BMI1BMI2-NEXT:    movl %edi, %eax
3106; X86-BMI1BMI2-NEXT:  .LBB34_6:
3107; X86-BMI1BMI2-NEXT:    popl %esi
3108; X86-BMI1BMI2-NEXT:    popl %edi
3109; X86-BMI1BMI2-NEXT:    retl
3110;
3111; X64-NOBMI-LABEL: bzhi64_d0:
3112; X64-NOBMI:       # %bb.0:
3113; X64-NOBMI-NEXT:    movq %rsi, %rcx
3114; X64-NOBMI-NEXT:    movq %rdi, %rax
3115; X64-NOBMI-NEXT:    negb %cl
3116; X64-NOBMI-NEXT:    shlq %cl, %rax
3117; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3118; X64-NOBMI-NEXT:    shrq %cl, %rax
3119; X64-NOBMI-NEXT:    retq
3120;
3121; X64-BMI1NOTBM-LABEL: bzhi64_d0:
3122; X64-BMI1NOTBM:       # %bb.0:
3123; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
3124; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
3125; X64-BMI1NOTBM-NEXT:    retq
3126;
3127; X64-BMI1BMI2-LABEL: bzhi64_d0:
3128; X64-BMI1BMI2:       # %bb.0:
3129; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
3130; X64-BMI1BMI2-NEXT:    retq
3131  %numhighbits = sub i64 64, %numlowbits
3132  %highbitscleared = shl i64 %val, %numhighbits
3133  %masked = lshr i64 %highbitscleared, %numhighbits
3134  ret i64 %masked
3135}
3136
3137define i64 @bzhi64_d1_indexzext(i64 %val, i8 %numlowbits) nounwind {
3138; X86-NOBMI-LABEL: bzhi64_d1_indexzext:
3139; X86-NOBMI:       # %bb.0:
3140; X86-NOBMI-NEXT:    pushl %ebx
3141; X86-NOBMI-NEXT:    pushl %edi
3142; X86-NOBMI-NEXT:    pushl %esi
3143; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
3144; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3145; X86-NOBMI-NEXT:    movb $64, %cl
3146; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3147; X86-NOBMI-NEXT:    movl %edx, %esi
3148; X86-NOBMI-NEXT:    shll %cl, %esi
3149; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
3150; X86-NOBMI-NEXT:    testb $32, %cl
3151; X86-NOBMI-NEXT:    movl %esi, %edi
3152; X86-NOBMI-NEXT:    jne .LBB35_2
3153; X86-NOBMI-NEXT:  # %bb.1:
3154; X86-NOBMI-NEXT:    movl %eax, %edi
3155; X86-NOBMI-NEXT:  .LBB35_2:
3156; X86-NOBMI-NEXT:    movl %edi, %eax
3157; X86-NOBMI-NEXT:    shrl %cl, %eax
3158; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3159; X86-NOBMI-NEXT:    testb $32, %cl
3160; X86-NOBMI-NEXT:    movl $0, %edx
3161; X86-NOBMI-NEXT:    jne .LBB35_4
3162; X86-NOBMI-NEXT:  # %bb.3:
3163; X86-NOBMI-NEXT:    movl %esi, %ebx
3164; X86-NOBMI-NEXT:    movl %eax, %edx
3165; X86-NOBMI-NEXT:  .LBB35_4:
3166; X86-NOBMI-NEXT:    shrdl %cl, %edi, %ebx
3167; X86-NOBMI-NEXT:    testb $32, %cl
3168; X86-NOBMI-NEXT:    jne .LBB35_6
3169; X86-NOBMI-NEXT:  # %bb.5:
3170; X86-NOBMI-NEXT:    movl %ebx, %eax
3171; X86-NOBMI-NEXT:  .LBB35_6:
3172; X86-NOBMI-NEXT:    popl %esi
3173; X86-NOBMI-NEXT:    popl %edi
3174; X86-NOBMI-NEXT:    popl %ebx
3175; X86-NOBMI-NEXT:    retl
3176;
3177; X86-BMI1NOTBM-LABEL: bzhi64_d1_indexzext:
3178; X86-BMI1NOTBM:       # %bb.0:
3179; X86-BMI1NOTBM-NEXT:    pushl %ebx
3180; X86-BMI1NOTBM-NEXT:    pushl %edi
3181; X86-BMI1NOTBM-NEXT:    pushl %esi
3182; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
3183; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3184; X86-BMI1NOTBM-NEXT:    movb $64, %cl
3185; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3186; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
3187; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
3188; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %eax
3189; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3190; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
3191; X86-BMI1NOTBM-NEXT:    jne .LBB35_2
3192; X86-BMI1NOTBM-NEXT:  # %bb.1:
3193; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
3194; X86-BMI1NOTBM-NEXT:  .LBB35_2:
3195; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
3196; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
3197; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3198; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3199; X86-BMI1NOTBM-NEXT:    movl $0, %edx
3200; X86-BMI1NOTBM-NEXT:    jne .LBB35_4
3201; X86-BMI1NOTBM-NEXT:  # %bb.3:
3202; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
3203; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
3204; X86-BMI1NOTBM-NEXT:  .LBB35_4:
3205; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %ebx
3206; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3207; X86-BMI1NOTBM-NEXT:    jne .LBB35_6
3208; X86-BMI1NOTBM-NEXT:  # %bb.5:
3209; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
3210; X86-BMI1NOTBM-NEXT:  .LBB35_6:
3211; X86-BMI1NOTBM-NEXT:    popl %esi
3212; X86-BMI1NOTBM-NEXT:    popl %edi
3213; X86-BMI1NOTBM-NEXT:    popl %ebx
3214; X86-BMI1NOTBM-NEXT:    retl
3215;
3216; X86-BMI1BMI2-LABEL: bzhi64_d1_indexzext:
3217; X86-BMI1BMI2:       # %bb.0:
3218; X86-BMI1BMI2-NEXT:    pushl %edi
3219; X86-BMI1BMI2-NEXT:    pushl %esi
3220; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3221; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3222; X86-BMI1BMI2-NEXT:    movb $64, %cl
3223; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
3224; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
3225; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
3226; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
3227; X86-BMI1BMI2-NEXT:    testb $32, %cl
3228; X86-BMI1BMI2-NEXT:    je .LBB35_2
3229; X86-BMI1BMI2-NEXT:  # %bb.1:
3230; X86-BMI1BMI2-NEXT:    movl %edi, %esi
3231; X86-BMI1BMI2-NEXT:    movl $0, %edi
3232; X86-BMI1BMI2-NEXT:  .LBB35_2:
3233; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
3234; X86-BMI1BMI2-NEXT:    jne .LBB35_4
3235; X86-BMI1BMI2-NEXT:  # %bb.3:
3236; X86-BMI1BMI2-NEXT:    movl %eax, %edx
3237; X86-BMI1BMI2-NEXT:  .LBB35_4:
3238; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
3239; X86-BMI1BMI2-NEXT:    testb $32, %cl
3240; X86-BMI1BMI2-NEXT:    jne .LBB35_6
3241; X86-BMI1BMI2-NEXT:  # %bb.5:
3242; X86-BMI1BMI2-NEXT:    movl %edi, %eax
3243; X86-BMI1BMI2-NEXT:  .LBB35_6:
3244; X86-BMI1BMI2-NEXT:    popl %esi
3245; X86-BMI1BMI2-NEXT:    popl %edi
3246; X86-BMI1BMI2-NEXT:    retl
3247;
3248; X64-NOBMI-LABEL: bzhi64_d1_indexzext:
3249; X64-NOBMI:       # %bb.0:
3250; X64-NOBMI-NEXT:    movl %esi, %ecx
3251; X64-NOBMI-NEXT:    movq %rdi, %rax
3252; X64-NOBMI-NEXT:    negb %cl
3253; X64-NOBMI-NEXT:    shlq %cl, %rax
3254; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3255; X64-NOBMI-NEXT:    shrq %cl, %rax
3256; X64-NOBMI-NEXT:    retq
3257;
3258; X64-BMI1NOTBM-LABEL: bzhi64_d1_indexzext:
3259; X64-BMI1NOTBM:       # %bb.0:
3260; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
3261; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
3262; X64-BMI1NOTBM-NEXT:    bextrq %rsi, %rdi, %rax
3263; X64-BMI1NOTBM-NEXT:    retq
3264;
3265; X64-BMI1BMI2-LABEL: bzhi64_d1_indexzext:
3266; X64-BMI1BMI2:       # %bb.0:
3267; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
3268; X64-BMI1BMI2-NEXT:    bzhiq %rsi, %rdi, %rax
3269; X64-BMI1BMI2-NEXT:    retq
3270  %numhighbits = sub i8 64, %numlowbits
3271  %sh_prom = zext i8 %numhighbits to i64
3272  %highbitscleared = shl i64 %val, %sh_prom
3273  %masked = lshr i64 %highbitscleared, %sh_prom
3274  ret i64 %masked
3275}
3276
3277define i64 @bzhi64_d2_load(i64* %w, i64 %numlowbits) nounwind {
3278; X86-NOBMI-LABEL: bzhi64_d2_load:
3279; X86-NOBMI:       # %bb.0:
3280; X86-NOBMI-NEXT:    pushl %ebx
3281; X86-NOBMI-NEXT:    pushl %edi
3282; X86-NOBMI-NEXT:    pushl %esi
3283; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3284; X86-NOBMI-NEXT:    movl (%eax), %edx
3285; X86-NOBMI-NEXT:    movl 4(%eax), %eax
3286; X86-NOBMI-NEXT:    movb $64, %cl
3287; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3288; X86-NOBMI-NEXT:    movl %edx, %esi
3289; X86-NOBMI-NEXT:    shll %cl, %esi
3290; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
3291; X86-NOBMI-NEXT:    testb $32, %cl
3292; X86-NOBMI-NEXT:    movl %esi, %edi
3293; X86-NOBMI-NEXT:    jne .LBB36_2
3294; X86-NOBMI-NEXT:  # %bb.1:
3295; X86-NOBMI-NEXT:    movl %eax, %edi
3296; X86-NOBMI-NEXT:  .LBB36_2:
3297; X86-NOBMI-NEXT:    movl %edi, %eax
3298; X86-NOBMI-NEXT:    shrl %cl, %eax
3299; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3300; X86-NOBMI-NEXT:    testb $32, %cl
3301; X86-NOBMI-NEXT:    movl $0, %edx
3302; X86-NOBMI-NEXT:    jne .LBB36_4
3303; X86-NOBMI-NEXT:  # %bb.3:
3304; X86-NOBMI-NEXT:    movl %esi, %ebx
3305; X86-NOBMI-NEXT:    movl %eax, %edx
3306; X86-NOBMI-NEXT:  .LBB36_4:
3307; X86-NOBMI-NEXT:    shrdl %cl, %edi, %ebx
3308; X86-NOBMI-NEXT:    testb $32, %cl
3309; X86-NOBMI-NEXT:    jne .LBB36_6
3310; X86-NOBMI-NEXT:  # %bb.5:
3311; X86-NOBMI-NEXT:    movl %ebx, %eax
3312; X86-NOBMI-NEXT:  .LBB36_6:
3313; X86-NOBMI-NEXT:    popl %esi
3314; X86-NOBMI-NEXT:    popl %edi
3315; X86-NOBMI-NEXT:    popl %ebx
3316; X86-NOBMI-NEXT:    retl
3317;
3318; X86-BMI1NOTBM-LABEL: bzhi64_d2_load:
3319; X86-BMI1NOTBM:       # %bb.0:
3320; X86-BMI1NOTBM-NEXT:    pushl %ebx
3321; X86-BMI1NOTBM-NEXT:    pushl %edi
3322; X86-BMI1NOTBM-NEXT:    pushl %esi
3323; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3324; X86-BMI1NOTBM-NEXT:    movl (%eax), %edx
3325; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
3326; X86-BMI1NOTBM-NEXT:    movb $64, %cl
3327; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3328; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
3329; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
3330; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %eax
3331; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3332; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
3333; X86-BMI1NOTBM-NEXT:    jne .LBB36_2
3334; X86-BMI1NOTBM-NEXT:  # %bb.1:
3335; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
3336; X86-BMI1NOTBM-NEXT:  .LBB36_2:
3337; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
3338; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
3339; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3340; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3341; X86-BMI1NOTBM-NEXT:    movl $0, %edx
3342; X86-BMI1NOTBM-NEXT:    jne .LBB36_4
3343; X86-BMI1NOTBM-NEXT:  # %bb.3:
3344; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
3345; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
3346; X86-BMI1NOTBM-NEXT:  .LBB36_4:
3347; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %ebx
3348; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3349; X86-BMI1NOTBM-NEXT:    jne .LBB36_6
3350; X86-BMI1NOTBM-NEXT:  # %bb.5:
3351; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
3352; X86-BMI1NOTBM-NEXT:  .LBB36_6:
3353; X86-BMI1NOTBM-NEXT:    popl %esi
3354; X86-BMI1NOTBM-NEXT:    popl %edi
3355; X86-BMI1NOTBM-NEXT:    popl %ebx
3356; X86-BMI1NOTBM-NEXT:    retl
3357;
3358; X86-BMI1BMI2-LABEL: bzhi64_d2_load:
3359; X86-BMI1BMI2:       # %bb.0:
3360; X86-BMI1BMI2-NEXT:    pushl %edi
3361; X86-BMI1BMI2-NEXT:    pushl %esi
3362; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3363; X86-BMI1BMI2-NEXT:    movl (%eax), %edx
3364; X86-BMI1BMI2-NEXT:    movl 4(%eax), %esi
3365; X86-BMI1BMI2-NEXT:    movb $64, %cl
3366; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
3367; X86-BMI1BMI2-NEXT:    shldl %cl, %edx, %esi
3368; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edx, %edi
3369; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
3370; X86-BMI1BMI2-NEXT:    testb $32, %cl
3371; X86-BMI1BMI2-NEXT:    je .LBB36_2
3372; X86-BMI1BMI2-NEXT:  # %bb.1:
3373; X86-BMI1BMI2-NEXT:    movl %edi, %esi
3374; X86-BMI1BMI2-NEXT:    movl $0, %edi
3375; X86-BMI1BMI2-NEXT:  .LBB36_2:
3376; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
3377; X86-BMI1BMI2-NEXT:    jne .LBB36_4
3378; X86-BMI1BMI2-NEXT:  # %bb.3:
3379; X86-BMI1BMI2-NEXT:    movl %eax, %edx
3380; X86-BMI1BMI2-NEXT:  .LBB36_4:
3381; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
3382; X86-BMI1BMI2-NEXT:    testb $32, %cl
3383; X86-BMI1BMI2-NEXT:    jne .LBB36_6
3384; X86-BMI1BMI2-NEXT:  # %bb.5:
3385; X86-BMI1BMI2-NEXT:    movl %edi, %eax
3386; X86-BMI1BMI2-NEXT:  .LBB36_6:
3387; X86-BMI1BMI2-NEXT:    popl %esi
3388; X86-BMI1BMI2-NEXT:    popl %edi
3389; X86-BMI1BMI2-NEXT:    retl
3390;
3391; X64-NOBMI-LABEL: bzhi64_d2_load:
3392; X64-NOBMI:       # %bb.0:
3393; X64-NOBMI-NEXT:    movq %rsi, %rcx
3394; X64-NOBMI-NEXT:    movq (%rdi), %rax
3395; X64-NOBMI-NEXT:    negb %cl
3396; X64-NOBMI-NEXT:    shlq %cl, %rax
3397; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3398; X64-NOBMI-NEXT:    shrq %cl, %rax
3399; X64-NOBMI-NEXT:    retq
3400;
3401; X64-BMI1NOTBM-LABEL: bzhi64_d2_load:
3402; X64-BMI1NOTBM:       # %bb.0:
3403; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
3404; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
3405; X64-BMI1NOTBM-NEXT:    retq
3406;
3407; X64-BMI1BMI2-LABEL: bzhi64_d2_load:
3408; X64-BMI1BMI2:       # %bb.0:
3409; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
3410; X64-BMI1BMI2-NEXT:    retq
3411  %val = load i64, i64* %w
3412  %numhighbits = sub i64 64, %numlowbits
3413  %highbitscleared = shl i64 %val, %numhighbits
3414  %masked = lshr i64 %highbitscleared, %numhighbits
3415  ret i64 %masked
3416}
3417
3418define i64 @bzhi64_d3_load_indexzext(i64* %w, i8 %numlowbits) nounwind {
3419; X86-NOBMI-LABEL: bzhi64_d3_load_indexzext:
3420; X86-NOBMI:       # %bb.0:
3421; X86-NOBMI-NEXT:    pushl %ebx
3422; X86-NOBMI-NEXT:    pushl %edi
3423; X86-NOBMI-NEXT:    pushl %esi
3424; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3425; X86-NOBMI-NEXT:    movl (%eax), %edx
3426; X86-NOBMI-NEXT:    movl 4(%eax), %eax
3427; X86-NOBMI-NEXT:    movb $64, %cl
3428; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3429; X86-NOBMI-NEXT:    movl %edx, %esi
3430; X86-NOBMI-NEXT:    shll %cl, %esi
3431; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
3432; X86-NOBMI-NEXT:    testb $32, %cl
3433; X86-NOBMI-NEXT:    movl %esi, %edi
3434; X86-NOBMI-NEXT:    jne .LBB37_2
3435; X86-NOBMI-NEXT:  # %bb.1:
3436; X86-NOBMI-NEXT:    movl %eax, %edi
3437; X86-NOBMI-NEXT:  .LBB37_2:
3438; X86-NOBMI-NEXT:    movl %edi, %eax
3439; X86-NOBMI-NEXT:    shrl %cl, %eax
3440; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3441; X86-NOBMI-NEXT:    testb $32, %cl
3442; X86-NOBMI-NEXT:    movl $0, %edx
3443; X86-NOBMI-NEXT:    jne .LBB37_4
3444; X86-NOBMI-NEXT:  # %bb.3:
3445; X86-NOBMI-NEXT:    movl %esi, %ebx
3446; X86-NOBMI-NEXT:    movl %eax, %edx
3447; X86-NOBMI-NEXT:  .LBB37_4:
3448; X86-NOBMI-NEXT:    shrdl %cl, %edi, %ebx
3449; X86-NOBMI-NEXT:    testb $32, %cl
3450; X86-NOBMI-NEXT:    jne .LBB37_6
3451; X86-NOBMI-NEXT:  # %bb.5:
3452; X86-NOBMI-NEXT:    movl %ebx, %eax
3453; X86-NOBMI-NEXT:  .LBB37_6:
3454; X86-NOBMI-NEXT:    popl %esi
3455; X86-NOBMI-NEXT:    popl %edi
3456; X86-NOBMI-NEXT:    popl %ebx
3457; X86-NOBMI-NEXT:    retl
3458;
3459; X86-BMI1NOTBM-LABEL: bzhi64_d3_load_indexzext:
3460; X86-BMI1NOTBM:       # %bb.0:
3461; X86-BMI1NOTBM-NEXT:    pushl %ebx
3462; X86-BMI1NOTBM-NEXT:    pushl %edi
3463; X86-BMI1NOTBM-NEXT:    pushl %esi
3464; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3465; X86-BMI1NOTBM-NEXT:    movl (%eax), %edx
3466; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
3467; X86-BMI1NOTBM-NEXT:    movb $64, %cl
3468; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3469; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
3470; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
3471; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %eax
3472; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3473; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
3474; X86-BMI1NOTBM-NEXT:    jne .LBB37_2
3475; X86-BMI1NOTBM-NEXT:  # %bb.1:
3476; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
3477; X86-BMI1NOTBM-NEXT:  .LBB37_2:
3478; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
3479; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
3480; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3481; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3482; X86-BMI1NOTBM-NEXT:    movl $0, %edx
3483; X86-BMI1NOTBM-NEXT:    jne .LBB37_4
3484; X86-BMI1NOTBM-NEXT:  # %bb.3:
3485; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
3486; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
3487; X86-BMI1NOTBM-NEXT:  .LBB37_4:
3488; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %ebx
3489; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3490; X86-BMI1NOTBM-NEXT:    jne .LBB37_6
3491; X86-BMI1NOTBM-NEXT:  # %bb.5:
3492; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
3493; X86-BMI1NOTBM-NEXT:  .LBB37_6:
3494; X86-BMI1NOTBM-NEXT:    popl %esi
3495; X86-BMI1NOTBM-NEXT:    popl %edi
3496; X86-BMI1NOTBM-NEXT:    popl %ebx
3497; X86-BMI1NOTBM-NEXT:    retl
3498;
3499; X86-BMI1BMI2-LABEL: bzhi64_d3_load_indexzext:
3500; X86-BMI1BMI2:       # %bb.0:
3501; X86-BMI1BMI2-NEXT:    pushl %edi
3502; X86-BMI1BMI2-NEXT:    pushl %esi
3503; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3504; X86-BMI1BMI2-NEXT:    movl (%eax), %edx
3505; X86-BMI1BMI2-NEXT:    movl 4(%eax), %esi
3506; X86-BMI1BMI2-NEXT:    movb $64, %cl
3507; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
3508; X86-BMI1BMI2-NEXT:    shldl %cl, %edx, %esi
3509; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edx, %edi
3510; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
3511; X86-BMI1BMI2-NEXT:    testb $32, %cl
3512; X86-BMI1BMI2-NEXT:    je .LBB37_2
3513; X86-BMI1BMI2-NEXT:  # %bb.1:
3514; X86-BMI1BMI2-NEXT:    movl %edi, %esi
3515; X86-BMI1BMI2-NEXT:    movl $0, %edi
3516; X86-BMI1BMI2-NEXT:  .LBB37_2:
3517; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
3518; X86-BMI1BMI2-NEXT:    jne .LBB37_4
3519; X86-BMI1BMI2-NEXT:  # %bb.3:
3520; X86-BMI1BMI2-NEXT:    movl %eax, %edx
3521; X86-BMI1BMI2-NEXT:  .LBB37_4:
3522; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
3523; X86-BMI1BMI2-NEXT:    testb $32, %cl
3524; X86-BMI1BMI2-NEXT:    jne .LBB37_6
3525; X86-BMI1BMI2-NEXT:  # %bb.5:
3526; X86-BMI1BMI2-NEXT:    movl %edi, %eax
3527; X86-BMI1BMI2-NEXT:  .LBB37_6:
3528; X86-BMI1BMI2-NEXT:    popl %esi
3529; X86-BMI1BMI2-NEXT:    popl %edi
3530; X86-BMI1BMI2-NEXT:    retl
3531;
3532; X64-NOBMI-LABEL: bzhi64_d3_load_indexzext:
3533; X64-NOBMI:       # %bb.0:
3534; X64-NOBMI-NEXT:    movl %esi, %ecx
3535; X64-NOBMI-NEXT:    movq (%rdi), %rax
3536; X64-NOBMI-NEXT:    negb %cl
3537; X64-NOBMI-NEXT:    shlq %cl, %rax
3538; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3539; X64-NOBMI-NEXT:    shrq %cl, %rax
3540; X64-NOBMI-NEXT:    retq
3541;
3542; X64-BMI1NOTBM-LABEL: bzhi64_d3_load_indexzext:
3543; X64-BMI1NOTBM:       # %bb.0:
3544; X64-BMI1NOTBM-NEXT:    # kill: def $esi killed $esi def $rsi
3545; X64-BMI1NOTBM-NEXT:    shlq $8, %rsi
3546; X64-BMI1NOTBM-NEXT:    bextrq %rsi, (%rdi), %rax
3547; X64-BMI1NOTBM-NEXT:    retq
3548;
3549; X64-BMI1BMI2-LABEL: bzhi64_d3_load_indexzext:
3550; X64-BMI1BMI2:       # %bb.0:
3551; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
3552; X64-BMI1BMI2-NEXT:    bzhiq %rsi, (%rdi), %rax
3553; X64-BMI1BMI2-NEXT:    retq
3554  %val = load i64, i64* %w
3555  %numhighbits = sub i8 64, %numlowbits
3556  %sh_prom = zext i8 %numhighbits to i64
3557  %highbitscleared = shl i64 %val, %sh_prom
3558  %masked = lshr i64 %highbitscleared, %sh_prom
3559  ret i64 %masked
3560}
3561
3562; ---------------------------------------------------------------------------- ;
3563; Constant mask
3564; ---------------------------------------------------------------------------- ;
3565
3566; 32-bit
3567
3568define i32 @bzhi32_constant_mask32(i32 %val) nounwind {
3569; X86-LABEL: bzhi32_constant_mask32:
3570; X86:       # %bb.0:
3571; X86-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
3572; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
3573; X86-NEXT:    retl
3574;
3575; X64-LABEL: bzhi32_constant_mask32:
3576; X64:       # %bb.0:
3577; X64-NEXT:    movl %edi, %eax
3578; X64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
3579; X64-NEXT:    retq
3580  %masked = and i32 %val, 2147483647
3581  ret i32 %masked
3582}
3583
3584define i32 @bzhi32_constant_mask32_load(i32* %val) nounwind {
3585; X86-LABEL: bzhi32_constant_mask32_load:
3586; X86:       # %bb.0:
3587; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3588; X86-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
3589; X86-NEXT:    andl (%ecx), %eax
3590; X86-NEXT:    retl
3591;
3592; X64-LABEL: bzhi32_constant_mask32_load:
3593; X64:       # %bb.0:
3594; X64-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
3595; X64-NEXT:    andl (%rdi), %eax
3596; X64-NEXT:    retq
3597  %val1 = load i32, i32* %val
3598  %masked = and i32 %val1, 2147483647
3599  ret i32 %masked
3600}
3601
3602define i32 @bzhi32_constant_mask16(i32 %val) nounwind {
3603; X86-LABEL: bzhi32_constant_mask16:
3604; X86:       # %bb.0:
3605; X86-NEXT:    movl $32767, %eax # imm = 0x7FFF
3606; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
3607; X86-NEXT:    retl
3608;
3609; X64-LABEL: bzhi32_constant_mask16:
3610; X64:       # %bb.0:
3611; X64-NEXT:    movl %edi, %eax
3612; X64-NEXT:    andl $32767, %eax # imm = 0x7FFF
3613; X64-NEXT:    retq
3614  %masked = and i32 %val, 32767
3615  ret i32 %masked
3616}
3617
3618define i32 @bzhi32_constant_mask16_load(i32* %val) nounwind {
3619; X86-LABEL: bzhi32_constant_mask16_load:
3620; X86:       # %bb.0:
3621; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3622; X86-NEXT:    movl $32767, %eax # imm = 0x7FFF
3623; X86-NEXT:    andl (%ecx), %eax
3624; X86-NEXT:    retl
3625;
3626; X64-LABEL: bzhi32_constant_mask16_load:
3627; X64:       # %bb.0:
3628; X64-NEXT:    movl $32767, %eax # imm = 0x7FFF
3629; X64-NEXT:    andl (%rdi), %eax
3630; X64-NEXT:    retq
3631  %val1 = load i32, i32* %val
3632  %masked = and i32 %val1, 32767
3633  ret i32 %masked
3634}
3635
3636define i32 @bzhi32_constant_mask8(i32 %val) nounwind {
3637; X86-LABEL: bzhi32_constant_mask8:
3638; X86:       # %bb.0:
3639; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3640; X86-NEXT:    andl $127, %eax
3641; X86-NEXT:    retl
3642;
3643; X64-LABEL: bzhi32_constant_mask8:
3644; X64:       # %bb.0:
3645; X64-NEXT:    movl %edi, %eax
3646; X64-NEXT:    andl $127, %eax
3647; X64-NEXT:    retq
3648  %masked = and i32 %val, 127
3649  ret i32 %masked
3650}
3651
3652define i32 @bzhi32_constant_mask8_load(i32* %val) nounwind {
3653; X86-LABEL: bzhi32_constant_mask8_load:
3654; X86:       # %bb.0:
3655; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3656; X86-NEXT:    movl (%eax), %eax
3657; X86-NEXT:    andl $127, %eax
3658; X86-NEXT:    retl
3659;
3660; X64-LABEL: bzhi32_constant_mask8_load:
3661; X64:       # %bb.0:
3662; X64-NEXT:    movl (%rdi), %eax
3663; X64-NEXT:    andl $127, %eax
3664; X64-NEXT:    retq
3665  %val1 = load i32, i32* %val
3666  %masked = and i32 %val1, 127
3667  ret i32 %masked
3668}
3669
3670; 64-bit
3671
3672define i64 @bzhi64_constant_mask64(i64 %val) nounwind {
3673; X86-LABEL: bzhi64_constant_mask64:
3674; X86:       # %bb.0:
3675; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3676; X86-NEXT:    movl $1073741823, %edx # imm = 0x3FFFFFFF
3677; X86-NEXT:    andl {{[0-9]+}}(%esp), %edx
3678; X86-NEXT:    retl
3679;
3680; X64-NOBMI-LABEL: bzhi64_constant_mask64:
3681; X64-NOBMI:       # %bb.0:
3682; X64-NOBMI-NEXT:    movabsq $4611686018427387903, %rax # imm = 0x3FFFFFFFFFFFFFFF
3683; X64-NOBMI-NEXT:    andq %rdi, %rax
3684; X64-NOBMI-NEXT:    retq
3685;
3686; X64-BMI1NOTBM-LABEL: bzhi64_constant_mask64:
3687; X64-BMI1NOTBM:       # %bb.0:
3688; X64-BMI1NOTBM-NEXT:    movl $15872, %eax # imm = 0x3E00
3689; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
3690; X64-BMI1NOTBM-NEXT:    retq
3691;
3692; X64-BMI1TBM-LABEL: bzhi64_constant_mask64:
3693; X64-BMI1TBM:       # %bb.0:
3694; X64-BMI1TBM-NEXT:    bextrq $15872, %rdi, %rax # imm = 0x3E00
3695; X64-BMI1TBM-NEXT:    retq
3696;
3697; X64-BMI1NOTBMBMI2-LABEL: bzhi64_constant_mask64:
3698; X64-BMI1NOTBMBMI2:       # %bb.0:
3699; X64-BMI1NOTBMBMI2-NEXT:    movb $62, %al
3700; X64-BMI1NOTBMBMI2-NEXT:    bzhiq %rax, %rdi, %rax
3701; X64-BMI1NOTBMBMI2-NEXT:    retq
3702  %masked = and i64 %val, 4611686018427387903
3703  ret i64 %masked
3704}
3705
3706define i64 @bzhi64_constant_mask64_load(i64* %val) nounwind {
3707; X86-LABEL: bzhi64_constant_mask64_load:
3708; X86:       # %bb.0:
3709; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3710; X86-NEXT:    movl (%ecx), %eax
3711; X86-NEXT:    movl $1073741823, %edx # imm = 0x3FFFFFFF
3712; X86-NEXT:    andl 4(%ecx), %edx
3713; X86-NEXT:    retl
3714;
3715; X64-NOBMI-LABEL: bzhi64_constant_mask64_load:
3716; X64-NOBMI:       # %bb.0:
3717; X64-NOBMI-NEXT:    movabsq $4611686018427387903, %rax # imm = 0x3FFFFFFFFFFFFFFF
3718; X64-NOBMI-NEXT:    andq (%rdi), %rax
3719; X64-NOBMI-NEXT:    retq
3720;
3721; X64-BMI1NOTBM-LABEL: bzhi64_constant_mask64_load:
3722; X64-BMI1NOTBM:       # %bb.0:
3723; X64-BMI1NOTBM-NEXT:    movl $15872, %eax # imm = 0x3E00
3724; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
3725; X64-BMI1NOTBM-NEXT:    retq
3726;
3727; X64-BMI1TBM-LABEL: bzhi64_constant_mask64_load:
3728; X64-BMI1TBM:       # %bb.0:
3729; X64-BMI1TBM-NEXT:    bextrq $15872, (%rdi), %rax # imm = 0x3E00
3730; X64-BMI1TBM-NEXT:    retq
3731;
3732; X64-BMI1NOTBMBMI2-LABEL: bzhi64_constant_mask64_load:
3733; X64-BMI1NOTBMBMI2:       # %bb.0:
3734; X64-BMI1NOTBMBMI2-NEXT:    movb $62, %al
3735; X64-BMI1NOTBMBMI2-NEXT:    bzhiq %rax, (%rdi), %rax
3736; X64-BMI1NOTBMBMI2-NEXT:    retq
3737  %val1 = load i64, i64* %val
3738  %masked = and i64 %val1, 4611686018427387903
3739  ret i64 %masked
3740}
3741
3742define i64 @bzhi64_constant_mask32(i64 %val) nounwind {
3743; X86-LABEL: bzhi64_constant_mask32:
3744; X86:       # %bb.0:
3745; X86-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
3746; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
3747; X86-NEXT:    xorl %edx, %edx
3748; X86-NEXT:    retl
3749;
3750; X64-LABEL: bzhi64_constant_mask32:
3751; X64:       # %bb.0:
3752; X64-NEXT:    movq %rdi, %rax
3753; X64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
3754; X64-NEXT:    retq
3755  %masked = and i64 %val, 2147483647
3756  ret i64 %masked
3757}
3758
3759define i64 @bzhi64_constant_mask32_load(i64* %val) nounwind {
3760; X86-LABEL: bzhi64_constant_mask32_load:
3761; X86:       # %bb.0:
3762; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3763; X86-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
3764; X86-NEXT:    andl (%ecx), %eax
3765; X86-NEXT:    xorl %edx, %edx
3766; X86-NEXT:    retl
3767;
3768; X64-LABEL: bzhi64_constant_mask32_load:
3769; X64:       # %bb.0:
3770; X64-NEXT:    movq (%rdi), %rax
3771; X64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
3772; X64-NEXT:    retq
3773  %val1 = load i64, i64* %val
3774  %masked = and i64 %val1, 2147483647
3775  ret i64 %masked
3776}
3777
3778define i64 @bzhi64_constant_mask16(i64 %val) nounwind {
3779; X86-LABEL: bzhi64_constant_mask16:
3780; X86:       # %bb.0:
3781; X86-NEXT:    movl $32767, %eax # imm = 0x7FFF
3782; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
3783; X86-NEXT:    xorl %edx, %edx
3784; X86-NEXT:    retl
3785;
3786; X64-LABEL: bzhi64_constant_mask16:
3787; X64:       # %bb.0:
3788; X64-NEXT:    movq %rdi, %rax
3789; X64-NEXT:    andl $32767, %eax # imm = 0x7FFF
3790; X64-NEXT:    retq
3791  %masked = and i64 %val, 32767
3792  ret i64 %masked
3793}
3794
3795define i64 @bzhi64_constant_mask16_load(i64* %val) nounwind {
3796; X86-LABEL: bzhi64_constant_mask16_load:
3797; X86:       # %bb.0:
3798; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3799; X86-NEXT:    movl $32767, %eax # imm = 0x7FFF
3800; X86-NEXT:    andl (%ecx), %eax
3801; X86-NEXT:    xorl %edx, %edx
3802; X86-NEXT:    retl
3803;
3804; X64-LABEL: bzhi64_constant_mask16_load:
3805; X64:       # %bb.0:
3806; X64-NEXT:    movq (%rdi), %rax
3807; X64-NEXT:    andl $32767, %eax # imm = 0x7FFF
3808; X64-NEXT:    retq
3809  %val1 = load i64, i64* %val
3810  %masked = and i64 %val1, 32767
3811  ret i64 %masked
3812}
3813
3814define i64 @bzhi64_constant_mask8(i64 %val) nounwind {
3815; X86-LABEL: bzhi64_constant_mask8:
3816; X86:       # %bb.0:
3817; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3818; X86-NEXT:    andl $127, %eax
3819; X86-NEXT:    xorl %edx, %edx
3820; X86-NEXT:    retl
3821;
3822; X64-LABEL: bzhi64_constant_mask8:
3823; X64:       # %bb.0:
3824; X64-NEXT:    movq %rdi, %rax
3825; X64-NEXT:    andl $127, %eax
3826; X64-NEXT:    retq
3827  %masked = and i64 %val, 127
3828  ret i64 %masked
3829}
3830
3831define i64 @bzhi64_constant_mask8_load(i64* %val) nounwind {
3832; X86-LABEL: bzhi64_constant_mask8_load:
3833; X86:       # %bb.0:
3834; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3835; X86-NEXT:    movl (%eax), %eax
3836; X86-NEXT:    andl $127, %eax
3837; X86-NEXT:    xorl %edx, %edx
3838; X86-NEXT:    retl
3839;
3840; X64-LABEL: bzhi64_constant_mask8_load:
3841; X64:       # %bb.0:
3842; X64-NEXT:    movq (%rdi), %rax
3843; X64-NEXT:    andl $127, %eax
3844; X64-NEXT:    retq
3845  %val1 = load i64, i64* %val
3846  %masked = and i64 %val1, 127
3847  ret i64 %masked
3848}
3849