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,+fast-bextr < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI,X86-NOBMI
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %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,+fast-bextr < %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,+fast-bextr < %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,+fast-bextr < %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,+fast-bextr < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI,X64-NOBMI
8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %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,+fast-bextr < %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,+fast-bextr < %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,+fast-bextr < %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-bits.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 >> start) &  (1 << nbits) - 1
21;   b) (x >> start) & ~(-1 << nbits)
22;   c) (x >> start) &  (-1 >> (32 - y))
23;   d) (x >> start) << (32 - y) >> (32 - y)
24; are equivalent.
25
26declare void @use32(i32)
27declare void @use64(i64)
28
29; ---------------------------------------------------------------------------- ;
30; Pattern a. 32-bit
31; ---------------------------------------------------------------------------- ;
32
33define i32 @bextr32_a0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
34; X86-NOBMI-LABEL: bextr32_a0:
35; X86-NOBMI:       # %bb.0:
36; X86-NOBMI-NEXT:    pushl %esi
37; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
38; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
39; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
40; X86-NOBMI-NEXT:    shrl %cl, %esi
41; X86-NOBMI-NEXT:    movl $1, %eax
42; X86-NOBMI-NEXT:    movl %edx, %ecx
43; X86-NOBMI-NEXT:    shll %cl, %eax
44; X86-NOBMI-NEXT:    decl %eax
45; X86-NOBMI-NEXT:    andl %esi, %eax
46; X86-NOBMI-NEXT:    popl %esi
47; X86-NOBMI-NEXT:    retl
48;
49; X86-BMI1NOTBM-LABEL: bextr32_a0:
50; X86-BMI1NOTBM:       # %bb.0:
51; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
52; X86-BMI1NOTBM-NEXT:    shll $8, %eax
53; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
54; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
55; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
56; X86-BMI1NOTBM-NEXT:    retl
57;
58; X86-BMI1BMI2-LABEL: bextr32_a0:
59; X86-BMI1BMI2:       # %bb.0:
60; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
61; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
62; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
63; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
64; X86-BMI1BMI2-NEXT:    retl
65;
66; X64-NOBMI-LABEL: bextr32_a0:
67; X64-NOBMI:       # %bb.0:
68; X64-NOBMI-NEXT:    movl %esi, %ecx
69; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
70; X64-NOBMI-NEXT:    shrl %cl, %edi
71; X64-NOBMI-NEXT:    movl $1, %eax
72; X64-NOBMI-NEXT:    movl %edx, %ecx
73; X64-NOBMI-NEXT:    shll %cl, %eax
74; X64-NOBMI-NEXT:    decl %eax
75; X64-NOBMI-NEXT:    andl %edi, %eax
76; X64-NOBMI-NEXT:    retq
77;
78; X64-BMI1NOTBM-LABEL: bextr32_a0:
79; X64-BMI1NOTBM:       # %bb.0:
80; X64-BMI1NOTBM-NEXT:    shll $8, %edx
81; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
82; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
83; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
84; X64-BMI1NOTBM-NEXT:    retq
85;
86; X64-BMI1BMI2-LABEL: bextr32_a0:
87; X64-BMI1BMI2:       # %bb.0:
88; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
89; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
90; X64-BMI1BMI2-NEXT:    retq
91  %shifted = lshr i32 %val, %numskipbits
92  %onebit = shl i32 1, %numlowbits
93  %mask = add nsw i32 %onebit, -1
94  %masked = and i32 %mask, %shifted
95  ret i32 %masked
96}
97
98define i32 @bextr32_a0_arithmetic(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
99; X86-NOBMI-LABEL: bextr32_a0_arithmetic:
100; X86-NOBMI:       # %bb.0:
101; X86-NOBMI-NEXT:    pushl %esi
102; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
103; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
104; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
105; X86-NOBMI-NEXT:    sarl %cl, %esi
106; X86-NOBMI-NEXT:    movl $1, %eax
107; X86-NOBMI-NEXT:    movl %edx, %ecx
108; X86-NOBMI-NEXT:    shll %cl, %eax
109; X86-NOBMI-NEXT:    decl %eax
110; X86-NOBMI-NEXT:    andl %esi, %eax
111; X86-NOBMI-NEXT:    popl %esi
112; X86-NOBMI-NEXT:    retl
113;
114; X86-BMI1NOTBM-LABEL: bextr32_a0_arithmetic:
115; X86-BMI1NOTBM:       # %bb.0:
116; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
117; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
118; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
119; X86-BMI1NOTBM-NEXT:    sarl %cl, %edx
120; X86-BMI1NOTBM-NEXT:    shll $8, %eax
121; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
122; X86-BMI1NOTBM-NEXT:    retl
123;
124; X86-BMI1BMI2-LABEL: bextr32_a0_arithmetic:
125; X86-BMI1BMI2:       # %bb.0:
126; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
127; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
128; X86-BMI1BMI2-NEXT:    sarxl %ecx, {{[0-9]+}}(%esp), %ecx
129; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
130; X86-BMI1BMI2-NEXT:    retl
131;
132; X64-NOBMI-LABEL: bextr32_a0_arithmetic:
133; X64-NOBMI:       # %bb.0:
134; X64-NOBMI-NEXT:    movl %esi, %ecx
135; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
136; X64-NOBMI-NEXT:    sarl %cl, %edi
137; X64-NOBMI-NEXT:    movl $1, %eax
138; X64-NOBMI-NEXT:    movl %edx, %ecx
139; X64-NOBMI-NEXT:    shll %cl, %eax
140; X64-NOBMI-NEXT:    decl %eax
141; X64-NOBMI-NEXT:    andl %edi, %eax
142; X64-NOBMI-NEXT:    retq
143;
144; X64-BMI1NOTBM-LABEL: bextr32_a0_arithmetic:
145; X64-BMI1NOTBM:       # %bb.0:
146; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
147; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
148; X64-BMI1NOTBM-NEXT:    sarl %cl, %edi
149; X64-BMI1NOTBM-NEXT:    shll $8, %edx
150; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
151; X64-BMI1NOTBM-NEXT:    retq
152;
153; X64-BMI1BMI2-LABEL: bextr32_a0_arithmetic:
154; X64-BMI1BMI2:       # %bb.0:
155; X64-BMI1BMI2-NEXT:    sarxl %esi, %edi, %eax
156; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
157; X64-BMI1BMI2-NEXT:    retq
158  %shifted = ashr i32 %val, %numskipbits
159  %onebit = shl i32 1, %numlowbits
160  %mask = add nsw i32 %onebit, -1
161  %masked = and i32 %mask, %shifted
162  ret i32 %masked
163}
164
165define i32 @bextr32_a1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
166; X86-NOBMI-LABEL: bextr32_a1_indexzext:
167; X86-NOBMI:       # %bb.0:
168; X86-NOBMI-NEXT:    pushl %esi
169; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
170; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
171; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
172; X86-NOBMI-NEXT:    shrl %cl, %esi
173; X86-NOBMI-NEXT:    movl $1, %eax
174; X86-NOBMI-NEXT:    movl %edx, %ecx
175; X86-NOBMI-NEXT:    shll %cl, %eax
176; X86-NOBMI-NEXT:    decl %eax
177; X86-NOBMI-NEXT:    andl %esi, %eax
178; X86-NOBMI-NEXT:    popl %esi
179; X86-NOBMI-NEXT:    retl
180;
181; X86-BMI1NOTBM-LABEL: bextr32_a1_indexzext:
182; X86-BMI1NOTBM:       # %bb.0:
183; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
184; X86-BMI1NOTBM-NEXT:    shll $8, %eax
185; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
186; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
187; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
188; X86-BMI1NOTBM-NEXT:    retl
189;
190; X86-BMI1BMI2-LABEL: bextr32_a1_indexzext:
191; X86-BMI1BMI2:       # %bb.0:
192; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
193; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
194; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
195; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
196; X86-BMI1BMI2-NEXT:    retl
197;
198; X64-NOBMI-LABEL: bextr32_a1_indexzext:
199; X64-NOBMI:       # %bb.0:
200; X64-NOBMI-NEXT:    movl %esi, %ecx
201; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
202; X64-NOBMI-NEXT:    shrl %cl, %edi
203; X64-NOBMI-NEXT:    movl $1, %eax
204; X64-NOBMI-NEXT:    movl %edx, %ecx
205; X64-NOBMI-NEXT:    shll %cl, %eax
206; X64-NOBMI-NEXT:    decl %eax
207; X64-NOBMI-NEXT:    andl %edi, %eax
208; X64-NOBMI-NEXT:    retq
209;
210; X64-BMI1NOTBM-LABEL: bextr32_a1_indexzext:
211; X64-BMI1NOTBM:       # %bb.0:
212; X64-BMI1NOTBM-NEXT:    shll $8, %edx
213; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
214; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
215; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
216; X64-BMI1NOTBM-NEXT:    retq
217;
218; X64-BMI1BMI2-LABEL: bextr32_a1_indexzext:
219; X64-BMI1BMI2:       # %bb.0:
220; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
221; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
222; X64-BMI1BMI2-NEXT:    retq
223  %skip = zext i8 %numskipbits to i32
224  %shifted = lshr i32 %val, %skip
225  %conv = zext i8 %numlowbits to i32
226  %onebit = shl i32 1, %conv
227  %mask = add nsw i32 %onebit, -1
228  %masked = and i32 %mask, %shifted
229  ret i32 %masked
230}
231
232define i32 @bextr32_a2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
233; X86-NOBMI-LABEL: bextr32_a2_load:
234; X86-NOBMI:       # %bb.0:
235; X86-NOBMI-NEXT:    pushl %esi
236; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
237; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
238; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
239; X86-NOBMI-NEXT:    movl (%eax), %esi
240; X86-NOBMI-NEXT:    shrl %cl, %esi
241; X86-NOBMI-NEXT:    movl $1, %eax
242; X86-NOBMI-NEXT:    movl %edx, %ecx
243; X86-NOBMI-NEXT:    shll %cl, %eax
244; X86-NOBMI-NEXT:    decl %eax
245; X86-NOBMI-NEXT:    andl %esi, %eax
246; X86-NOBMI-NEXT:    popl %esi
247; X86-NOBMI-NEXT:    retl
248;
249; X86-BMI1NOTBM-LABEL: bextr32_a2_load:
250; X86-BMI1NOTBM:       # %bb.0:
251; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
252; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
253; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
254; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
255; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
256; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
257; X86-BMI1NOTBM-NEXT:    retl
258;
259; X86-BMI1BMI2-LABEL: bextr32_a2_load:
260; X86-BMI1BMI2:       # %bb.0:
261; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
262; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
263; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
264; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
265; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
266; X86-BMI1BMI2-NEXT:    retl
267;
268; X64-NOBMI-LABEL: bextr32_a2_load:
269; X64-NOBMI:       # %bb.0:
270; X64-NOBMI-NEXT:    movl %esi, %ecx
271; X64-NOBMI-NEXT:    movl (%rdi), %esi
272; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
273; X64-NOBMI-NEXT:    shrl %cl, %esi
274; X64-NOBMI-NEXT:    movl $1, %eax
275; X64-NOBMI-NEXT:    movl %edx, %ecx
276; X64-NOBMI-NEXT:    shll %cl, %eax
277; X64-NOBMI-NEXT:    decl %eax
278; X64-NOBMI-NEXT:    andl %esi, %eax
279; X64-NOBMI-NEXT:    retq
280;
281; X64-BMI1NOTBM-LABEL: bextr32_a2_load:
282; X64-BMI1NOTBM:       # %bb.0:
283; X64-BMI1NOTBM-NEXT:    shll $8, %edx
284; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
285; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
286; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
287; X64-BMI1NOTBM-NEXT:    retq
288;
289; X64-BMI1BMI2-LABEL: bextr32_a2_load:
290; X64-BMI1BMI2:       # %bb.0:
291; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
292; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
293; X64-BMI1BMI2-NEXT:    retq
294  %val = load i32, i32* %w
295  %shifted = lshr i32 %val, %numskipbits
296  %onebit = shl i32 1, %numlowbits
297  %mask = add nsw i32 %onebit, -1
298  %masked = and i32 %mask, %shifted
299  ret i32 %masked
300}
301
302define i32 @bextr32_a3_load_indexzext(i32* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
303; X86-NOBMI-LABEL: bextr32_a3_load_indexzext:
304; X86-NOBMI:       # %bb.0:
305; X86-NOBMI-NEXT:    pushl %esi
306; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
307; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
308; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
309; X86-NOBMI-NEXT:    movl (%eax), %esi
310; X86-NOBMI-NEXT:    shrl %cl, %esi
311; X86-NOBMI-NEXT:    movl $1, %eax
312; X86-NOBMI-NEXT:    movl %edx, %ecx
313; X86-NOBMI-NEXT:    shll %cl, %eax
314; X86-NOBMI-NEXT:    decl %eax
315; X86-NOBMI-NEXT:    andl %esi, %eax
316; X86-NOBMI-NEXT:    popl %esi
317; X86-NOBMI-NEXT:    retl
318;
319; X86-BMI1NOTBM-LABEL: bextr32_a3_load_indexzext:
320; X86-BMI1NOTBM:       # %bb.0:
321; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
322; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
323; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
324; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
325; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
326; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
327; X86-BMI1NOTBM-NEXT:    retl
328;
329; X86-BMI1BMI2-LABEL: bextr32_a3_load_indexzext:
330; X86-BMI1BMI2:       # %bb.0:
331; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
332; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
333; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
334; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
335; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
336; X86-BMI1BMI2-NEXT:    retl
337;
338; X64-NOBMI-LABEL: bextr32_a3_load_indexzext:
339; X64-NOBMI:       # %bb.0:
340; X64-NOBMI-NEXT:    movl %esi, %ecx
341; X64-NOBMI-NEXT:    movl (%rdi), %esi
342; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
343; X64-NOBMI-NEXT:    shrl %cl, %esi
344; X64-NOBMI-NEXT:    movl $1, %eax
345; X64-NOBMI-NEXT:    movl %edx, %ecx
346; X64-NOBMI-NEXT:    shll %cl, %eax
347; X64-NOBMI-NEXT:    decl %eax
348; X64-NOBMI-NEXT:    andl %esi, %eax
349; X64-NOBMI-NEXT:    retq
350;
351; X64-BMI1NOTBM-LABEL: bextr32_a3_load_indexzext:
352; X64-BMI1NOTBM:       # %bb.0:
353; X64-BMI1NOTBM-NEXT:    shll $8, %edx
354; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
355; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
356; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
357; X64-BMI1NOTBM-NEXT:    retq
358;
359; X64-BMI1BMI2-LABEL: bextr32_a3_load_indexzext:
360; X64-BMI1BMI2:       # %bb.0:
361; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
362; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
363; X64-BMI1BMI2-NEXT:    retq
364  %val = load i32, i32* %w
365  %skip = zext i8 %numskipbits to i32
366  %shifted = lshr i32 %val, %skip
367  %conv = zext i8 %numlowbits to i32
368  %onebit = shl i32 1, %conv
369  %mask = add nsw i32 %onebit, -1
370  %masked = and i32 %mask, %shifted
371  ret i32 %masked
372}
373
374define i32 @bextr32_a4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
375; X86-NOBMI-LABEL: bextr32_a4_commutative:
376; X86-NOBMI:       # %bb.0:
377; X86-NOBMI-NEXT:    pushl %esi
378; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
379; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
380; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
381; X86-NOBMI-NEXT:    shrl %cl, %esi
382; X86-NOBMI-NEXT:    movl $1, %eax
383; X86-NOBMI-NEXT:    movl %edx, %ecx
384; X86-NOBMI-NEXT:    shll %cl, %eax
385; X86-NOBMI-NEXT:    decl %eax
386; X86-NOBMI-NEXT:    andl %esi, %eax
387; X86-NOBMI-NEXT:    popl %esi
388; X86-NOBMI-NEXT:    retl
389;
390; X86-BMI1NOTBM-LABEL: bextr32_a4_commutative:
391; X86-BMI1NOTBM:       # %bb.0:
392; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
393; X86-BMI1NOTBM-NEXT:    shll $8, %eax
394; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
395; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
396; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
397; X86-BMI1NOTBM-NEXT:    retl
398;
399; X86-BMI1BMI2-LABEL: bextr32_a4_commutative:
400; X86-BMI1BMI2:       # %bb.0:
401; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
402; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
403; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
404; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
405; X86-BMI1BMI2-NEXT:    retl
406;
407; X64-NOBMI-LABEL: bextr32_a4_commutative:
408; X64-NOBMI:       # %bb.0:
409; X64-NOBMI-NEXT:    movl %esi, %ecx
410; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
411; X64-NOBMI-NEXT:    shrl %cl, %edi
412; X64-NOBMI-NEXT:    movl $1, %eax
413; X64-NOBMI-NEXT:    movl %edx, %ecx
414; X64-NOBMI-NEXT:    shll %cl, %eax
415; X64-NOBMI-NEXT:    decl %eax
416; X64-NOBMI-NEXT:    andl %edi, %eax
417; X64-NOBMI-NEXT:    retq
418;
419; X64-BMI1NOTBM-LABEL: bextr32_a4_commutative:
420; X64-BMI1NOTBM:       # %bb.0:
421; X64-BMI1NOTBM-NEXT:    shll $8, %edx
422; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
423; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
424; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
425; X64-BMI1NOTBM-NEXT:    retq
426;
427; X64-BMI1BMI2-LABEL: bextr32_a4_commutative:
428; X64-BMI1BMI2:       # %bb.0:
429; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
430; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
431; X64-BMI1BMI2-NEXT:    retq
432  %shifted = lshr i32 %val, %numskipbits
433  %onebit = shl i32 1, %numlowbits
434  %mask = add nsw i32 %onebit, -1
435  %masked = and i32 %shifted, %mask ; swapped order
436  ret i32 %masked
437}
438
439define i32 @bextr32_a5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
440; X86-NOBMI-LABEL: bextr32_a5_skipextrauses:
441; X86-NOBMI:       # %bb.0:
442; X86-NOBMI-NEXT:    pushl %edi
443; X86-NOBMI-NEXT:    pushl %esi
444; X86-NOBMI-NEXT:    pushl %eax
445; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
446; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
447; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
448; X86-NOBMI-NEXT:    movl %eax, %ecx
449; X86-NOBMI-NEXT:    shrl %cl, %edi
450; X86-NOBMI-NEXT:    movl $1, %esi
451; X86-NOBMI-NEXT:    movl %edx, %ecx
452; X86-NOBMI-NEXT:    shll %cl, %esi
453; X86-NOBMI-NEXT:    decl %esi
454; X86-NOBMI-NEXT:    andl %edi, %esi
455; X86-NOBMI-NEXT:    movl %eax, (%esp)
456; X86-NOBMI-NEXT:    calll use32
457; X86-NOBMI-NEXT:    movl %esi, %eax
458; X86-NOBMI-NEXT:    addl $4, %esp
459; X86-NOBMI-NEXT:    popl %esi
460; X86-NOBMI-NEXT:    popl %edi
461; X86-NOBMI-NEXT:    retl
462;
463; X86-BMI1NOTBM-LABEL: bextr32_a5_skipextrauses:
464; X86-BMI1NOTBM:       # %bb.0:
465; X86-BMI1NOTBM-NEXT:    pushl %esi
466; X86-BMI1NOTBM-NEXT:    subl $8, %esp
467; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
468; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
469; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
470; X86-BMI1NOTBM-NEXT:    movzbl %al, %edx
471; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
472; X86-BMI1NOTBM-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
473; X86-BMI1NOTBM-NEXT:    movl %eax, (%esp)
474; X86-BMI1NOTBM-NEXT:    calll use32
475; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
476; X86-BMI1NOTBM-NEXT:    addl $8, %esp
477; X86-BMI1NOTBM-NEXT:    popl %esi
478; X86-BMI1NOTBM-NEXT:    retl
479;
480; X86-BMI1BMI2-LABEL: bextr32_a5_skipextrauses:
481; X86-BMI1BMI2:       # %bb.0:
482; X86-BMI1BMI2-NEXT:    pushl %esi
483; X86-BMI1BMI2-NEXT:    subl $8, %esp
484; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
485; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
486; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
487; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %esi
488; X86-BMI1BMI2-NEXT:    movl %ecx, (%esp)
489; X86-BMI1BMI2-NEXT:    calll use32
490; X86-BMI1BMI2-NEXT:    movl %esi, %eax
491; X86-BMI1BMI2-NEXT:    addl $8, %esp
492; X86-BMI1BMI2-NEXT:    popl %esi
493; X86-BMI1BMI2-NEXT:    retl
494;
495; X64-NOBMI-LABEL: bextr32_a5_skipextrauses:
496; X64-NOBMI:       # %bb.0:
497; X64-NOBMI-NEXT:    pushq %rbx
498; X64-NOBMI-NEXT:    movl %esi, %ecx
499; X64-NOBMI-NEXT:    shrl %cl, %edi
500; X64-NOBMI-NEXT:    movl $1, %ebx
501; X64-NOBMI-NEXT:    movl %edx, %ecx
502; X64-NOBMI-NEXT:    shll %cl, %ebx
503; X64-NOBMI-NEXT:    decl %ebx
504; X64-NOBMI-NEXT:    andl %edi, %ebx
505; X64-NOBMI-NEXT:    movl %esi, %edi
506; X64-NOBMI-NEXT:    callq use32
507; X64-NOBMI-NEXT:    movl %ebx, %eax
508; X64-NOBMI-NEXT:    popq %rbx
509; X64-NOBMI-NEXT:    retq
510;
511; X64-BMI1NOTBM-LABEL: bextr32_a5_skipextrauses:
512; X64-BMI1NOTBM:       # %bb.0:
513; X64-BMI1NOTBM-NEXT:    pushq %rbx
514; X64-BMI1NOTBM-NEXT:    shll $8, %edx
515; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
516; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
517; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %ebx
518; X64-BMI1NOTBM-NEXT:    movl %esi, %edi
519; X64-BMI1NOTBM-NEXT:    callq use32
520; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
521; X64-BMI1NOTBM-NEXT:    popq %rbx
522; X64-BMI1NOTBM-NEXT:    retq
523;
524; X64-BMI1BMI2-LABEL: bextr32_a5_skipextrauses:
525; X64-BMI1BMI2:       # %bb.0:
526; X64-BMI1BMI2-NEXT:    pushq %rbx
527; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
528; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %ebx
529; X64-BMI1BMI2-NEXT:    movl %esi, %edi
530; X64-BMI1BMI2-NEXT:    callq use32
531; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
532; X64-BMI1BMI2-NEXT:    popq %rbx
533; X64-BMI1BMI2-NEXT:    retq
534  %shifted = lshr i32 %val, %numskipbits
535  %onebit = shl i32 1, %numlowbits
536  %mask = add nsw i32 %onebit, -1
537  %masked = and i32 %mask, %shifted
538  call void @use32(i32 %numskipbits)
539  ret i32 %masked
540}
541
542; 64-bit
543
544define i64 @bextr64_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
545; X86-NOBMI-LABEL: bextr64_a0:
546; X86-NOBMI:       # %bb.0:
547; X86-NOBMI-NEXT:    pushl %edi
548; X86-NOBMI-NEXT:    pushl %esi
549; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
550; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
551; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
552; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
553; X86-NOBMI-NEXT:    movl %eax, %edi
554; X86-NOBMI-NEXT:    shrl %cl, %edi
555; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
556; X86-NOBMI-NEXT:    testb $32, %cl
557; X86-NOBMI-NEXT:    je .LBB7_2
558; X86-NOBMI-NEXT:  # %bb.1:
559; X86-NOBMI-NEXT:    movl %edi, %esi
560; X86-NOBMI-NEXT:    xorl %edi, %edi
561; X86-NOBMI-NEXT:  .LBB7_2:
562; X86-NOBMI-NEXT:    movl $1, %eax
563; X86-NOBMI-NEXT:    xorl %edx, %edx
564; X86-NOBMI-NEXT:    movb %ch, %cl
565; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
566; X86-NOBMI-NEXT:    shll %cl, %eax
567; X86-NOBMI-NEXT:    testb $32, %ch
568; X86-NOBMI-NEXT:    je .LBB7_4
569; X86-NOBMI-NEXT:  # %bb.3:
570; X86-NOBMI-NEXT:    movl %eax, %edx
571; X86-NOBMI-NEXT:    xorl %eax, %eax
572; X86-NOBMI-NEXT:  .LBB7_4:
573; X86-NOBMI-NEXT:    addl $-1, %eax
574; X86-NOBMI-NEXT:    adcl $-1, %edx
575; X86-NOBMI-NEXT:    andl %esi, %eax
576; X86-NOBMI-NEXT:    andl %edi, %edx
577; X86-NOBMI-NEXT:    popl %esi
578; X86-NOBMI-NEXT:    popl %edi
579; X86-NOBMI-NEXT:    retl
580;
581; X86-BMI1NOTBM-LABEL: bextr64_a0:
582; X86-BMI1NOTBM:       # %bb.0:
583; X86-BMI1NOTBM-NEXT:    pushl %edi
584; X86-BMI1NOTBM-NEXT:    pushl %esi
585; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
586; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
587; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
588; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
589; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
590; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
591; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
592; X86-BMI1NOTBM-NEXT:    testb $32, %cl
593; X86-BMI1NOTBM-NEXT:    je .LBB7_2
594; X86-BMI1NOTBM-NEXT:  # %bb.1:
595; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
596; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
597; X86-BMI1NOTBM-NEXT:  .LBB7_2:
598; X86-BMI1NOTBM-NEXT:    movl $1, %eax
599; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
600; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
601; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
602; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
603; X86-BMI1NOTBM-NEXT:    testb $32, %ch
604; X86-BMI1NOTBM-NEXT:    je .LBB7_4
605; X86-BMI1NOTBM-NEXT:  # %bb.3:
606; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
607; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
608; X86-BMI1NOTBM-NEXT:  .LBB7_4:
609; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
610; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
611; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
612; X86-BMI1NOTBM-NEXT:    andl %edi, %edx
613; X86-BMI1NOTBM-NEXT:    popl %esi
614; X86-BMI1NOTBM-NEXT:    popl %edi
615; X86-BMI1NOTBM-NEXT:    retl
616;
617; X86-BMI1BMI2-LABEL: bextr64_a0:
618; X86-BMI1BMI2:       # %bb.0:
619; X86-BMI1BMI2-NEXT:    pushl %ebx
620; X86-BMI1BMI2-NEXT:    pushl %edi
621; X86-BMI1BMI2-NEXT:    pushl %esi
622; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
623; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
624; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
625; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
626; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
627; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
628; X86-BMI1BMI2-NEXT:    testb $32, %cl
629; X86-BMI1BMI2-NEXT:    je .LBB7_2
630; X86-BMI1BMI2-NEXT:  # %bb.1:
631; X86-BMI1BMI2-NEXT:    movl %edi, %esi
632; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
633; X86-BMI1BMI2-NEXT:  .LBB7_2:
634; X86-BMI1BMI2-NEXT:    movl $1, %eax
635; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
636; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
637; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
638; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
639; X86-BMI1BMI2-NEXT:    testb $32, %bl
640; X86-BMI1BMI2-NEXT:    je .LBB7_4
641; X86-BMI1BMI2-NEXT:  # %bb.3:
642; X86-BMI1BMI2-NEXT:    movl %eax, %edx
643; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
644; X86-BMI1BMI2-NEXT:  .LBB7_4:
645; X86-BMI1BMI2-NEXT:    addl $-1, %eax
646; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
647; X86-BMI1BMI2-NEXT:    andl %esi, %eax
648; X86-BMI1BMI2-NEXT:    andl %edi, %edx
649; X86-BMI1BMI2-NEXT:    popl %esi
650; X86-BMI1BMI2-NEXT:    popl %edi
651; X86-BMI1BMI2-NEXT:    popl %ebx
652; X86-BMI1BMI2-NEXT:    retl
653;
654; X64-NOBMI-LABEL: bextr64_a0:
655; X64-NOBMI:       # %bb.0:
656; X64-NOBMI-NEXT:    movq %rsi, %rcx
657; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
658; X64-NOBMI-NEXT:    shrq %cl, %rdi
659; X64-NOBMI-NEXT:    movl $1, %eax
660; X64-NOBMI-NEXT:    movl %edx, %ecx
661; X64-NOBMI-NEXT:    shlq %cl, %rax
662; X64-NOBMI-NEXT:    decq %rax
663; X64-NOBMI-NEXT:    andq %rdi, %rax
664; X64-NOBMI-NEXT:    retq
665;
666; X64-BMI1NOTBM-LABEL: bextr64_a0:
667; X64-BMI1NOTBM:       # %bb.0:
668; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
669; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
670; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
671; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
672; X64-BMI1NOTBM-NEXT:    retq
673;
674; X64-BMI1BMI2-LABEL: bextr64_a0:
675; X64-BMI1BMI2:       # %bb.0:
676; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
677; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
678; X64-BMI1BMI2-NEXT:    retq
679  %shifted = lshr i64 %val, %numskipbits
680  %onebit = shl i64 1, %numlowbits
681  %mask = add nsw i64 %onebit, -1
682  %masked = and i64 %mask, %shifted
683  ret i64 %masked
684}
685
686define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
687; X86-NOBMI-LABEL: bextr64_a0_arithmetic:
688; X86-NOBMI:       # %bb.0:
689; X86-NOBMI-NEXT:    pushl %edi
690; X86-NOBMI-NEXT:    pushl %esi
691; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
692; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
693; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
694; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
695; X86-NOBMI-NEXT:    movl %eax, %esi
696; X86-NOBMI-NEXT:    sarl %cl, %esi
697; X86-NOBMI-NEXT:    shrdl %cl, %eax, %edi
698; X86-NOBMI-NEXT:    testb $32, %cl
699; X86-NOBMI-NEXT:    je .LBB8_2
700; X86-NOBMI-NEXT:  # %bb.1:
701; X86-NOBMI-NEXT:    sarl $31, %eax
702; X86-NOBMI-NEXT:    movl %esi, %edi
703; X86-NOBMI-NEXT:    movl %eax, %esi
704; X86-NOBMI-NEXT:  .LBB8_2:
705; X86-NOBMI-NEXT:    movl $1, %eax
706; X86-NOBMI-NEXT:    xorl %edx, %edx
707; X86-NOBMI-NEXT:    movb %ch, %cl
708; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
709; X86-NOBMI-NEXT:    shll %cl, %eax
710; X86-NOBMI-NEXT:    testb $32, %ch
711; X86-NOBMI-NEXT:    je .LBB8_4
712; X86-NOBMI-NEXT:  # %bb.3:
713; X86-NOBMI-NEXT:    movl %eax, %edx
714; X86-NOBMI-NEXT:    xorl %eax, %eax
715; X86-NOBMI-NEXT:  .LBB8_4:
716; X86-NOBMI-NEXT:    addl $-1, %eax
717; X86-NOBMI-NEXT:    adcl $-1, %edx
718; X86-NOBMI-NEXT:    andl %edi, %eax
719; X86-NOBMI-NEXT:    andl %esi, %edx
720; X86-NOBMI-NEXT:    popl %esi
721; X86-NOBMI-NEXT:    popl %edi
722; X86-NOBMI-NEXT:    retl
723;
724; X86-BMI1NOTBM-LABEL: bextr64_a0_arithmetic:
725; X86-BMI1NOTBM:       # %bb.0:
726; X86-BMI1NOTBM-NEXT:    pushl %edi
727; X86-BMI1NOTBM-NEXT:    pushl %esi
728; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
729; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
730; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
731; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
732; X86-BMI1NOTBM-NEXT:    movl %eax, %esi
733; X86-BMI1NOTBM-NEXT:    sarl %cl, %esi
734; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %edi
735; X86-BMI1NOTBM-NEXT:    testb $32, %cl
736; X86-BMI1NOTBM-NEXT:    je .LBB8_2
737; X86-BMI1NOTBM-NEXT:  # %bb.1:
738; X86-BMI1NOTBM-NEXT:    sarl $31, %eax
739; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
740; X86-BMI1NOTBM-NEXT:    movl %eax, %esi
741; X86-BMI1NOTBM-NEXT:  .LBB8_2:
742; X86-BMI1NOTBM-NEXT:    movl $1, %eax
743; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
744; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
745; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
746; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
747; X86-BMI1NOTBM-NEXT:    testb $32, %ch
748; X86-BMI1NOTBM-NEXT:    je .LBB8_4
749; X86-BMI1NOTBM-NEXT:  # %bb.3:
750; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
751; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
752; X86-BMI1NOTBM-NEXT:  .LBB8_4:
753; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
754; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
755; X86-BMI1NOTBM-NEXT:    andl %edi, %eax
756; X86-BMI1NOTBM-NEXT:    andl %esi, %edx
757; X86-BMI1NOTBM-NEXT:    popl %esi
758; X86-BMI1NOTBM-NEXT:    popl %edi
759; X86-BMI1NOTBM-NEXT:    retl
760;
761; X86-BMI1BMI2-LABEL: bextr64_a0_arithmetic:
762; X86-BMI1BMI2:       # %bb.0:
763; X86-BMI1BMI2-NEXT:    pushl %ebx
764; X86-BMI1BMI2-NEXT:    pushl %edi
765; X86-BMI1BMI2-NEXT:    pushl %esi
766; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
767; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
768; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
769; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
770; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
771; X86-BMI1BMI2-NEXT:    sarxl %ecx, %eax, %edi
772; X86-BMI1BMI2-NEXT:    testb $32, %cl
773; X86-BMI1BMI2-NEXT:    je .LBB8_2
774; X86-BMI1BMI2-NEXT:  # %bb.1:
775; X86-BMI1BMI2-NEXT:    sarl $31, %eax
776; X86-BMI1BMI2-NEXT:    movl %edi, %esi
777; X86-BMI1BMI2-NEXT:    movl %eax, %edi
778; X86-BMI1BMI2-NEXT:  .LBB8_2:
779; X86-BMI1BMI2-NEXT:    movl $1, %eax
780; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
781; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
782; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
783; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
784; X86-BMI1BMI2-NEXT:    testb $32, %bl
785; X86-BMI1BMI2-NEXT:    je .LBB8_4
786; X86-BMI1BMI2-NEXT:  # %bb.3:
787; X86-BMI1BMI2-NEXT:    movl %eax, %edx
788; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
789; X86-BMI1BMI2-NEXT:  .LBB8_4:
790; X86-BMI1BMI2-NEXT:    addl $-1, %eax
791; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
792; X86-BMI1BMI2-NEXT:    andl %esi, %eax
793; X86-BMI1BMI2-NEXT:    andl %edi, %edx
794; X86-BMI1BMI2-NEXT:    popl %esi
795; X86-BMI1BMI2-NEXT:    popl %edi
796; X86-BMI1BMI2-NEXT:    popl %ebx
797; X86-BMI1BMI2-NEXT:    retl
798;
799; X64-NOBMI-LABEL: bextr64_a0_arithmetic:
800; X64-NOBMI:       # %bb.0:
801; X64-NOBMI-NEXT:    movq %rsi, %rcx
802; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
803; X64-NOBMI-NEXT:    sarq %cl, %rdi
804; X64-NOBMI-NEXT:    movl $1, %eax
805; X64-NOBMI-NEXT:    movl %edx, %ecx
806; X64-NOBMI-NEXT:    shlq %cl, %rax
807; X64-NOBMI-NEXT:    decq %rax
808; X64-NOBMI-NEXT:    andq %rdi, %rax
809; X64-NOBMI-NEXT:    retq
810;
811; X64-BMI1NOTBM-LABEL: bextr64_a0_arithmetic:
812; X64-BMI1NOTBM:       # %bb.0:
813; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
814; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
815; X64-BMI1NOTBM-NEXT:    sarq %cl, %rdi
816; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
817; X64-BMI1NOTBM-NEXT:    bextrq %rdx, %rdi, %rax
818; X64-BMI1NOTBM-NEXT:    retq
819;
820; X64-BMI1BMI2-LABEL: bextr64_a0_arithmetic:
821; X64-BMI1BMI2:       # %bb.0:
822; X64-BMI1BMI2-NEXT:    sarxq %rsi, %rdi, %rax
823; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
824; X64-BMI1BMI2-NEXT:    retq
825  %shifted = ashr i64 %val, %numskipbits
826  %onebit = shl i64 1, %numlowbits
827  %mask = add nsw i64 %onebit, -1
828  %masked = and i64 %mask, %shifted
829  ret i64 %masked
830}
831
832define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
833; X86-NOBMI-LABEL: bextr64_a1_indexzext:
834; X86-NOBMI:       # %bb.0:
835; X86-NOBMI-NEXT:    pushl %edi
836; X86-NOBMI-NEXT:    pushl %esi
837; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
838; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
839; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
840; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
841; X86-NOBMI-NEXT:    movl %eax, %edi
842; X86-NOBMI-NEXT:    shrl %cl, %edi
843; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
844; X86-NOBMI-NEXT:    testb $32, %cl
845; X86-NOBMI-NEXT:    je .LBB9_2
846; X86-NOBMI-NEXT:  # %bb.1:
847; X86-NOBMI-NEXT:    movl %edi, %esi
848; X86-NOBMI-NEXT:    xorl %edi, %edi
849; X86-NOBMI-NEXT:  .LBB9_2:
850; X86-NOBMI-NEXT:    movl $1, %eax
851; X86-NOBMI-NEXT:    xorl %edx, %edx
852; X86-NOBMI-NEXT:    movb %ch, %cl
853; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
854; X86-NOBMI-NEXT:    shll %cl, %eax
855; X86-NOBMI-NEXT:    testb $32, %ch
856; X86-NOBMI-NEXT:    je .LBB9_4
857; X86-NOBMI-NEXT:  # %bb.3:
858; X86-NOBMI-NEXT:    movl %eax, %edx
859; X86-NOBMI-NEXT:    xorl %eax, %eax
860; X86-NOBMI-NEXT:  .LBB9_4:
861; X86-NOBMI-NEXT:    addl $-1, %eax
862; X86-NOBMI-NEXT:    adcl $-1, %edx
863; X86-NOBMI-NEXT:    andl %esi, %eax
864; X86-NOBMI-NEXT:    andl %edi, %edx
865; X86-NOBMI-NEXT:    popl %esi
866; X86-NOBMI-NEXT:    popl %edi
867; X86-NOBMI-NEXT:    retl
868;
869; X86-BMI1NOTBM-LABEL: bextr64_a1_indexzext:
870; X86-BMI1NOTBM:       # %bb.0:
871; X86-BMI1NOTBM-NEXT:    pushl %edi
872; X86-BMI1NOTBM-NEXT:    pushl %esi
873; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
874; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
875; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
876; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
877; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
878; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
879; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
880; X86-BMI1NOTBM-NEXT:    testb $32, %cl
881; X86-BMI1NOTBM-NEXT:    je .LBB9_2
882; X86-BMI1NOTBM-NEXT:  # %bb.1:
883; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
884; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
885; X86-BMI1NOTBM-NEXT:  .LBB9_2:
886; X86-BMI1NOTBM-NEXT:    movl $1, %eax
887; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
888; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
889; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
890; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
891; X86-BMI1NOTBM-NEXT:    testb $32, %ch
892; X86-BMI1NOTBM-NEXT:    je .LBB9_4
893; X86-BMI1NOTBM-NEXT:  # %bb.3:
894; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
895; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
896; X86-BMI1NOTBM-NEXT:  .LBB9_4:
897; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
898; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
899; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
900; X86-BMI1NOTBM-NEXT:    andl %edi, %edx
901; X86-BMI1NOTBM-NEXT:    popl %esi
902; X86-BMI1NOTBM-NEXT:    popl %edi
903; X86-BMI1NOTBM-NEXT:    retl
904;
905; X86-BMI1BMI2-LABEL: bextr64_a1_indexzext:
906; X86-BMI1BMI2:       # %bb.0:
907; X86-BMI1BMI2-NEXT:    pushl %ebx
908; X86-BMI1BMI2-NEXT:    pushl %edi
909; X86-BMI1BMI2-NEXT:    pushl %esi
910; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
911; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
912; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
913; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
914; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
915; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
916; X86-BMI1BMI2-NEXT:    testb $32, %cl
917; X86-BMI1BMI2-NEXT:    je .LBB9_2
918; X86-BMI1BMI2-NEXT:  # %bb.1:
919; X86-BMI1BMI2-NEXT:    movl %edi, %esi
920; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
921; X86-BMI1BMI2-NEXT:  .LBB9_2:
922; X86-BMI1BMI2-NEXT:    movl $1, %eax
923; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
924; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
925; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
926; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
927; X86-BMI1BMI2-NEXT:    testb $32, %bl
928; X86-BMI1BMI2-NEXT:    je .LBB9_4
929; X86-BMI1BMI2-NEXT:  # %bb.3:
930; X86-BMI1BMI2-NEXT:    movl %eax, %edx
931; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
932; X86-BMI1BMI2-NEXT:  .LBB9_4:
933; X86-BMI1BMI2-NEXT:    addl $-1, %eax
934; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
935; X86-BMI1BMI2-NEXT:    andl %esi, %eax
936; X86-BMI1BMI2-NEXT:    andl %edi, %edx
937; X86-BMI1BMI2-NEXT:    popl %esi
938; X86-BMI1BMI2-NEXT:    popl %edi
939; X86-BMI1BMI2-NEXT:    popl %ebx
940; X86-BMI1BMI2-NEXT:    retl
941;
942; X64-NOBMI-LABEL: bextr64_a1_indexzext:
943; X64-NOBMI:       # %bb.0:
944; X64-NOBMI-NEXT:    movl %esi, %ecx
945; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
946; X64-NOBMI-NEXT:    shrq %cl, %rdi
947; X64-NOBMI-NEXT:    movl $1, %eax
948; X64-NOBMI-NEXT:    movl %edx, %ecx
949; X64-NOBMI-NEXT:    shlq %cl, %rax
950; X64-NOBMI-NEXT:    decq %rax
951; X64-NOBMI-NEXT:    andq %rdi, %rax
952; X64-NOBMI-NEXT:    retq
953;
954; X64-BMI1NOTBM-LABEL: bextr64_a1_indexzext:
955; X64-BMI1NOTBM:       # %bb.0:
956; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
957; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
958; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
959; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
960; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
961; X64-BMI1NOTBM-NEXT:    retq
962;
963; X64-BMI1BMI2-LABEL: bextr64_a1_indexzext:
964; X64-BMI1BMI2:       # %bb.0:
965; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
966; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
967; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
968; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
969; X64-BMI1BMI2-NEXT:    retq
970  %skip = zext i8 %numskipbits to i64
971  %shifted = lshr i64 %val, %skip
972  %conv = zext i8 %numlowbits to i64
973  %onebit = shl i64 1, %conv
974  %mask = add nsw i64 %onebit, -1
975  %masked = and i64 %mask, %shifted
976  ret i64 %masked
977}
978
979define i64 @bextr64_a2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
980; X86-NOBMI-LABEL: bextr64_a2_load:
981; X86-NOBMI:       # %bb.0:
982; X86-NOBMI-NEXT:    pushl %edi
983; X86-NOBMI-NEXT:    pushl %esi
984; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
985; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
986; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
987; X86-NOBMI-NEXT:    movl (%eax), %esi
988; X86-NOBMI-NEXT:    movl 4(%eax), %eax
989; X86-NOBMI-NEXT:    movl %eax, %edi
990; X86-NOBMI-NEXT:    shrl %cl, %edi
991; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
992; X86-NOBMI-NEXT:    testb $32, %cl
993; X86-NOBMI-NEXT:    je .LBB10_2
994; X86-NOBMI-NEXT:  # %bb.1:
995; X86-NOBMI-NEXT:    movl %edi, %esi
996; X86-NOBMI-NEXT:    xorl %edi, %edi
997; X86-NOBMI-NEXT:  .LBB10_2:
998; X86-NOBMI-NEXT:    movl $1, %eax
999; X86-NOBMI-NEXT:    xorl %edx, %edx
1000; X86-NOBMI-NEXT:    movb %ch, %cl
1001; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
1002; X86-NOBMI-NEXT:    shll %cl, %eax
1003; X86-NOBMI-NEXT:    testb $32, %ch
1004; X86-NOBMI-NEXT:    je .LBB10_4
1005; X86-NOBMI-NEXT:  # %bb.3:
1006; X86-NOBMI-NEXT:    movl %eax, %edx
1007; X86-NOBMI-NEXT:    xorl %eax, %eax
1008; X86-NOBMI-NEXT:  .LBB10_4:
1009; X86-NOBMI-NEXT:    addl $-1, %eax
1010; X86-NOBMI-NEXT:    adcl $-1, %edx
1011; X86-NOBMI-NEXT:    andl %esi, %eax
1012; X86-NOBMI-NEXT:    andl %edi, %edx
1013; X86-NOBMI-NEXT:    popl %esi
1014; X86-NOBMI-NEXT:    popl %edi
1015; X86-NOBMI-NEXT:    retl
1016;
1017; X86-BMI1NOTBM-LABEL: bextr64_a2_load:
1018; X86-BMI1NOTBM:       # %bb.0:
1019; X86-BMI1NOTBM-NEXT:    pushl %edi
1020; X86-BMI1NOTBM-NEXT:    pushl %esi
1021; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
1022; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1023; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1024; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
1025; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
1026; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
1027; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
1028; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
1029; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1030; X86-BMI1NOTBM-NEXT:    je .LBB10_2
1031; X86-BMI1NOTBM-NEXT:  # %bb.1:
1032; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
1033; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
1034; X86-BMI1NOTBM-NEXT:  .LBB10_2:
1035; X86-BMI1NOTBM-NEXT:    movl $1, %eax
1036; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
1037; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
1038; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
1039; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
1040; X86-BMI1NOTBM-NEXT:    testb $32, %ch
1041; X86-BMI1NOTBM-NEXT:    je .LBB10_4
1042; X86-BMI1NOTBM-NEXT:  # %bb.3:
1043; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
1044; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
1045; X86-BMI1NOTBM-NEXT:  .LBB10_4:
1046; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
1047; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
1048; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
1049; X86-BMI1NOTBM-NEXT:    andl %edi, %edx
1050; X86-BMI1NOTBM-NEXT:    popl %esi
1051; X86-BMI1NOTBM-NEXT:    popl %edi
1052; X86-BMI1NOTBM-NEXT:    retl
1053;
1054; X86-BMI1BMI2-LABEL: bextr64_a2_load:
1055; X86-BMI1BMI2:       # %bb.0:
1056; X86-BMI1BMI2-NEXT:    pushl %ebx
1057; X86-BMI1BMI2-NEXT:    pushl %edi
1058; X86-BMI1BMI2-NEXT:    pushl %esi
1059; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1060; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1061; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1062; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
1063; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
1064; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
1065; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
1066; X86-BMI1BMI2-NEXT:    testb $32, %cl
1067; X86-BMI1BMI2-NEXT:    je .LBB10_2
1068; X86-BMI1BMI2-NEXT:  # %bb.1:
1069; X86-BMI1BMI2-NEXT:    movl %edi, %esi
1070; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
1071; X86-BMI1BMI2-NEXT:  .LBB10_2:
1072; X86-BMI1BMI2-NEXT:    movl $1, %eax
1073; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
1074; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
1075; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
1076; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
1077; X86-BMI1BMI2-NEXT:    testb $32, %bl
1078; X86-BMI1BMI2-NEXT:    je .LBB10_4
1079; X86-BMI1BMI2-NEXT:  # %bb.3:
1080; X86-BMI1BMI2-NEXT:    movl %eax, %edx
1081; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
1082; X86-BMI1BMI2-NEXT:  .LBB10_4:
1083; X86-BMI1BMI2-NEXT:    addl $-1, %eax
1084; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
1085; X86-BMI1BMI2-NEXT:    andl %esi, %eax
1086; X86-BMI1BMI2-NEXT:    andl %edi, %edx
1087; X86-BMI1BMI2-NEXT:    popl %esi
1088; X86-BMI1BMI2-NEXT:    popl %edi
1089; X86-BMI1BMI2-NEXT:    popl %ebx
1090; X86-BMI1BMI2-NEXT:    retl
1091;
1092; X64-NOBMI-LABEL: bextr64_a2_load:
1093; X64-NOBMI:       # %bb.0:
1094; X64-NOBMI-NEXT:    movq %rsi, %rcx
1095; X64-NOBMI-NEXT:    movq (%rdi), %rsi
1096; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1097; X64-NOBMI-NEXT:    shrq %cl, %rsi
1098; X64-NOBMI-NEXT:    movl $1, %eax
1099; X64-NOBMI-NEXT:    movl %edx, %ecx
1100; X64-NOBMI-NEXT:    shlq %cl, %rax
1101; X64-NOBMI-NEXT:    decq %rax
1102; X64-NOBMI-NEXT:    andq %rsi, %rax
1103; X64-NOBMI-NEXT:    retq
1104;
1105; X64-BMI1NOTBM-LABEL: bextr64_a2_load:
1106; X64-BMI1NOTBM:       # %bb.0:
1107; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
1108; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1109; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
1110; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
1111; X64-BMI1NOTBM-NEXT:    retq
1112;
1113; X64-BMI1BMI2-LABEL: bextr64_a2_load:
1114; X64-BMI1BMI2:       # %bb.0:
1115; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1116; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1117; X64-BMI1BMI2-NEXT:    retq
1118  %val = load i64, i64* %w
1119  %shifted = lshr i64 %val, %numskipbits
1120  %onebit = shl i64 1, %numlowbits
1121  %mask = add nsw i64 %onebit, -1
1122  %masked = and i64 %mask, %shifted
1123  ret i64 %masked
1124}
1125
1126define i64 @bextr64_a3_load_indexzext(i64* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
1127; X86-NOBMI-LABEL: bextr64_a3_load_indexzext:
1128; X86-NOBMI:       # %bb.0:
1129; X86-NOBMI-NEXT:    pushl %edi
1130; X86-NOBMI-NEXT:    pushl %esi
1131; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
1132; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1133; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1134; X86-NOBMI-NEXT:    movl (%eax), %esi
1135; X86-NOBMI-NEXT:    movl 4(%eax), %eax
1136; X86-NOBMI-NEXT:    movl %eax, %edi
1137; X86-NOBMI-NEXT:    shrl %cl, %edi
1138; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
1139; X86-NOBMI-NEXT:    testb $32, %cl
1140; X86-NOBMI-NEXT:    je .LBB11_2
1141; X86-NOBMI-NEXT:  # %bb.1:
1142; X86-NOBMI-NEXT:    movl %edi, %esi
1143; X86-NOBMI-NEXT:    xorl %edi, %edi
1144; X86-NOBMI-NEXT:  .LBB11_2:
1145; X86-NOBMI-NEXT:    movl $1, %eax
1146; X86-NOBMI-NEXT:    xorl %edx, %edx
1147; X86-NOBMI-NEXT:    movb %ch, %cl
1148; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
1149; X86-NOBMI-NEXT:    shll %cl, %eax
1150; X86-NOBMI-NEXT:    testb $32, %ch
1151; X86-NOBMI-NEXT:    je .LBB11_4
1152; X86-NOBMI-NEXT:  # %bb.3:
1153; X86-NOBMI-NEXT:    movl %eax, %edx
1154; X86-NOBMI-NEXT:    xorl %eax, %eax
1155; X86-NOBMI-NEXT:  .LBB11_4:
1156; X86-NOBMI-NEXT:    addl $-1, %eax
1157; X86-NOBMI-NEXT:    adcl $-1, %edx
1158; X86-NOBMI-NEXT:    andl %esi, %eax
1159; X86-NOBMI-NEXT:    andl %edi, %edx
1160; X86-NOBMI-NEXT:    popl %esi
1161; X86-NOBMI-NEXT:    popl %edi
1162; X86-NOBMI-NEXT:    retl
1163;
1164; X86-BMI1NOTBM-LABEL: bextr64_a3_load_indexzext:
1165; X86-BMI1NOTBM:       # %bb.0:
1166; X86-BMI1NOTBM-NEXT:    pushl %edi
1167; X86-BMI1NOTBM-NEXT:    pushl %esi
1168; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
1169; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1170; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1171; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
1172; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
1173; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
1174; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
1175; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
1176; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1177; X86-BMI1NOTBM-NEXT:    je .LBB11_2
1178; X86-BMI1NOTBM-NEXT:  # %bb.1:
1179; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
1180; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
1181; X86-BMI1NOTBM-NEXT:  .LBB11_2:
1182; X86-BMI1NOTBM-NEXT:    movl $1, %eax
1183; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
1184; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
1185; X86-BMI1NOTBM-NEXT:    shldl %cl, %eax, %edx
1186; X86-BMI1NOTBM-NEXT:    shll %cl, %eax
1187; X86-BMI1NOTBM-NEXT:    testb $32, %ch
1188; X86-BMI1NOTBM-NEXT:    je .LBB11_4
1189; X86-BMI1NOTBM-NEXT:  # %bb.3:
1190; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
1191; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
1192; X86-BMI1NOTBM-NEXT:  .LBB11_4:
1193; X86-BMI1NOTBM-NEXT:    addl $-1, %eax
1194; X86-BMI1NOTBM-NEXT:    adcl $-1, %edx
1195; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
1196; X86-BMI1NOTBM-NEXT:    andl %edi, %edx
1197; X86-BMI1NOTBM-NEXT:    popl %esi
1198; X86-BMI1NOTBM-NEXT:    popl %edi
1199; X86-BMI1NOTBM-NEXT:    retl
1200;
1201; X86-BMI1BMI2-LABEL: bextr64_a3_load_indexzext:
1202; X86-BMI1BMI2:       # %bb.0:
1203; X86-BMI1BMI2-NEXT:    pushl %ebx
1204; X86-BMI1BMI2-NEXT:    pushl %edi
1205; X86-BMI1BMI2-NEXT:    pushl %esi
1206; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1207; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1208; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1209; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
1210; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
1211; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
1212; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
1213; X86-BMI1BMI2-NEXT:    testb $32, %cl
1214; X86-BMI1BMI2-NEXT:    je .LBB11_2
1215; X86-BMI1BMI2-NEXT:  # %bb.1:
1216; X86-BMI1BMI2-NEXT:    movl %edi, %esi
1217; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
1218; X86-BMI1BMI2-NEXT:  .LBB11_2:
1219; X86-BMI1BMI2-NEXT:    movl $1, %eax
1220; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
1221; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
1222; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
1223; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
1224; X86-BMI1BMI2-NEXT:    testb $32, %bl
1225; X86-BMI1BMI2-NEXT:    je .LBB11_4
1226; X86-BMI1BMI2-NEXT:  # %bb.3:
1227; X86-BMI1BMI2-NEXT:    movl %eax, %edx
1228; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
1229; X86-BMI1BMI2-NEXT:  .LBB11_4:
1230; X86-BMI1BMI2-NEXT:    addl $-1, %eax
1231; X86-BMI1BMI2-NEXT:    adcl $-1, %edx
1232; X86-BMI1BMI2-NEXT:    andl %esi, %eax
1233; X86-BMI1BMI2-NEXT:    andl %edi, %edx
1234; X86-BMI1BMI2-NEXT:    popl %esi
1235; X86-BMI1BMI2-NEXT:    popl %edi
1236; X86-BMI1BMI2-NEXT:    popl %ebx
1237; X86-BMI1BMI2-NEXT:    retl
1238;
1239; X64-NOBMI-LABEL: bextr64_a3_load_indexzext:
1240; X64-NOBMI:       # %bb.0:
1241; X64-NOBMI-NEXT:    movl %esi, %ecx
1242; X64-NOBMI-NEXT:    movq (%rdi), %rsi
1243; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1244; X64-NOBMI-NEXT:    shrq %cl, %rsi
1245; X64-NOBMI-NEXT:    movl $1, %eax
1246; X64-NOBMI-NEXT:    movl %edx, %ecx
1247; X64-NOBMI-NEXT:    shlq %cl, %rax
1248; X64-NOBMI-NEXT:    decq %rax
1249; X64-NOBMI-NEXT:    andq %rsi, %rax
1250; X64-NOBMI-NEXT:    retq
1251;
1252; X64-BMI1NOTBM-LABEL: bextr64_a3_load_indexzext:
1253; X64-BMI1NOTBM:       # %bb.0:
1254; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
1255; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
1256; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1257; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
1258; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
1259; X64-BMI1NOTBM-NEXT:    retq
1260;
1261; X64-BMI1BMI2-LABEL: bextr64_a3_load_indexzext:
1262; X64-BMI1BMI2:       # %bb.0:
1263; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
1264; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1265; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1266; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1267; X64-BMI1BMI2-NEXT:    retq
1268  %val = load i64, i64* %w
1269  %skip = zext i8 %numskipbits to i64
1270  %shifted = lshr i64 %val, %skip
1271  %conv = zext i8 %numlowbits to i64
1272  %onebit = shl i64 1, %conv
1273  %mask = add nsw i64 %onebit, -1
1274  %masked = and i64 %mask, %shifted
1275  ret i64 %masked
1276}
1277
1278define i64 @bextr64_a4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1279; X86-NOBMI-LABEL: bextr64_a4_commutative:
1280; X86-NOBMI:       # %bb.0:
1281; X86-NOBMI-NEXT:    pushl %edi
1282; X86-NOBMI-NEXT:    pushl %esi
1283; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
1284; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1285; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1286; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1287; X86-NOBMI-NEXT:    movl %esi, %edx
1288; X86-NOBMI-NEXT:    shrl %cl, %edx
1289; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
1290; X86-NOBMI-NEXT:    testb $32, %cl
1291; X86-NOBMI-NEXT:    je .LBB12_2
1292; X86-NOBMI-NEXT:  # %bb.1:
1293; X86-NOBMI-NEXT:    movl %edx, %eax
1294; X86-NOBMI-NEXT:    xorl %edx, %edx
1295; X86-NOBMI-NEXT:  .LBB12_2:
1296; X86-NOBMI-NEXT:    movl $1, %esi
1297; X86-NOBMI-NEXT:    xorl %edi, %edi
1298; X86-NOBMI-NEXT:    movb %ch, %cl
1299; X86-NOBMI-NEXT:    shldl %cl, %esi, %edi
1300; X86-NOBMI-NEXT:    shll %cl, %esi
1301; X86-NOBMI-NEXT:    testb $32, %ch
1302; X86-NOBMI-NEXT:    je .LBB12_4
1303; X86-NOBMI-NEXT:  # %bb.3:
1304; X86-NOBMI-NEXT:    movl %esi, %edi
1305; X86-NOBMI-NEXT:    xorl %esi, %esi
1306; X86-NOBMI-NEXT:  .LBB12_4:
1307; X86-NOBMI-NEXT:    addl $-1, %esi
1308; X86-NOBMI-NEXT:    adcl $-1, %edi
1309; X86-NOBMI-NEXT:    andl %esi, %eax
1310; X86-NOBMI-NEXT:    andl %edi, %edx
1311; X86-NOBMI-NEXT:    popl %esi
1312; X86-NOBMI-NEXT:    popl %edi
1313; X86-NOBMI-NEXT:    retl
1314;
1315; X86-BMI1NOTBM-LABEL: bextr64_a4_commutative:
1316; X86-BMI1NOTBM:       # %bb.0:
1317; X86-BMI1NOTBM-NEXT:    pushl %edi
1318; X86-BMI1NOTBM-NEXT:    pushl %esi
1319; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %ch
1320; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1321; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1322; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
1323; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
1324; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
1325; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %eax
1326; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1327; X86-BMI1NOTBM-NEXT:    je .LBB12_2
1328; X86-BMI1NOTBM-NEXT:  # %bb.1:
1329; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
1330; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
1331; X86-BMI1NOTBM-NEXT:  .LBB12_2:
1332; X86-BMI1NOTBM-NEXT:    movl $1, %esi
1333; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
1334; X86-BMI1NOTBM-NEXT:    movb %ch, %cl
1335; X86-BMI1NOTBM-NEXT:    shldl %cl, %esi, %edi
1336; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1337; X86-BMI1NOTBM-NEXT:    testb $32, %ch
1338; X86-BMI1NOTBM-NEXT:    je .LBB12_4
1339; X86-BMI1NOTBM-NEXT:  # %bb.3:
1340; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
1341; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1342; X86-BMI1NOTBM-NEXT:  .LBB12_4:
1343; X86-BMI1NOTBM-NEXT:    addl $-1, %esi
1344; X86-BMI1NOTBM-NEXT:    adcl $-1, %edi
1345; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
1346; X86-BMI1NOTBM-NEXT:    andl %edi, %edx
1347; X86-BMI1NOTBM-NEXT:    popl %esi
1348; X86-BMI1NOTBM-NEXT:    popl %edi
1349; X86-BMI1NOTBM-NEXT:    retl
1350;
1351; X86-BMI1BMI2-LABEL: bextr64_a4_commutative:
1352; X86-BMI1BMI2:       # %bb.0:
1353; X86-BMI1BMI2-NEXT:    pushl %ebx
1354; X86-BMI1BMI2-NEXT:    pushl %edi
1355; X86-BMI1BMI2-NEXT:    pushl %esi
1356; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1357; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1358; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1359; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1360; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
1361; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
1362; X86-BMI1BMI2-NEXT:    testb $32, %cl
1363; X86-BMI1BMI2-NEXT:    je .LBB12_2
1364; X86-BMI1BMI2-NEXT:  # %bb.1:
1365; X86-BMI1BMI2-NEXT:    movl %edx, %eax
1366; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
1367; X86-BMI1BMI2-NEXT:  .LBB12_2:
1368; X86-BMI1BMI2-NEXT:    movl $1, %edi
1369; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1370; X86-BMI1BMI2-NEXT:    movl %ebx, %ecx
1371; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %esi
1372; X86-BMI1BMI2-NEXT:    shlxl %ebx, %edi, %ecx
1373; X86-BMI1BMI2-NEXT:    testb $32, %bl
1374; X86-BMI1BMI2-NEXT:    je .LBB12_4
1375; X86-BMI1BMI2-NEXT:  # %bb.3:
1376; X86-BMI1BMI2-NEXT:    movl %ecx, %esi
1377; X86-BMI1BMI2-NEXT:    xorl %ecx, %ecx
1378; X86-BMI1BMI2-NEXT:  .LBB12_4:
1379; X86-BMI1BMI2-NEXT:    addl $-1, %ecx
1380; X86-BMI1BMI2-NEXT:    adcl $-1, %esi
1381; X86-BMI1BMI2-NEXT:    andl %ecx, %eax
1382; X86-BMI1BMI2-NEXT:    andl %esi, %edx
1383; X86-BMI1BMI2-NEXT:    popl %esi
1384; X86-BMI1BMI2-NEXT:    popl %edi
1385; X86-BMI1BMI2-NEXT:    popl %ebx
1386; X86-BMI1BMI2-NEXT:    retl
1387;
1388; X64-NOBMI-LABEL: bextr64_a4_commutative:
1389; X64-NOBMI:       # %bb.0:
1390; X64-NOBMI-NEXT:    movq %rsi, %rcx
1391; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1392; X64-NOBMI-NEXT:    shrq %cl, %rdi
1393; X64-NOBMI-NEXT:    movl $1, %eax
1394; X64-NOBMI-NEXT:    movl %edx, %ecx
1395; X64-NOBMI-NEXT:    shlq %cl, %rax
1396; X64-NOBMI-NEXT:    decq %rax
1397; X64-NOBMI-NEXT:    andq %rdi, %rax
1398; X64-NOBMI-NEXT:    retq
1399;
1400; X64-BMI1NOTBM-LABEL: bextr64_a4_commutative:
1401; X64-BMI1NOTBM:       # %bb.0:
1402; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
1403; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1404; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
1405; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
1406; X64-BMI1NOTBM-NEXT:    retq
1407;
1408; X64-BMI1BMI2-LABEL: bextr64_a4_commutative:
1409; X64-BMI1BMI2:       # %bb.0:
1410; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1411; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1412; X64-BMI1BMI2-NEXT:    retq
1413  %shifted = lshr i64 %val, %numskipbits
1414  %onebit = shl i64 1, %numlowbits
1415  %mask = add nsw i64 %onebit, -1
1416  %masked = and i64 %shifted, %mask ; swapped order
1417  ret i64 %masked
1418}
1419
1420define i64 @bextr64_a5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1421; X86-NOBMI-LABEL: bextr64_a5_skipextrauses:
1422; X86-NOBMI:       # %bb.0:
1423; X86-NOBMI-NEXT:    pushl %ebp
1424; X86-NOBMI-NEXT:    pushl %ebx
1425; X86-NOBMI-NEXT:    pushl %edi
1426; X86-NOBMI-NEXT:    pushl %esi
1427; X86-NOBMI-NEXT:    subl $12, %esp
1428; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1429; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1430; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1431; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1432; X86-NOBMI-NEXT:    movl %esi, %ebp
1433; X86-NOBMI-NEXT:    movl %eax, %ecx
1434; X86-NOBMI-NEXT:    shrl %cl, %ebp
1435; X86-NOBMI-NEXT:    shrdl %cl, %esi, %ebx
1436; X86-NOBMI-NEXT:    testb $32, %al
1437; X86-NOBMI-NEXT:    je .LBB13_2
1438; X86-NOBMI-NEXT:  # %bb.1:
1439; X86-NOBMI-NEXT:    movl %ebp, %ebx
1440; X86-NOBMI-NEXT:    xorl %ebp, %ebp
1441; X86-NOBMI-NEXT:  .LBB13_2:
1442; X86-NOBMI-NEXT:    movl $1, %esi
1443; X86-NOBMI-NEXT:    xorl %edi, %edi
1444; X86-NOBMI-NEXT:    movl %edx, %ecx
1445; X86-NOBMI-NEXT:    shldl %cl, %esi, %edi
1446; X86-NOBMI-NEXT:    shll %cl, %esi
1447; X86-NOBMI-NEXT:    testb $32, %dl
1448; X86-NOBMI-NEXT:    je .LBB13_4
1449; X86-NOBMI-NEXT:  # %bb.3:
1450; X86-NOBMI-NEXT:    movl %esi, %edi
1451; X86-NOBMI-NEXT:    xorl %esi, %esi
1452; X86-NOBMI-NEXT:  .LBB13_4:
1453; X86-NOBMI-NEXT:    addl $-1, %esi
1454; X86-NOBMI-NEXT:    adcl $-1, %edi
1455; X86-NOBMI-NEXT:    andl %ebx, %esi
1456; X86-NOBMI-NEXT:    andl %ebp, %edi
1457; X86-NOBMI-NEXT:    subl $8, %esp
1458; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
1459; X86-NOBMI-NEXT:    pushl %eax
1460; X86-NOBMI-NEXT:    calll use64
1461; X86-NOBMI-NEXT:    addl $16, %esp
1462; X86-NOBMI-NEXT:    movl %esi, %eax
1463; X86-NOBMI-NEXT:    movl %edi, %edx
1464; X86-NOBMI-NEXT:    addl $12, %esp
1465; X86-NOBMI-NEXT:    popl %esi
1466; X86-NOBMI-NEXT:    popl %edi
1467; X86-NOBMI-NEXT:    popl %ebx
1468; X86-NOBMI-NEXT:    popl %ebp
1469; X86-NOBMI-NEXT:    retl
1470;
1471; X86-BMI1NOTBM-LABEL: bextr64_a5_skipextrauses:
1472; X86-BMI1NOTBM:       # %bb.0:
1473; X86-BMI1NOTBM-NEXT:    pushl %ebp
1474; X86-BMI1NOTBM-NEXT:    pushl %ebx
1475; X86-BMI1NOTBM-NEXT:    pushl %edi
1476; X86-BMI1NOTBM-NEXT:    pushl %esi
1477; X86-BMI1NOTBM-NEXT:    subl $12, %esp
1478; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %dl
1479; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1480; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
1481; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1482; X86-BMI1NOTBM-NEXT:    movl %esi, %ebp
1483; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
1484; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebp
1485; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %ebx
1486; X86-BMI1NOTBM-NEXT:    testb $32, %al
1487; X86-BMI1NOTBM-NEXT:    je .LBB13_2
1488; X86-BMI1NOTBM-NEXT:  # %bb.1:
1489; X86-BMI1NOTBM-NEXT:    movl %ebp, %ebx
1490; X86-BMI1NOTBM-NEXT:    xorl %ebp, %ebp
1491; X86-BMI1NOTBM-NEXT:  .LBB13_2:
1492; X86-BMI1NOTBM-NEXT:    movl $1, %esi
1493; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
1494; X86-BMI1NOTBM-NEXT:    movl %edx, %ecx
1495; X86-BMI1NOTBM-NEXT:    shldl %cl, %esi, %edi
1496; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
1497; X86-BMI1NOTBM-NEXT:    testb $32, %dl
1498; X86-BMI1NOTBM-NEXT:    je .LBB13_4
1499; X86-BMI1NOTBM-NEXT:  # %bb.3:
1500; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
1501; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
1502; X86-BMI1NOTBM-NEXT:  .LBB13_4:
1503; X86-BMI1NOTBM-NEXT:    addl $-1, %esi
1504; X86-BMI1NOTBM-NEXT:    adcl $-1, %edi
1505; X86-BMI1NOTBM-NEXT:    andl %ebx, %esi
1506; X86-BMI1NOTBM-NEXT:    andl %ebp, %edi
1507; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1508; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
1509; X86-BMI1NOTBM-NEXT:    pushl %eax
1510; X86-BMI1NOTBM-NEXT:    calll use64
1511; X86-BMI1NOTBM-NEXT:    addl $16, %esp
1512; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1513; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
1514; X86-BMI1NOTBM-NEXT:    addl $12, %esp
1515; X86-BMI1NOTBM-NEXT:    popl %esi
1516; X86-BMI1NOTBM-NEXT:    popl %edi
1517; X86-BMI1NOTBM-NEXT:    popl %ebx
1518; X86-BMI1NOTBM-NEXT:    popl %ebp
1519; X86-BMI1NOTBM-NEXT:    retl
1520;
1521; X86-BMI1BMI2-LABEL: bextr64_a5_skipextrauses:
1522; X86-BMI1BMI2:       # %bb.0:
1523; X86-BMI1BMI2-NEXT:    pushl %ebp
1524; X86-BMI1BMI2-NEXT:    pushl %ebx
1525; X86-BMI1BMI2-NEXT:    pushl %edi
1526; X86-BMI1BMI2-NEXT:    pushl %esi
1527; X86-BMI1BMI2-NEXT:    subl $12, %esp
1528; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
1529; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1530; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1531; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1532; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
1533; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %ebx
1534; X86-BMI1BMI2-NEXT:    shrxl %eax, %esi, %ebp
1535; X86-BMI1BMI2-NEXT:    testb $32, %al
1536; X86-BMI1BMI2-NEXT:    je .LBB13_2
1537; X86-BMI1BMI2-NEXT:  # %bb.1:
1538; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
1539; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
1540; X86-BMI1BMI2-NEXT:  .LBB13_2:
1541; X86-BMI1BMI2-NEXT:    movl $1, %edi
1542; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
1543; X86-BMI1BMI2-NEXT:    movl %edx, %ecx
1544; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %esi
1545; X86-BMI1BMI2-NEXT:    shlxl %edx, %edi, %edi
1546; X86-BMI1BMI2-NEXT:    testb $32, %dl
1547; X86-BMI1BMI2-NEXT:    je .LBB13_4
1548; X86-BMI1BMI2-NEXT:  # %bb.3:
1549; X86-BMI1BMI2-NEXT:    movl %edi, %esi
1550; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
1551; X86-BMI1BMI2-NEXT:  .LBB13_4:
1552; X86-BMI1BMI2-NEXT:    addl $-1, %edi
1553; X86-BMI1BMI2-NEXT:    adcl $-1, %esi
1554; X86-BMI1BMI2-NEXT:    andl %ebx, %edi
1555; X86-BMI1BMI2-NEXT:    andl %ebp, %esi
1556; X86-BMI1BMI2-NEXT:    subl $8, %esp
1557; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
1558; X86-BMI1BMI2-NEXT:    pushl %eax
1559; X86-BMI1BMI2-NEXT:    calll use64
1560; X86-BMI1BMI2-NEXT:    addl $16, %esp
1561; X86-BMI1BMI2-NEXT:    movl %edi, %eax
1562; X86-BMI1BMI2-NEXT:    movl %esi, %edx
1563; X86-BMI1BMI2-NEXT:    addl $12, %esp
1564; X86-BMI1BMI2-NEXT:    popl %esi
1565; X86-BMI1BMI2-NEXT:    popl %edi
1566; X86-BMI1BMI2-NEXT:    popl %ebx
1567; X86-BMI1BMI2-NEXT:    popl %ebp
1568; X86-BMI1BMI2-NEXT:    retl
1569;
1570; X64-NOBMI-LABEL: bextr64_a5_skipextrauses:
1571; X64-NOBMI:       # %bb.0:
1572; X64-NOBMI-NEXT:    pushq %rbx
1573; X64-NOBMI-NEXT:    movl %esi, %ecx
1574; X64-NOBMI-NEXT:    shrq %cl, %rdi
1575; X64-NOBMI-NEXT:    movl $1, %ebx
1576; X64-NOBMI-NEXT:    movl %edx, %ecx
1577; X64-NOBMI-NEXT:    shlq %cl, %rbx
1578; X64-NOBMI-NEXT:    decq %rbx
1579; X64-NOBMI-NEXT:    andq %rdi, %rbx
1580; X64-NOBMI-NEXT:    movq %rsi, %rdi
1581; X64-NOBMI-NEXT:    callq use64
1582; X64-NOBMI-NEXT:    movq %rbx, %rax
1583; X64-NOBMI-NEXT:    popq %rbx
1584; X64-NOBMI-NEXT:    retq
1585;
1586; X64-BMI1NOTBM-LABEL: bextr64_a5_skipextrauses:
1587; X64-BMI1NOTBM:       # %bb.0:
1588; X64-BMI1NOTBM-NEXT:    pushq %rbx
1589; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
1590; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1591; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
1592; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rbx
1593; X64-BMI1NOTBM-NEXT:    movq %rsi, %rdi
1594; X64-BMI1NOTBM-NEXT:    callq use64
1595; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
1596; X64-BMI1NOTBM-NEXT:    popq %rbx
1597; X64-BMI1NOTBM-NEXT:    retq
1598;
1599; X64-BMI1BMI2-LABEL: bextr64_a5_skipextrauses:
1600; X64-BMI1BMI2:       # %bb.0:
1601; X64-BMI1BMI2-NEXT:    pushq %rbx
1602; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1603; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
1604; X64-BMI1BMI2-NEXT:    movq %rsi, %rdi
1605; X64-BMI1BMI2-NEXT:    callq use64
1606; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
1607; X64-BMI1BMI2-NEXT:    popq %rbx
1608; X64-BMI1BMI2-NEXT:    retq
1609  %shifted = lshr i64 %val, %numskipbits
1610  %onebit = shl i64 1, %numlowbits
1611  %mask = add nsw i64 %onebit, -1
1612  %masked = and i64 %mask, %shifted
1613  call void @use64(i64 %numskipbits)
1614  ret i64 %masked
1615}
1616
1617; ---------------------------------------------------------------------------- ;
1618; Pattern b. 32-bit
1619; ---------------------------------------------------------------------------- ;
1620
1621define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
1622; X86-NOBMI-LABEL: bextr32_b0:
1623; X86-NOBMI:       # %bb.0:
1624; X86-NOBMI-NEXT:    pushl %esi
1625; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1626; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1627; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1628; X86-NOBMI-NEXT:    shrl %cl, %esi
1629; X86-NOBMI-NEXT:    movl $-1, %eax
1630; X86-NOBMI-NEXT:    movl %edx, %ecx
1631; X86-NOBMI-NEXT:    shll %cl, %eax
1632; X86-NOBMI-NEXT:    notl %eax
1633; X86-NOBMI-NEXT:    andl %esi, %eax
1634; X86-NOBMI-NEXT:    popl %esi
1635; X86-NOBMI-NEXT:    retl
1636;
1637; X86-BMI1NOTBM-LABEL: bextr32_b0:
1638; X86-BMI1NOTBM:       # %bb.0:
1639; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1640; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1641; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1642; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
1643; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
1644; X86-BMI1NOTBM-NEXT:    retl
1645;
1646; X86-BMI1BMI2-LABEL: bextr32_b0:
1647; X86-BMI1BMI2:       # %bb.0:
1648; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1649; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1650; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
1651; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1652; X86-BMI1BMI2-NEXT:    retl
1653;
1654; X64-NOBMI-LABEL: bextr32_b0:
1655; X64-NOBMI:       # %bb.0:
1656; X64-NOBMI-NEXT:    movl %esi, %ecx
1657; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1658; X64-NOBMI-NEXT:    shrl %cl, %edi
1659; X64-NOBMI-NEXT:    movl $-1, %eax
1660; X64-NOBMI-NEXT:    movl %edx, %ecx
1661; X64-NOBMI-NEXT:    shll %cl, %eax
1662; X64-NOBMI-NEXT:    notl %eax
1663; X64-NOBMI-NEXT:    andl %edi, %eax
1664; X64-NOBMI-NEXT:    retq
1665;
1666; X64-BMI1NOTBM-LABEL: bextr32_b0:
1667; X64-BMI1NOTBM:       # %bb.0:
1668; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1669; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1670; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
1671; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
1672; X64-BMI1NOTBM-NEXT:    retq
1673;
1674; X64-BMI1BMI2-LABEL: bextr32_b0:
1675; X64-BMI1BMI2:       # %bb.0:
1676; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
1677; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1678; X64-BMI1BMI2-NEXT:    retq
1679  %shifted = lshr i32 %val, %numskipbits
1680  %notmask = shl i32 -1, %numlowbits
1681  %mask = xor i32 %notmask, -1
1682  %masked = and i32 %mask, %shifted
1683  ret i32 %masked
1684}
1685
1686define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
1687; X86-NOBMI-LABEL: bextr32_b1_indexzext:
1688; X86-NOBMI:       # %bb.0:
1689; X86-NOBMI-NEXT:    pushl %esi
1690; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1691; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1692; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1693; X86-NOBMI-NEXT:    shrl %cl, %esi
1694; X86-NOBMI-NEXT:    movl $-1, %eax
1695; X86-NOBMI-NEXT:    movl %edx, %ecx
1696; X86-NOBMI-NEXT:    shll %cl, %eax
1697; X86-NOBMI-NEXT:    notl %eax
1698; X86-NOBMI-NEXT:    andl %esi, %eax
1699; X86-NOBMI-NEXT:    popl %esi
1700; X86-NOBMI-NEXT:    retl
1701;
1702; X86-BMI1NOTBM-LABEL: bextr32_b1_indexzext:
1703; X86-BMI1NOTBM:       # %bb.0:
1704; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1705; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1706; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1707; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
1708; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
1709; X86-BMI1NOTBM-NEXT:    retl
1710;
1711; X86-BMI1BMI2-LABEL: bextr32_b1_indexzext:
1712; X86-BMI1BMI2:       # %bb.0:
1713; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1714; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1715; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
1716; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1717; X86-BMI1BMI2-NEXT:    retl
1718;
1719; X64-NOBMI-LABEL: bextr32_b1_indexzext:
1720; X64-NOBMI:       # %bb.0:
1721; X64-NOBMI-NEXT:    movl %esi, %ecx
1722; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1723; X64-NOBMI-NEXT:    shrl %cl, %edi
1724; X64-NOBMI-NEXT:    movl $-1, %eax
1725; X64-NOBMI-NEXT:    movl %edx, %ecx
1726; X64-NOBMI-NEXT:    shll %cl, %eax
1727; X64-NOBMI-NEXT:    notl %eax
1728; X64-NOBMI-NEXT:    andl %edi, %eax
1729; X64-NOBMI-NEXT:    retq
1730;
1731; X64-BMI1NOTBM-LABEL: bextr32_b1_indexzext:
1732; X64-BMI1NOTBM:       # %bb.0:
1733; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1734; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1735; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
1736; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
1737; X64-BMI1NOTBM-NEXT:    retq
1738;
1739; X64-BMI1BMI2-LABEL: bextr32_b1_indexzext:
1740; X64-BMI1BMI2:       # %bb.0:
1741; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
1742; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1743; X64-BMI1BMI2-NEXT:    retq
1744  %skip = zext i8 %numskipbits to i32
1745  %shifted = lshr i32 %val, %skip
1746  %conv = zext i8 %numlowbits to i32
1747  %notmask = shl i32 -1, %conv
1748  %mask = xor i32 %notmask, -1
1749  %masked = and i32 %mask, %shifted
1750  ret i32 %masked
1751}
1752
1753define i32 @bextr32_b2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
1754; X86-NOBMI-LABEL: bextr32_b2_load:
1755; X86-NOBMI:       # %bb.0:
1756; X86-NOBMI-NEXT:    pushl %esi
1757; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1758; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1759; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1760; X86-NOBMI-NEXT:    movl (%eax), %esi
1761; X86-NOBMI-NEXT:    shrl %cl, %esi
1762; X86-NOBMI-NEXT:    movl $-1, %eax
1763; X86-NOBMI-NEXT:    movl %edx, %ecx
1764; X86-NOBMI-NEXT:    shll %cl, %eax
1765; X86-NOBMI-NEXT:    notl %eax
1766; X86-NOBMI-NEXT:    andl %esi, %eax
1767; X86-NOBMI-NEXT:    popl %esi
1768; X86-NOBMI-NEXT:    retl
1769;
1770; X86-BMI1NOTBM-LABEL: bextr32_b2_load:
1771; X86-BMI1NOTBM:       # %bb.0:
1772; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1773; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1774; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
1775; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1776; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
1777; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
1778; X86-BMI1NOTBM-NEXT:    retl
1779;
1780; X86-BMI1BMI2-LABEL: bextr32_b2_load:
1781; X86-BMI1BMI2:       # %bb.0:
1782; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1783; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1784; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
1785; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
1786; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1787; X86-BMI1BMI2-NEXT:    retl
1788;
1789; X64-NOBMI-LABEL: bextr32_b2_load:
1790; X64-NOBMI:       # %bb.0:
1791; X64-NOBMI-NEXT:    movl %esi, %ecx
1792; X64-NOBMI-NEXT:    movl (%rdi), %esi
1793; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1794; X64-NOBMI-NEXT:    shrl %cl, %esi
1795; X64-NOBMI-NEXT:    movl $-1, %eax
1796; X64-NOBMI-NEXT:    movl %edx, %ecx
1797; X64-NOBMI-NEXT:    shll %cl, %eax
1798; X64-NOBMI-NEXT:    notl %eax
1799; X64-NOBMI-NEXT:    andl %esi, %eax
1800; X64-NOBMI-NEXT:    retq
1801;
1802; X64-BMI1NOTBM-LABEL: bextr32_b2_load:
1803; X64-BMI1NOTBM:       # %bb.0:
1804; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1805; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1806; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
1807; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
1808; X64-BMI1NOTBM-NEXT:    retq
1809;
1810; X64-BMI1BMI2-LABEL: bextr32_b2_load:
1811; X64-BMI1BMI2:       # %bb.0:
1812; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1813; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1814; X64-BMI1BMI2-NEXT:    retq
1815  %val = load i32, i32* %w
1816  %shifted = lshr i32 %val, %numskipbits
1817  %notmask = shl i32 -1, %numlowbits
1818  %mask = xor i32 %notmask, -1
1819  %masked = and i32 %mask, %shifted
1820  ret i32 %masked
1821}
1822
1823define i32 @bextr32_b3_load_indexzext(i32* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
1824; X86-NOBMI-LABEL: bextr32_b3_load_indexzext:
1825; X86-NOBMI:       # %bb.0:
1826; X86-NOBMI-NEXT:    pushl %esi
1827; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1828; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1829; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1830; X86-NOBMI-NEXT:    movl (%eax), %esi
1831; X86-NOBMI-NEXT:    shrl %cl, %esi
1832; X86-NOBMI-NEXT:    movl $-1, %eax
1833; X86-NOBMI-NEXT:    movl %edx, %ecx
1834; X86-NOBMI-NEXT:    shll %cl, %eax
1835; X86-NOBMI-NEXT:    notl %eax
1836; X86-NOBMI-NEXT:    andl %esi, %eax
1837; X86-NOBMI-NEXT:    popl %esi
1838; X86-NOBMI-NEXT:    retl
1839;
1840; X86-BMI1NOTBM-LABEL: bextr32_b3_load_indexzext:
1841; X86-BMI1NOTBM:       # %bb.0:
1842; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1843; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1844; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
1845; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1846; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
1847; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
1848; X86-BMI1NOTBM-NEXT:    retl
1849;
1850; X86-BMI1BMI2-LABEL: bextr32_b3_load_indexzext:
1851; X86-BMI1BMI2:       # %bb.0:
1852; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1853; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1854; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
1855; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
1856; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1857; X86-BMI1BMI2-NEXT:    retl
1858;
1859; X64-NOBMI-LABEL: bextr32_b3_load_indexzext:
1860; X64-NOBMI:       # %bb.0:
1861; X64-NOBMI-NEXT:    movl %esi, %ecx
1862; X64-NOBMI-NEXT:    movl (%rdi), %esi
1863; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1864; X64-NOBMI-NEXT:    shrl %cl, %esi
1865; X64-NOBMI-NEXT:    movl $-1, %eax
1866; X64-NOBMI-NEXT:    movl %edx, %ecx
1867; X64-NOBMI-NEXT:    shll %cl, %eax
1868; X64-NOBMI-NEXT:    notl %eax
1869; X64-NOBMI-NEXT:    andl %esi, %eax
1870; X64-NOBMI-NEXT:    retq
1871;
1872; X64-BMI1NOTBM-LABEL: bextr32_b3_load_indexzext:
1873; X64-BMI1NOTBM:       # %bb.0:
1874; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1875; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1876; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
1877; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
1878; X64-BMI1NOTBM-NEXT:    retq
1879;
1880; X64-BMI1BMI2-LABEL: bextr32_b3_load_indexzext:
1881; X64-BMI1BMI2:       # %bb.0:
1882; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
1883; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1884; X64-BMI1BMI2-NEXT:    retq
1885  %val = load i32, i32* %w
1886  %skip = zext i8 %numskipbits to i32
1887  %shifted = lshr i32 %val, %skip
1888  %conv = zext i8 %numlowbits to i32
1889  %notmask = shl i32 -1, %conv
1890  %mask = xor i32 %notmask, -1
1891  %masked = and i32 %mask, %shifted
1892  ret i32 %masked
1893}
1894
1895define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
1896; X86-NOBMI-LABEL: bextr32_b4_commutative:
1897; X86-NOBMI:       # %bb.0:
1898; X86-NOBMI-NEXT:    pushl %esi
1899; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1900; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1901; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1902; X86-NOBMI-NEXT:    shrl %cl, %esi
1903; X86-NOBMI-NEXT:    movl $-1, %eax
1904; X86-NOBMI-NEXT:    movl %edx, %ecx
1905; X86-NOBMI-NEXT:    shll %cl, %eax
1906; X86-NOBMI-NEXT:    notl %eax
1907; X86-NOBMI-NEXT:    andl %esi, %eax
1908; X86-NOBMI-NEXT:    popl %esi
1909; X86-NOBMI-NEXT:    retl
1910;
1911; X86-BMI1NOTBM-LABEL: bextr32_b4_commutative:
1912; X86-BMI1NOTBM:       # %bb.0:
1913; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1914; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1915; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1916; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
1917; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
1918; X86-BMI1NOTBM-NEXT:    retl
1919;
1920; X86-BMI1BMI2-LABEL: bextr32_b4_commutative:
1921; X86-BMI1BMI2:       # %bb.0:
1922; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1923; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1924; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
1925; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1926; X86-BMI1BMI2-NEXT:    retl
1927;
1928; X64-NOBMI-LABEL: bextr32_b4_commutative:
1929; X64-NOBMI:       # %bb.0:
1930; X64-NOBMI-NEXT:    movl %esi, %ecx
1931; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1932; X64-NOBMI-NEXT:    shrl %cl, %edi
1933; X64-NOBMI-NEXT:    movl $-1, %eax
1934; X64-NOBMI-NEXT:    movl %edx, %ecx
1935; X64-NOBMI-NEXT:    shll %cl, %eax
1936; X64-NOBMI-NEXT:    notl %eax
1937; X64-NOBMI-NEXT:    andl %edi, %eax
1938; X64-NOBMI-NEXT:    retq
1939;
1940; X64-BMI1NOTBM-LABEL: bextr32_b4_commutative:
1941; X64-BMI1NOTBM:       # %bb.0:
1942; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1943; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
1944; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
1945; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
1946; X64-BMI1NOTBM-NEXT:    retq
1947;
1948; X64-BMI1BMI2-LABEL: bextr32_b4_commutative:
1949; X64-BMI1BMI2:       # %bb.0:
1950; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
1951; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1952; X64-BMI1BMI2-NEXT:    retq
1953  %shifted = lshr i32 %val, %numskipbits
1954  %notmask = shl i32 -1, %numlowbits
1955  %mask = xor i32 %notmask, -1
1956  %masked = and i32 %shifted, %mask ; swapped order
1957  ret i32 %masked
1958}
1959
1960define i32 @bextr32_b5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
1961; X86-NOBMI-LABEL: bextr32_b5_skipextrauses:
1962; X86-NOBMI:       # %bb.0:
1963; X86-NOBMI-NEXT:    pushl %edi
1964; X86-NOBMI-NEXT:    pushl %esi
1965; X86-NOBMI-NEXT:    pushl %eax
1966; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1967; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1968; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1969; X86-NOBMI-NEXT:    movl %eax, %ecx
1970; X86-NOBMI-NEXT:    shrl %cl, %edi
1971; X86-NOBMI-NEXT:    movl $-1, %esi
1972; X86-NOBMI-NEXT:    movl %edx, %ecx
1973; X86-NOBMI-NEXT:    shll %cl, %esi
1974; X86-NOBMI-NEXT:    notl %esi
1975; X86-NOBMI-NEXT:    andl %edi, %esi
1976; X86-NOBMI-NEXT:    movl %eax, (%esp)
1977; X86-NOBMI-NEXT:    calll use32
1978; X86-NOBMI-NEXT:    movl %esi, %eax
1979; X86-NOBMI-NEXT:    addl $4, %esp
1980; X86-NOBMI-NEXT:    popl %esi
1981; X86-NOBMI-NEXT:    popl %edi
1982; X86-NOBMI-NEXT:    retl
1983;
1984; X86-BMI1NOTBM-LABEL: bextr32_b5_skipextrauses:
1985; X86-BMI1NOTBM:       # %bb.0:
1986; X86-BMI1NOTBM-NEXT:    pushl %esi
1987; X86-BMI1NOTBM-NEXT:    subl $8, %esp
1988; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1989; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1990; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
1991; X86-BMI1NOTBM-NEXT:    movzbl %al, %edx
1992; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
1993; X86-BMI1NOTBM-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
1994; X86-BMI1NOTBM-NEXT:    movl %eax, (%esp)
1995; X86-BMI1NOTBM-NEXT:    calll use32
1996; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
1997; X86-BMI1NOTBM-NEXT:    addl $8, %esp
1998; X86-BMI1NOTBM-NEXT:    popl %esi
1999; X86-BMI1NOTBM-NEXT:    retl
2000;
2001; X86-BMI1BMI2-LABEL: bextr32_b5_skipextrauses:
2002; X86-BMI1BMI2:       # %bb.0:
2003; X86-BMI1BMI2-NEXT:    pushl %esi
2004; X86-BMI1BMI2-NEXT:    subl $8, %esp
2005; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2006; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2007; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
2008; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %esi
2009; X86-BMI1BMI2-NEXT:    movl %ecx, (%esp)
2010; X86-BMI1BMI2-NEXT:    calll use32
2011; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2012; X86-BMI1BMI2-NEXT:    addl $8, %esp
2013; X86-BMI1BMI2-NEXT:    popl %esi
2014; X86-BMI1BMI2-NEXT:    retl
2015;
2016; X64-NOBMI-LABEL: bextr32_b5_skipextrauses:
2017; X64-NOBMI:       # %bb.0:
2018; X64-NOBMI-NEXT:    pushq %rbx
2019; X64-NOBMI-NEXT:    movl %esi, %ecx
2020; X64-NOBMI-NEXT:    shrl %cl, %edi
2021; X64-NOBMI-NEXT:    movl $-1, %ebx
2022; X64-NOBMI-NEXT:    movl %edx, %ecx
2023; X64-NOBMI-NEXT:    shll %cl, %ebx
2024; X64-NOBMI-NEXT:    notl %ebx
2025; X64-NOBMI-NEXT:    andl %edi, %ebx
2026; X64-NOBMI-NEXT:    movl %esi, %edi
2027; X64-NOBMI-NEXT:    callq use32
2028; X64-NOBMI-NEXT:    movl %ebx, %eax
2029; X64-NOBMI-NEXT:    popq %rbx
2030; X64-NOBMI-NEXT:    retq
2031;
2032; X64-BMI1NOTBM-LABEL: bextr32_b5_skipextrauses:
2033; X64-BMI1NOTBM:       # %bb.0:
2034; X64-BMI1NOTBM-NEXT:    pushq %rbx
2035; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2036; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2037; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2038; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %ebx
2039; X64-BMI1NOTBM-NEXT:    movl %esi, %edi
2040; X64-BMI1NOTBM-NEXT:    callq use32
2041; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
2042; X64-BMI1NOTBM-NEXT:    popq %rbx
2043; X64-BMI1NOTBM-NEXT:    retq
2044;
2045; X64-BMI1BMI2-LABEL: bextr32_b5_skipextrauses:
2046; X64-BMI1BMI2:       # %bb.0:
2047; X64-BMI1BMI2-NEXT:    pushq %rbx
2048; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
2049; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %ebx
2050; X64-BMI1BMI2-NEXT:    movl %esi, %edi
2051; X64-BMI1BMI2-NEXT:    callq use32
2052; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
2053; X64-BMI1BMI2-NEXT:    popq %rbx
2054; X64-BMI1BMI2-NEXT:    retq
2055  %shifted = lshr i32 %val, %numskipbits
2056  %notmask = shl i32 -1, %numlowbits
2057  %mask = xor i32 %notmask, -1
2058  %masked = and i32 %mask, %shifted
2059  call void @use32(i32 %numskipbits)
2060  ret i32 %masked
2061}
2062
2063; 64-bit
2064
2065define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2066; X86-NOBMI-LABEL: bextr64_b0:
2067; X86-NOBMI:       # %bb.0:
2068; X86-NOBMI-NEXT:    pushl %edi
2069; X86-NOBMI-NEXT:    pushl %esi
2070; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2071; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2072; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2073; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2074; X86-NOBMI-NEXT:    movl %eax, %edi
2075; X86-NOBMI-NEXT:    shrl %cl, %edi
2076; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2077; X86-NOBMI-NEXT:    testb $32, %cl
2078; X86-NOBMI-NEXT:    je .LBB20_2
2079; X86-NOBMI-NEXT:  # %bb.1:
2080; X86-NOBMI-NEXT:    movl %edi, %esi
2081; X86-NOBMI-NEXT:    xorl %edi, %edi
2082; X86-NOBMI-NEXT:  .LBB20_2:
2083; X86-NOBMI-NEXT:    movl $-1, %edx
2084; X86-NOBMI-NEXT:    movl $-1, %eax
2085; X86-NOBMI-NEXT:    movb %ch, %cl
2086; X86-NOBMI-NEXT:    shll %cl, %eax
2087; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2088; X86-NOBMI-NEXT:    testb $32, %ch
2089; X86-NOBMI-NEXT:    je .LBB20_4
2090; X86-NOBMI-NEXT:  # %bb.3:
2091; X86-NOBMI-NEXT:    movl %eax, %edx
2092; X86-NOBMI-NEXT:    xorl %eax, %eax
2093; X86-NOBMI-NEXT:  .LBB20_4:
2094; X86-NOBMI-NEXT:    notl %edx
2095; X86-NOBMI-NEXT:    andl %edi, %edx
2096; X86-NOBMI-NEXT:    notl %eax
2097; X86-NOBMI-NEXT:    andl %esi, %eax
2098; X86-NOBMI-NEXT:    popl %esi
2099; X86-NOBMI-NEXT:    popl %edi
2100; X86-NOBMI-NEXT:    retl
2101;
2102; X86-BMI1NOTBM-LABEL: bextr64_b0:
2103; X86-BMI1NOTBM:       # %bb.0:
2104; X86-BMI1NOTBM-NEXT:    pushl %ebx
2105; X86-BMI1NOTBM-NEXT:    pushl %edi
2106; X86-BMI1NOTBM-NEXT:    pushl %esi
2107; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2108; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2109; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
2110; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2111; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2112; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2113; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2114; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2115; X86-BMI1NOTBM-NEXT:    je .LBB20_2
2116; X86-BMI1NOTBM-NEXT:  # %bb.1:
2117; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2118; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2119; X86-BMI1NOTBM-NEXT:  .LBB20_2:
2120; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2121; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2122; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2123; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2124; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2125; X86-BMI1NOTBM-NEXT:    testb $32, %al
2126; X86-BMI1NOTBM-NEXT:    je .LBB20_4
2127; X86-BMI1NOTBM-NEXT:  # %bb.3:
2128; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2129; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2130; X86-BMI1NOTBM-NEXT:  .LBB20_4:
2131; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2132; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2133; X86-BMI1NOTBM-NEXT:    popl %esi
2134; X86-BMI1NOTBM-NEXT:    popl %edi
2135; X86-BMI1NOTBM-NEXT:    popl %ebx
2136; X86-BMI1NOTBM-NEXT:    retl
2137;
2138; X86-BMI1BMI2-LABEL: bextr64_b0:
2139; X86-BMI1BMI2:       # %bb.0:
2140; X86-BMI1BMI2-NEXT:    pushl %ebx
2141; X86-BMI1BMI2-NEXT:    pushl %edi
2142; X86-BMI1BMI2-NEXT:    pushl %esi
2143; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2144; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2145; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2146; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2147; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
2148; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
2149; X86-BMI1BMI2-NEXT:    testb $32, %cl
2150; X86-BMI1BMI2-NEXT:    je .LBB20_2
2151; X86-BMI1BMI2-NEXT:  # %bb.1:
2152; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2153; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2154; X86-BMI1BMI2-NEXT:  .LBB20_2:
2155; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2156; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2157; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2158; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2159; X86-BMI1BMI2-NEXT:    testb $32, %al
2160; X86-BMI1BMI2-NEXT:    je .LBB20_4
2161; X86-BMI1BMI2-NEXT:  # %bb.3:
2162; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2163; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2164; X86-BMI1BMI2-NEXT:  .LBB20_4:
2165; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2166; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2167; X86-BMI1BMI2-NEXT:    popl %esi
2168; X86-BMI1BMI2-NEXT:    popl %edi
2169; X86-BMI1BMI2-NEXT:    popl %ebx
2170; X86-BMI1BMI2-NEXT:    retl
2171;
2172; X64-NOBMI-LABEL: bextr64_b0:
2173; X64-NOBMI:       # %bb.0:
2174; X64-NOBMI-NEXT:    movq %rsi, %rcx
2175; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2176; X64-NOBMI-NEXT:    shrq %cl, %rdi
2177; X64-NOBMI-NEXT:    movq $-1, %rax
2178; X64-NOBMI-NEXT:    movl %edx, %ecx
2179; X64-NOBMI-NEXT:    shlq %cl, %rax
2180; X64-NOBMI-NEXT:    notq %rax
2181; X64-NOBMI-NEXT:    andq %rdi, %rax
2182; X64-NOBMI-NEXT:    retq
2183;
2184; X64-BMI1NOTBM-LABEL: bextr64_b0:
2185; X64-BMI1NOTBM:       # %bb.0:
2186; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2187; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2188; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2189; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
2190; X64-BMI1NOTBM-NEXT:    retq
2191;
2192; X64-BMI1BMI2-LABEL: bextr64_b0:
2193; X64-BMI1BMI2:       # %bb.0:
2194; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2195; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2196; X64-BMI1BMI2-NEXT:    retq
2197  %shifted = lshr i64 %val, %numskipbits
2198  %notmask = shl i64 -1, %numlowbits
2199  %mask = xor i64 %notmask, -1
2200  %masked = and i64 %mask, %shifted
2201  ret i64 %masked
2202}
2203
2204define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2205; X86-NOBMI-LABEL: bextr64_b1_indexzext:
2206; X86-NOBMI:       # %bb.0:
2207; X86-NOBMI-NEXT:    pushl %edi
2208; X86-NOBMI-NEXT:    pushl %esi
2209; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2210; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2211; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2212; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2213; X86-NOBMI-NEXT:    movl %eax, %edi
2214; X86-NOBMI-NEXT:    shrl %cl, %edi
2215; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2216; X86-NOBMI-NEXT:    testb $32, %cl
2217; X86-NOBMI-NEXT:    je .LBB21_2
2218; X86-NOBMI-NEXT:  # %bb.1:
2219; X86-NOBMI-NEXT:    movl %edi, %esi
2220; X86-NOBMI-NEXT:    xorl %edi, %edi
2221; X86-NOBMI-NEXT:  .LBB21_2:
2222; X86-NOBMI-NEXT:    movl $-1, %edx
2223; X86-NOBMI-NEXT:    movl $-1, %eax
2224; X86-NOBMI-NEXT:    movb %ch, %cl
2225; X86-NOBMI-NEXT:    shll %cl, %eax
2226; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2227; X86-NOBMI-NEXT:    testb $32, %ch
2228; X86-NOBMI-NEXT:    je .LBB21_4
2229; X86-NOBMI-NEXT:  # %bb.3:
2230; X86-NOBMI-NEXT:    movl %eax, %edx
2231; X86-NOBMI-NEXT:    xorl %eax, %eax
2232; X86-NOBMI-NEXT:  .LBB21_4:
2233; X86-NOBMI-NEXT:    notl %edx
2234; X86-NOBMI-NEXT:    andl %edi, %edx
2235; X86-NOBMI-NEXT:    notl %eax
2236; X86-NOBMI-NEXT:    andl %esi, %eax
2237; X86-NOBMI-NEXT:    popl %esi
2238; X86-NOBMI-NEXT:    popl %edi
2239; X86-NOBMI-NEXT:    retl
2240;
2241; X86-BMI1NOTBM-LABEL: bextr64_b1_indexzext:
2242; X86-BMI1NOTBM:       # %bb.0:
2243; X86-BMI1NOTBM-NEXT:    pushl %ebx
2244; X86-BMI1NOTBM-NEXT:    pushl %edi
2245; X86-BMI1NOTBM-NEXT:    pushl %esi
2246; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2247; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2248; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
2249; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2250; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2251; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2252; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2253; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2254; X86-BMI1NOTBM-NEXT:    je .LBB21_2
2255; X86-BMI1NOTBM-NEXT:  # %bb.1:
2256; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2257; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2258; X86-BMI1NOTBM-NEXT:  .LBB21_2:
2259; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2260; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2261; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2262; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2263; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2264; X86-BMI1NOTBM-NEXT:    testb $32, %al
2265; X86-BMI1NOTBM-NEXT:    je .LBB21_4
2266; X86-BMI1NOTBM-NEXT:  # %bb.3:
2267; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2268; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2269; X86-BMI1NOTBM-NEXT:  .LBB21_4:
2270; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2271; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2272; X86-BMI1NOTBM-NEXT:    popl %esi
2273; X86-BMI1NOTBM-NEXT:    popl %edi
2274; X86-BMI1NOTBM-NEXT:    popl %ebx
2275; X86-BMI1NOTBM-NEXT:    retl
2276;
2277; X86-BMI1BMI2-LABEL: bextr64_b1_indexzext:
2278; X86-BMI1BMI2:       # %bb.0:
2279; X86-BMI1BMI2-NEXT:    pushl %ebx
2280; X86-BMI1BMI2-NEXT:    pushl %edi
2281; X86-BMI1BMI2-NEXT:    pushl %esi
2282; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2283; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2284; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2285; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2286; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
2287; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
2288; X86-BMI1BMI2-NEXT:    testb $32, %cl
2289; X86-BMI1BMI2-NEXT:    je .LBB21_2
2290; X86-BMI1BMI2-NEXT:  # %bb.1:
2291; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2292; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2293; X86-BMI1BMI2-NEXT:  .LBB21_2:
2294; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2295; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2296; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2297; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2298; X86-BMI1BMI2-NEXT:    testb $32, %al
2299; X86-BMI1BMI2-NEXT:    je .LBB21_4
2300; X86-BMI1BMI2-NEXT:  # %bb.3:
2301; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2302; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2303; X86-BMI1BMI2-NEXT:  .LBB21_4:
2304; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2305; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2306; X86-BMI1BMI2-NEXT:    popl %esi
2307; X86-BMI1BMI2-NEXT:    popl %edi
2308; X86-BMI1BMI2-NEXT:    popl %ebx
2309; X86-BMI1BMI2-NEXT:    retl
2310;
2311; X64-NOBMI-LABEL: bextr64_b1_indexzext:
2312; X64-NOBMI:       # %bb.0:
2313; X64-NOBMI-NEXT:    movl %esi, %ecx
2314; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2315; X64-NOBMI-NEXT:    shrq %cl, %rdi
2316; X64-NOBMI-NEXT:    movq $-1, %rax
2317; X64-NOBMI-NEXT:    movl %edx, %ecx
2318; X64-NOBMI-NEXT:    shlq %cl, %rax
2319; X64-NOBMI-NEXT:    notq %rax
2320; X64-NOBMI-NEXT:    andq %rdi, %rax
2321; X64-NOBMI-NEXT:    retq
2322;
2323; X64-BMI1NOTBM-LABEL: bextr64_b1_indexzext:
2324; X64-BMI1NOTBM:       # %bb.0:
2325; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
2326; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2327; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2328; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2329; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
2330; X64-BMI1NOTBM-NEXT:    retq
2331;
2332; X64-BMI1BMI2-LABEL: bextr64_b1_indexzext:
2333; X64-BMI1BMI2:       # %bb.0:
2334; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
2335; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2336; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2337; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2338; X64-BMI1BMI2-NEXT:    retq
2339  %skip = zext i8 %numskipbits to i64
2340  %shifted = lshr i64 %val, %skip
2341  %conv = zext i8 %numlowbits to i64
2342  %notmask = shl i64 -1, %conv
2343  %mask = xor i64 %notmask, -1
2344  %masked = and i64 %mask, %shifted
2345  ret i64 %masked
2346}
2347
2348define i64 @bextr64_b2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
2349; X86-NOBMI-LABEL: bextr64_b2_load:
2350; X86-NOBMI:       # %bb.0:
2351; X86-NOBMI-NEXT:    pushl %edi
2352; X86-NOBMI-NEXT:    pushl %esi
2353; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2354; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2355; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2356; X86-NOBMI-NEXT:    movl (%eax), %esi
2357; X86-NOBMI-NEXT:    movl 4(%eax), %eax
2358; X86-NOBMI-NEXT:    movl %eax, %edi
2359; X86-NOBMI-NEXT:    shrl %cl, %edi
2360; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2361; X86-NOBMI-NEXT:    testb $32, %cl
2362; X86-NOBMI-NEXT:    je .LBB22_2
2363; X86-NOBMI-NEXT:  # %bb.1:
2364; X86-NOBMI-NEXT:    movl %edi, %esi
2365; X86-NOBMI-NEXT:    xorl %edi, %edi
2366; X86-NOBMI-NEXT:  .LBB22_2:
2367; X86-NOBMI-NEXT:    movl $-1, %edx
2368; X86-NOBMI-NEXT:    movl $-1, %eax
2369; X86-NOBMI-NEXT:    movb %ch, %cl
2370; X86-NOBMI-NEXT:    shll %cl, %eax
2371; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2372; X86-NOBMI-NEXT:    testb $32, %ch
2373; X86-NOBMI-NEXT:    je .LBB22_4
2374; X86-NOBMI-NEXT:  # %bb.3:
2375; X86-NOBMI-NEXT:    movl %eax, %edx
2376; X86-NOBMI-NEXT:    xorl %eax, %eax
2377; X86-NOBMI-NEXT:  .LBB22_4:
2378; X86-NOBMI-NEXT:    notl %edx
2379; X86-NOBMI-NEXT:    andl %edi, %edx
2380; X86-NOBMI-NEXT:    notl %eax
2381; X86-NOBMI-NEXT:    andl %esi, %eax
2382; X86-NOBMI-NEXT:    popl %esi
2383; X86-NOBMI-NEXT:    popl %edi
2384; X86-NOBMI-NEXT:    retl
2385;
2386; X86-BMI1NOTBM-LABEL: bextr64_b2_load:
2387; X86-BMI1NOTBM:       # %bb.0:
2388; X86-BMI1NOTBM-NEXT:    pushl %ebx
2389; X86-BMI1NOTBM-NEXT:    pushl %edi
2390; X86-BMI1NOTBM-NEXT:    pushl %esi
2391; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2392; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2393; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2394; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2395; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2396; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2397; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2398; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2399; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2400; X86-BMI1NOTBM-NEXT:    je .LBB22_2
2401; X86-BMI1NOTBM-NEXT:  # %bb.1:
2402; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2403; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2404; X86-BMI1NOTBM-NEXT:  .LBB22_2:
2405; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2406; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2407; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2408; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2409; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2410; X86-BMI1NOTBM-NEXT:    testb $32, %al
2411; X86-BMI1NOTBM-NEXT:    je .LBB22_4
2412; X86-BMI1NOTBM-NEXT:  # %bb.3:
2413; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2414; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2415; X86-BMI1NOTBM-NEXT:  .LBB22_4:
2416; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2417; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2418; X86-BMI1NOTBM-NEXT:    popl %esi
2419; X86-BMI1NOTBM-NEXT:    popl %edi
2420; X86-BMI1NOTBM-NEXT:    popl %ebx
2421; X86-BMI1NOTBM-NEXT:    retl
2422;
2423; X86-BMI1BMI2-LABEL: bextr64_b2_load:
2424; X86-BMI1BMI2:       # %bb.0:
2425; X86-BMI1BMI2-NEXT:    pushl %ebx
2426; X86-BMI1BMI2-NEXT:    pushl %edi
2427; X86-BMI1BMI2-NEXT:    pushl %esi
2428; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2429; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2430; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2431; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2432; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2433; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edi, %edx
2434; X86-BMI1BMI2-NEXT:    shrdl %cl, %edi, %esi
2435; X86-BMI1BMI2-NEXT:    testb $32, %cl
2436; X86-BMI1BMI2-NEXT:    je .LBB22_2
2437; X86-BMI1BMI2-NEXT:  # %bb.1:
2438; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2439; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2440; X86-BMI1BMI2-NEXT:  .LBB22_2:
2441; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2442; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2443; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2444; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2445; X86-BMI1BMI2-NEXT:    testb $32, %al
2446; X86-BMI1BMI2-NEXT:    je .LBB22_4
2447; X86-BMI1BMI2-NEXT:  # %bb.3:
2448; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2449; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2450; X86-BMI1BMI2-NEXT:  .LBB22_4:
2451; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2452; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2453; X86-BMI1BMI2-NEXT:    popl %esi
2454; X86-BMI1BMI2-NEXT:    popl %edi
2455; X86-BMI1BMI2-NEXT:    popl %ebx
2456; X86-BMI1BMI2-NEXT:    retl
2457;
2458; X64-NOBMI-LABEL: bextr64_b2_load:
2459; X64-NOBMI:       # %bb.0:
2460; X64-NOBMI-NEXT:    movq %rsi, %rcx
2461; X64-NOBMI-NEXT:    movq (%rdi), %rsi
2462; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2463; X64-NOBMI-NEXT:    shrq %cl, %rsi
2464; X64-NOBMI-NEXT:    movq $-1, %rax
2465; X64-NOBMI-NEXT:    movl %edx, %ecx
2466; X64-NOBMI-NEXT:    shlq %cl, %rax
2467; X64-NOBMI-NEXT:    notq %rax
2468; X64-NOBMI-NEXT:    andq %rsi, %rax
2469; X64-NOBMI-NEXT:    retq
2470;
2471; X64-BMI1NOTBM-LABEL: bextr64_b2_load:
2472; X64-BMI1NOTBM:       # %bb.0:
2473; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2474; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2475; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2476; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
2477; X64-BMI1NOTBM-NEXT:    retq
2478;
2479; X64-BMI1BMI2-LABEL: bextr64_b2_load:
2480; X64-BMI1BMI2:       # %bb.0:
2481; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
2482; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2483; X64-BMI1BMI2-NEXT:    retq
2484  %val = load i64, i64* %w
2485  %shifted = lshr i64 %val, %numskipbits
2486  %notmask = shl i64 -1, %numlowbits
2487  %mask = xor i64 %notmask, -1
2488  %masked = and i64 %mask, %shifted
2489  ret i64 %masked
2490}
2491
2492define i64 @bextr64_b3_load_indexzext(i64* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2493; X86-NOBMI-LABEL: bextr64_b3_load_indexzext:
2494; X86-NOBMI:       # %bb.0:
2495; X86-NOBMI-NEXT:    pushl %edi
2496; X86-NOBMI-NEXT:    pushl %esi
2497; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2498; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2499; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2500; X86-NOBMI-NEXT:    movl (%eax), %esi
2501; X86-NOBMI-NEXT:    movl 4(%eax), %eax
2502; X86-NOBMI-NEXT:    movl %eax, %edi
2503; X86-NOBMI-NEXT:    shrl %cl, %edi
2504; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2505; X86-NOBMI-NEXT:    testb $32, %cl
2506; X86-NOBMI-NEXT:    je .LBB23_2
2507; X86-NOBMI-NEXT:  # %bb.1:
2508; X86-NOBMI-NEXT:    movl %edi, %esi
2509; X86-NOBMI-NEXT:    xorl %edi, %edi
2510; X86-NOBMI-NEXT:  .LBB23_2:
2511; X86-NOBMI-NEXT:    movl $-1, %edx
2512; X86-NOBMI-NEXT:    movl $-1, %eax
2513; X86-NOBMI-NEXT:    movb %ch, %cl
2514; X86-NOBMI-NEXT:    shll %cl, %eax
2515; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2516; X86-NOBMI-NEXT:    testb $32, %ch
2517; X86-NOBMI-NEXT:    je .LBB23_4
2518; X86-NOBMI-NEXT:  # %bb.3:
2519; X86-NOBMI-NEXT:    movl %eax, %edx
2520; X86-NOBMI-NEXT:    xorl %eax, %eax
2521; X86-NOBMI-NEXT:  .LBB23_4:
2522; X86-NOBMI-NEXT:    notl %edx
2523; X86-NOBMI-NEXT:    andl %edi, %edx
2524; X86-NOBMI-NEXT:    notl %eax
2525; X86-NOBMI-NEXT:    andl %esi, %eax
2526; X86-NOBMI-NEXT:    popl %esi
2527; X86-NOBMI-NEXT:    popl %edi
2528; X86-NOBMI-NEXT:    retl
2529;
2530; X86-BMI1NOTBM-LABEL: bextr64_b3_load_indexzext:
2531; X86-BMI1NOTBM:       # %bb.0:
2532; X86-BMI1NOTBM-NEXT:    pushl %ebx
2533; X86-BMI1NOTBM-NEXT:    pushl %edi
2534; X86-BMI1NOTBM-NEXT:    pushl %esi
2535; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2536; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2537; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2538; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2539; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2540; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2541; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2542; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2543; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2544; X86-BMI1NOTBM-NEXT:    je .LBB23_2
2545; X86-BMI1NOTBM-NEXT:  # %bb.1:
2546; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2547; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2548; X86-BMI1NOTBM-NEXT:  .LBB23_2:
2549; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2550; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2551; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2552; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2553; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2554; X86-BMI1NOTBM-NEXT:    testb $32, %al
2555; X86-BMI1NOTBM-NEXT:    je .LBB23_4
2556; X86-BMI1NOTBM-NEXT:  # %bb.3:
2557; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2558; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2559; X86-BMI1NOTBM-NEXT:  .LBB23_4:
2560; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2561; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2562; X86-BMI1NOTBM-NEXT:    popl %esi
2563; X86-BMI1NOTBM-NEXT:    popl %edi
2564; X86-BMI1NOTBM-NEXT:    popl %ebx
2565; X86-BMI1NOTBM-NEXT:    retl
2566;
2567; X86-BMI1BMI2-LABEL: bextr64_b3_load_indexzext:
2568; X86-BMI1BMI2:       # %bb.0:
2569; X86-BMI1BMI2-NEXT:    pushl %ebx
2570; X86-BMI1BMI2-NEXT:    pushl %edi
2571; X86-BMI1BMI2-NEXT:    pushl %esi
2572; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2573; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2574; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2575; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2576; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2577; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edi, %edx
2578; X86-BMI1BMI2-NEXT:    shrdl %cl, %edi, %esi
2579; X86-BMI1BMI2-NEXT:    testb $32, %cl
2580; X86-BMI1BMI2-NEXT:    je .LBB23_2
2581; X86-BMI1BMI2-NEXT:  # %bb.1:
2582; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2583; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2584; X86-BMI1BMI2-NEXT:  .LBB23_2:
2585; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2586; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2587; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2588; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2589; X86-BMI1BMI2-NEXT:    testb $32, %al
2590; X86-BMI1BMI2-NEXT:    je .LBB23_4
2591; X86-BMI1BMI2-NEXT:  # %bb.3:
2592; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2593; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2594; X86-BMI1BMI2-NEXT:  .LBB23_4:
2595; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2596; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2597; X86-BMI1BMI2-NEXT:    popl %esi
2598; X86-BMI1BMI2-NEXT:    popl %edi
2599; X86-BMI1BMI2-NEXT:    popl %ebx
2600; X86-BMI1BMI2-NEXT:    retl
2601;
2602; X64-NOBMI-LABEL: bextr64_b3_load_indexzext:
2603; X64-NOBMI:       # %bb.0:
2604; X64-NOBMI-NEXT:    movl %esi, %ecx
2605; X64-NOBMI-NEXT:    movq (%rdi), %rsi
2606; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2607; X64-NOBMI-NEXT:    shrq %cl, %rsi
2608; X64-NOBMI-NEXT:    movq $-1, %rax
2609; X64-NOBMI-NEXT:    movl %edx, %ecx
2610; X64-NOBMI-NEXT:    shlq %cl, %rax
2611; X64-NOBMI-NEXT:    notq %rax
2612; X64-NOBMI-NEXT:    andq %rsi, %rax
2613; X64-NOBMI-NEXT:    retq
2614;
2615; X64-BMI1NOTBM-LABEL: bextr64_b3_load_indexzext:
2616; X64-BMI1NOTBM:       # %bb.0:
2617; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
2618; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2619; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2620; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2621; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
2622; X64-BMI1NOTBM-NEXT:    retq
2623;
2624; X64-BMI1BMI2-LABEL: bextr64_b3_load_indexzext:
2625; X64-BMI1BMI2:       # %bb.0:
2626; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
2627; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2628; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
2629; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2630; X64-BMI1BMI2-NEXT:    retq
2631  %val = load i64, i64* %w
2632  %skip = zext i8 %numskipbits to i64
2633  %shifted = lshr i64 %val, %skip
2634  %conv = zext i8 %numlowbits to i64
2635  %notmask = shl i64 -1, %conv
2636  %mask = xor i64 %notmask, -1
2637  %masked = and i64 %mask, %shifted
2638  ret i64 %masked
2639}
2640
2641define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2642; X86-NOBMI-LABEL: bextr64_b4_commutative:
2643; X86-NOBMI:       # %bb.0:
2644; X86-NOBMI-NEXT:    pushl %edi
2645; X86-NOBMI-NEXT:    pushl %esi
2646; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2647; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2648; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2649; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2650; X86-NOBMI-NEXT:    movl %esi, %edx
2651; X86-NOBMI-NEXT:    shrl %cl, %edx
2652; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
2653; X86-NOBMI-NEXT:    testb $32, %cl
2654; X86-NOBMI-NEXT:    je .LBB24_2
2655; X86-NOBMI-NEXT:  # %bb.1:
2656; X86-NOBMI-NEXT:    movl %edx, %eax
2657; X86-NOBMI-NEXT:    xorl %edx, %edx
2658; X86-NOBMI-NEXT:  .LBB24_2:
2659; X86-NOBMI-NEXT:    movl $-1, %edi
2660; X86-NOBMI-NEXT:    movl $-1, %esi
2661; X86-NOBMI-NEXT:    movb %ch, %cl
2662; X86-NOBMI-NEXT:    shll %cl, %esi
2663; X86-NOBMI-NEXT:    shldl %cl, %edi, %edi
2664; X86-NOBMI-NEXT:    testb $32, %ch
2665; X86-NOBMI-NEXT:    je .LBB24_4
2666; X86-NOBMI-NEXT:  # %bb.3:
2667; X86-NOBMI-NEXT:    movl %esi, %edi
2668; X86-NOBMI-NEXT:    xorl %esi, %esi
2669; X86-NOBMI-NEXT:  .LBB24_4:
2670; X86-NOBMI-NEXT:    notl %edi
2671; X86-NOBMI-NEXT:    andl %edi, %edx
2672; X86-NOBMI-NEXT:    notl %esi
2673; X86-NOBMI-NEXT:    andl %esi, %eax
2674; X86-NOBMI-NEXT:    popl %esi
2675; X86-NOBMI-NEXT:    popl %edi
2676; X86-NOBMI-NEXT:    retl
2677;
2678; X86-BMI1NOTBM-LABEL: bextr64_b4_commutative:
2679; X86-BMI1NOTBM:       # %bb.0:
2680; X86-BMI1NOTBM-NEXT:    pushl %ebx
2681; X86-BMI1NOTBM-NEXT:    pushl %edi
2682; X86-BMI1NOTBM-NEXT:    pushl %esi
2683; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2684; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2685; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
2686; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2687; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2688; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2689; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2690; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2691; X86-BMI1NOTBM-NEXT:    je .LBB24_2
2692; X86-BMI1NOTBM-NEXT:  # %bb.1:
2693; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2694; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2695; X86-BMI1NOTBM-NEXT:  .LBB24_2:
2696; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2697; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2698; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2699; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2700; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2701; X86-BMI1NOTBM-NEXT:    testb $32, %al
2702; X86-BMI1NOTBM-NEXT:    je .LBB24_4
2703; X86-BMI1NOTBM-NEXT:  # %bb.3:
2704; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2705; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2706; X86-BMI1NOTBM-NEXT:  .LBB24_4:
2707; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2708; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2709; X86-BMI1NOTBM-NEXT:    popl %esi
2710; X86-BMI1NOTBM-NEXT:    popl %edi
2711; X86-BMI1NOTBM-NEXT:    popl %ebx
2712; X86-BMI1NOTBM-NEXT:    retl
2713;
2714; X86-BMI1BMI2-LABEL: bextr64_b4_commutative:
2715; X86-BMI1BMI2:       # %bb.0:
2716; X86-BMI1BMI2-NEXT:    pushl %ebx
2717; X86-BMI1BMI2-NEXT:    pushl %edi
2718; X86-BMI1BMI2-NEXT:    pushl %esi
2719; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2720; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2721; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2722; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2723; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
2724; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
2725; X86-BMI1BMI2-NEXT:    testb $32, %cl
2726; X86-BMI1BMI2-NEXT:    je .LBB24_2
2727; X86-BMI1BMI2-NEXT:  # %bb.1:
2728; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2729; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2730; X86-BMI1BMI2-NEXT:  .LBB24_2:
2731; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2732; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2733; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2734; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2735; X86-BMI1BMI2-NEXT:    testb $32, %al
2736; X86-BMI1BMI2-NEXT:    je .LBB24_4
2737; X86-BMI1BMI2-NEXT:  # %bb.3:
2738; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2739; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2740; X86-BMI1BMI2-NEXT:  .LBB24_4:
2741; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2742; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2743; X86-BMI1BMI2-NEXT:    popl %esi
2744; X86-BMI1BMI2-NEXT:    popl %edi
2745; X86-BMI1BMI2-NEXT:    popl %ebx
2746; X86-BMI1BMI2-NEXT:    retl
2747;
2748; X64-NOBMI-LABEL: bextr64_b4_commutative:
2749; X64-NOBMI:       # %bb.0:
2750; X64-NOBMI-NEXT:    movq %rsi, %rcx
2751; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2752; X64-NOBMI-NEXT:    shrq %cl, %rdi
2753; X64-NOBMI-NEXT:    movq $-1, %rax
2754; X64-NOBMI-NEXT:    movl %edx, %ecx
2755; X64-NOBMI-NEXT:    shlq %cl, %rax
2756; X64-NOBMI-NEXT:    notq %rax
2757; X64-NOBMI-NEXT:    andq %rdi, %rax
2758; X64-NOBMI-NEXT:    retq
2759;
2760; X64-BMI1NOTBM-LABEL: bextr64_b4_commutative:
2761; X64-BMI1NOTBM:       # %bb.0:
2762; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2763; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2764; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2765; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
2766; X64-BMI1NOTBM-NEXT:    retq
2767;
2768; X64-BMI1BMI2-LABEL: bextr64_b4_commutative:
2769; X64-BMI1BMI2:       # %bb.0:
2770; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2771; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2772; X64-BMI1BMI2-NEXT:    retq
2773  %shifted = lshr i64 %val, %numskipbits
2774  %notmask = shl i64 -1, %numlowbits
2775  %mask = xor i64 %notmask, -1
2776  %masked = and i64 %shifted, %mask ; swapped order
2777  ret i64 %masked
2778}
2779
2780define i64 @bextr64_b5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2781; X86-NOBMI-LABEL: bextr64_b5_skipextrauses:
2782; X86-NOBMI:       # %bb.0:
2783; X86-NOBMI-NEXT:    pushl %ebp
2784; X86-NOBMI-NEXT:    pushl %ebx
2785; X86-NOBMI-NEXT:    pushl %edi
2786; X86-NOBMI-NEXT:    pushl %esi
2787; X86-NOBMI-NEXT:    subl $12, %esp
2788; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2789; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
2790; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2791; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2792; X86-NOBMI-NEXT:    movl %esi, %ebp
2793; X86-NOBMI-NEXT:    movl %eax, %ecx
2794; X86-NOBMI-NEXT:    shrl %cl, %ebp
2795; X86-NOBMI-NEXT:    shrdl %cl, %esi, %ebx
2796; X86-NOBMI-NEXT:    testb $32, %al
2797; X86-NOBMI-NEXT:    je .LBB25_2
2798; X86-NOBMI-NEXT:  # %bb.1:
2799; X86-NOBMI-NEXT:    movl %ebp, %ebx
2800; X86-NOBMI-NEXT:    xorl %ebp, %ebp
2801; X86-NOBMI-NEXT:  .LBB25_2:
2802; X86-NOBMI-NEXT:    movl $-1, %esi
2803; X86-NOBMI-NEXT:    movl $-1, %edi
2804; X86-NOBMI-NEXT:    movl %edx, %ecx
2805; X86-NOBMI-NEXT:    shll %cl, %edi
2806; X86-NOBMI-NEXT:    shldl %cl, %esi, %esi
2807; X86-NOBMI-NEXT:    testb $32, %dl
2808; X86-NOBMI-NEXT:    je .LBB25_4
2809; X86-NOBMI-NEXT:  # %bb.3:
2810; X86-NOBMI-NEXT:    movl %edi, %esi
2811; X86-NOBMI-NEXT:    xorl %edi, %edi
2812; X86-NOBMI-NEXT:  .LBB25_4:
2813; X86-NOBMI-NEXT:    notl %esi
2814; X86-NOBMI-NEXT:    andl %ebp, %esi
2815; X86-NOBMI-NEXT:    notl %edi
2816; X86-NOBMI-NEXT:    andl %ebx, %edi
2817; X86-NOBMI-NEXT:    subl $8, %esp
2818; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
2819; X86-NOBMI-NEXT:    pushl %eax
2820; X86-NOBMI-NEXT:    calll use64
2821; X86-NOBMI-NEXT:    addl $16, %esp
2822; X86-NOBMI-NEXT:    movl %edi, %eax
2823; X86-NOBMI-NEXT:    movl %esi, %edx
2824; X86-NOBMI-NEXT:    addl $12, %esp
2825; X86-NOBMI-NEXT:    popl %esi
2826; X86-NOBMI-NEXT:    popl %edi
2827; X86-NOBMI-NEXT:    popl %ebx
2828; X86-NOBMI-NEXT:    popl %ebp
2829; X86-NOBMI-NEXT:    retl
2830;
2831; X86-BMI1NOTBM-LABEL: bextr64_b5_skipextrauses:
2832; X86-BMI1NOTBM:       # %bb.0:
2833; X86-BMI1NOTBM-NEXT:    pushl %ebp
2834; X86-BMI1NOTBM-NEXT:    pushl %ebx
2835; X86-BMI1NOTBM-NEXT:    pushl %edi
2836; X86-BMI1NOTBM-NEXT:    pushl %esi
2837; X86-BMI1NOTBM-NEXT:    subl $12, %esp
2838; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %dl
2839; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2840; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
2841; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2842; X86-BMI1NOTBM-NEXT:    movl %ebx, %esi
2843; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2844; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
2845; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %edi
2846; X86-BMI1NOTBM-NEXT:    testb $32, %al
2847; X86-BMI1NOTBM-NEXT:    je .LBB25_2
2848; X86-BMI1NOTBM-NEXT:  # %bb.1:
2849; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
2850; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
2851; X86-BMI1NOTBM-NEXT:  .LBB25_2:
2852; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2853; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
2854; X86-BMI1NOTBM-NEXT:    movl %edx, %ecx
2855; X86-BMI1NOTBM-NEXT:    shll %cl, %ebp
2856; X86-BMI1NOTBM-NEXT:    shldl %cl, %ebx, %ebx
2857; X86-BMI1NOTBM-NEXT:    testb $32, %dl
2858; X86-BMI1NOTBM-NEXT:    je .LBB25_4
2859; X86-BMI1NOTBM-NEXT:  # %bb.3:
2860; X86-BMI1NOTBM-NEXT:    movl %ebp, %ebx
2861; X86-BMI1NOTBM-NEXT:    xorl %ebp, %ebp
2862; X86-BMI1NOTBM-NEXT:  .LBB25_4:
2863; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %esi
2864; X86-BMI1NOTBM-NEXT:    andnl %edi, %ebp, %edi
2865; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2866; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
2867; X86-BMI1NOTBM-NEXT:    pushl %eax
2868; X86-BMI1NOTBM-NEXT:    calll use64
2869; X86-BMI1NOTBM-NEXT:    addl $16, %esp
2870; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
2871; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
2872; X86-BMI1NOTBM-NEXT:    addl $12, %esp
2873; X86-BMI1NOTBM-NEXT:    popl %esi
2874; X86-BMI1NOTBM-NEXT:    popl %edi
2875; X86-BMI1NOTBM-NEXT:    popl %ebx
2876; X86-BMI1NOTBM-NEXT:    popl %ebp
2877; X86-BMI1NOTBM-NEXT:    retl
2878;
2879; X86-BMI1BMI2-LABEL: bextr64_b5_skipextrauses:
2880; X86-BMI1BMI2:       # %bb.0:
2881; X86-BMI1BMI2-NEXT:    pushl %ebp
2882; X86-BMI1BMI2-NEXT:    pushl %ebx
2883; X86-BMI1BMI2-NEXT:    pushl %edi
2884; X86-BMI1BMI2-NEXT:    pushl %esi
2885; X86-BMI1BMI2-NEXT:    subl $12, %esp
2886; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
2887; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
2888; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2889; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2890; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2891; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
2892; X86-BMI1BMI2-NEXT:    shrxl %eax, %esi, %esi
2893; X86-BMI1BMI2-NEXT:    testb $32, %al
2894; X86-BMI1BMI2-NEXT:    je .LBB25_2
2895; X86-BMI1BMI2-NEXT:  # %bb.1:
2896; X86-BMI1BMI2-NEXT:    movl %esi, %edi
2897; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
2898; X86-BMI1BMI2-NEXT:  .LBB25_2:
2899; X86-BMI1BMI2-NEXT:    movl $-1, %ebp
2900; X86-BMI1BMI2-NEXT:    shlxl %edx, %ebp, %ebx
2901; X86-BMI1BMI2-NEXT:    movl %edx, %ecx
2902; X86-BMI1BMI2-NEXT:    shldl %cl, %ebp, %ebp
2903; X86-BMI1BMI2-NEXT:    testb $32, %dl
2904; X86-BMI1BMI2-NEXT:    je .LBB25_4
2905; X86-BMI1BMI2-NEXT:  # %bb.3:
2906; X86-BMI1BMI2-NEXT:    movl %ebx, %ebp
2907; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2908; X86-BMI1BMI2-NEXT:  .LBB25_4:
2909; X86-BMI1BMI2-NEXT:    andnl %esi, %ebp, %esi
2910; X86-BMI1BMI2-NEXT:    andnl %edi, %ebx, %edi
2911; X86-BMI1BMI2-NEXT:    subl $8, %esp
2912; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
2913; X86-BMI1BMI2-NEXT:    pushl %eax
2914; X86-BMI1BMI2-NEXT:    calll use64
2915; X86-BMI1BMI2-NEXT:    addl $16, %esp
2916; X86-BMI1BMI2-NEXT:    movl %edi, %eax
2917; X86-BMI1BMI2-NEXT:    movl %esi, %edx
2918; X86-BMI1BMI2-NEXT:    addl $12, %esp
2919; X86-BMI1BMI2-NEXT:    popl %esi
2920; X86-BMI1BMI2-NEXT:    popl %edi
2921; X86-BMI1BMI2-NEXT:    popl %ebx
2922; X86-BMI1BMI2-NEXT:    popl %ebp
2923; X86-BMI1BMI2-NEXT:    retl
2924;
2925; X64-NOBMI-LABEL: bextr64_b5_skipextrauses:
2926; X64-NOBMI:       # %bb.0:
2927; X64-NOBMI-NEXT:    pushq %rbx
2928; X64-NOBMI-NEXT:    movl %esi, %ecx
2929; X64-NOBMI-NEXT:    shrq %cl, %rdi
2930; X64-NOBMI-NEXT:    movq $-1, %rbx
2931; X64-NOBMI-NEXT:    movl %edx, %ecx
2932; X64-NOBMI-NEXT:    shlq %cl, %rbx
2933; X64-NOBMI-NEXT:    notq %rbx
2934; X64-NOBMI-NEXT:    andq %rdi, %rbx
2935; X64-NOBMI-NEXT:    movq %rsi, %rdi
2936; X64-NOBMI-NEXT:    callq use64
2937; X64-NOBMI-NEXT:    movq %rbx, %rax
2938; X64-NOBMI-NEXT:    popq %rbx
2939; X64-NOBMI-NEXT:    retq
2940;
2941; X64-BMI1NOTBM-LABEL: bextr64_b5_skipextrauses:
2942; X64-BMI1NOTBM:       # %bb.0:
2943; X64-BMI1NOTBM-NEXT:    pushq %rbx
2944; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2945; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2946; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2947; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rbx
2948; X64-BMI1NOTBM-NEXT:    movq %rsi, %rdi
2949; X64-BMI1NOTBM-NEXT:    callq use64
2950; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
2951; X64-BMI1NOTBM-NEXT:    popq %rbx
2952; X64-BMI1NOTBM-NEXT:    retq
2953;
2954; X64-BMI1BMI2-LABEL: bextr64_b5_skipextrauses:
2955; X64-BMI1BMI2:       # %bb.0:
2956; X64-BMI1BMI2-NEXT:    pushq %rbx
2957; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2958; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
2959; X64-BMI1BMI2-NEXT:    movq %rsi, %rdi
2960; X64-BMI1BMI2-NEXT:    callq use64
2961; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
2962; X64-BMI1BMI2-NEXT:    popq %rbx
2963; X64-BMI1BMI2-NEXT:    retq
2964  %shifted = lshr i64 %val, %numskipbits
2965  %notmask = shl i64 -1, %numlowbits
2966  %mask = xor i64 %notmask, -1
2967  %masked = and i64 %mask, %shifted
2968  call void @use64(i64 %numskipbits)
2969  ret i64 %masked
2970}
2971
2972; ---------------------------------------------------------------------------- ;
2973; Pattern c. 32-bit
2974; ---------------------------------------------------------------------------- ;
2975
2976define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2977; X86-NOBMI-LABEL: bextr32_c0:
2978; X86-NOBMI:       # %bb.0:
2979; X86-NOBMI-NEXT:    pushl %edi
2980; X86-NOBMI-NEXT:    pushl %esi
2981; X86-NOBMI-NEXT:    pushl %eax
2982; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2983; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
2984; X86-NOBMI-NEXT:    shrl %cl, %edi
2985; X86-NOBMI-NEXT:    xorl %ecx, %ecx
2986; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
2987; X86-NOBMI-NEXT:    movl $-1, %esi
2988; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2989; X86-NOBMI-NEXT:    shrl %cl, %esi
2990; X86-NOBMI-NEXT:    movl %esi, (%esp)
2991; X86-NOBMI-NEXT:    calll use32
2992; X86-NOBMI-NEXT:    andl %edi, %esi
2993; X86-NOBMI-NEXT:    movl %esi, %eax
2994; X86-NOBMI-NEXT:    addl $4, %esp
2995; X86-NOBMI-NEXT:    popl %esi
2996; X86-NOBMI-NEXT:    popl %edi
2997; X86-NOBMI-NEXT:    retl
2998;
2999; X86-BMI1NOTBM-LABEL: bextr32_c0:
3000; X86-BMI1NOTBM:       # %bb.0:
3001; X86-BMI1NOTBM-NEXT:    pushl %edi
3002; X86-BMI1NOTBM-NEXT:    pushl %esi
3003; X86-BMI1NOTBM-NEXT:    pushl %eax
3004; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3005; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3006; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3007; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3008; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3009; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3010; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3011; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3012; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3013; X86-BMI1NOTBM-NEXT:    calll use32
3014; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3015; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3016; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3017; X86-BMI1NOTBM-NEXT:    popl %esi
3018; X86-BMI1NOTBM-NEXT:    popl %edi
3019; X86-BMI1NOTBM-NEXT:    retl
3020;
3021; X86-BMI1BMI2-LABEL: bextr32_c0:
3022; X86-BMI1BMI2:       # %bb.0:
3023; X86-BMI1BMI2-NEXT:    pushl %ebx
3024; X86-BMI1BMI2-NEXT:    pushl %esi
3025; X86-BMI1BMI2-NEXT:    pushl %eax
3026; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3027; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3028; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
3029; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3030; X86-BMI1BMI2-NEXT:    negb %al
3031; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3032; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3033; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3034; X86-BMI1BMI2-NEXT:    calll use32
3035; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3036; X86-BMI1BMI2-NEXT:    addl $4, %esp
3037; X86-BMI1BMI2-NEXT:    popl %esi
3038; X86-BMI1BMI2-NEXT:    popl %ebx
3039; X86-BMI1BMI2-NEXT:    retl
3040;
3041; X64-NOBMI-LABEL: bextr32_c0:
3042; X64-NOBMI:       # %bb.0:
3043; X64-NOBMI-NEXT:    pushq %rbp
3044; X64-NOBMI-NEXT:    pushq %rbx
3045; X64-NOBMI-NEXT:    pushq %rax
3046; X64-NOBMI-NEXT:    movl %esi, %ecx
3047; X64-NOBMI-NEXT:    movl %edi, %ebx
3048; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3049; X64-NOBMI-NEXT:    shrl %cl, %ebx
3050; X64-NOBMI-NEXT:    negb %dl
3051; X64-NOBMI-NEXT:    movl $-1, %ebp
3052; X64-NOBMI-NEXT:    movl %edx, %ecx
3053; X64-NOBMI-NEXT:    shrl %cl, %ebp
3054; X64-NOBMI-NEXT:    movl %ebp, %edi
3055; X64-NOBMI-NEXT:    callq use32
3056; X64-NOBMI-NEXT:    andl %ebx, %ebp
3057; X64-NOBMI-NEXT:    movl %ebp, %eax
3058; X64-NOBMI-NEXT:    addq $8, %rsp
3059; X64-NOBMI-NEXT:    popq %rbx
3060; X64-NOBMI-NEXT:    popq %rbp
3061; X64-NOBMI-NEXT:    retq
3062;
3063; X64-BMI1NOTBM-LABEL: bextr32_c0:
3064; X64-BMI1NOTBM:       # %bb.0:
3065; X64-BMI1NOTBM-NEXT:    pushq %rbp
3066; X64-BMI1NOTBM-NEXT:    pushq %rbx
3067; X64-BMI1NOTBM-NEXT:    pushq %rax
3068; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3069; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
3070; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3071; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3072; X64-BMI1NOTBM-NEXT:    negb %dl
3073; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
3074; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3075; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3076; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
3077; X64-BMI1NOTBM-NEXT:    callq use32
3078; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
3079; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
3080; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3081; X64-BMI1NOTBM-NEXT:    popq %rbx
3082; X64-BMI1NOTBM-NEXT:    popq %rbp
3083; X64-BMI1NOTBM-NEXT:    retq
3084;
3085; X64-BMI1BMI2-LABEL: bextr32_c0:
3086; X64-BMI1BMI2:       # %bb.0:
3087; X64-BMI1BMI2-NEXT:    pushq %rbp
3088; X64-BMI1BMI2-NEXT:    pushq %rbx
3089; X64-BMI1BMI2-NEXT:    pushq %rax
3090; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3091; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
3092; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3093; X64-BMI1BMI2-NEXT:    negb %al
3094; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3095; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3096; X64-BMI1BMI2-NEXT:    callq use32
3097; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3098; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3099; X64-BMI1BMI2-NEXT:    popq %rbx
3100; X64-BMI1BMI2-NEXT:    popq %rbp
3101; X64-BMI1BMI2-NEXT:    retq
3102  %shifted = lshr i32 %val, %numskipbits
3103  %numhighbits = sub i32 32, %numlowbits
3104  %mask = lshr i32 -1, %numhighbits
3105  call void @use32(i32 %mask)
3106  %masked = and i32 %mask, %shifted
3107  ret i32 %masked
3108}
3109
3110define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
3111; X86-NOBMI-LABEL: bextr32_c1_indexzext:
3112; X86-NOBMI:       # %bb.0:
3113; X86-NOBMI-NEXT:    pushl %edi
3114; X86-NOBMI-NEXT:    pushl %esi
3115; X86-NOBMI-NEXT:    pushl %eax
3116; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3117; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3118; X86-NOBMI-NEXT:    shrl %cl, %edi
3119; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3120; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3121; X86-NOBMI-NEXT:    movl $-1, %esi
3122; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3123; X86-NOBMI-NEXT:    shrl %cl, %esi
3124; X86-NOBMI-NEXT:    movl %esi, (%esp)
3125; X86-NOBMI-NEXT:    calll use32
3126; X86-NOBMI-NEXT:    andl %edi, %esi
3127; X86-NOBMI-NEXT:    movl %esi, %eax
3128; X86-NOBMI-NEXT:    addl $4, %esp
3129; X86-NOBMI-NEXT:    popl %esi
3130; X86-NOBMI-NEXT:    popl %edi
3131; X86-NOBMI-NEXT:    retl
3132;
3133; X86-BMI1NOTBM-LABEL: bextr32_c1_indexzext:
3134; X86-BMI1NOTBM:       # %bb.0:
3135; X86-BMI1NOTBM-NEXT:    pushl %edi
3136; X86-BMI1NOTBM-NEXT:    pushl %esi
3137; X86-BMI1NOTBM-NEXT:    pushl %eax
3138; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3139; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3140; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3141; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3142; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3143; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3144; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3145; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3146; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3147; X86-BMI1NOTBM-NEXT:    calll use32
3148; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3149; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3150; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3151; X86-BMI1NOTBM-NEXT:    popl %esi
3152; X86-BMI1NOTBM-NEXT:    popl %edi
3153; X86-BMI1NOTBM-NEXT:    retl
3154;
3155; X86-BMI1BMI2-LABEL: bextr32_c1_indexzext:
3156; X86-BMI1BMI2:       # %bb.0:
3157; X86-BMI1BMI2-NEXT:    pushl %ebx
3158; X86-BMI1BMI2-NEXT:    pushl %esi
3159; X86-BMI1BMI2-NEXT:    pushl %eax
3160; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3161; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3162; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
3163; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3164; X86-BMI1BMI2-NEXT:    negb %al
3165; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3166; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3167; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3168; X86-BMI1BMI2-NEXT:    calll use32
3169; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3170; X86-BMI1BMI2-NEXT:    addl $4, %esp
3171; X86-BMI1BMI2-NEXT:    popl %esi
3172; X86-BMI1BMI2-NEXT:    popl %ebx
3173; X86-BMI1BMI2-NEXT:    retl
3174;
3175; X64-NOBMI-LABEL: bextr32_c1_indexzext:
3176; X64-NOBMI:       # %bb.0:
3177; X64-NOBMI-NEXT:    pushq %rbp
3178; X64-NOBMI-NEXT:    pushq %rbx
3179; X64-NOBMI-NEXT:    pushq %rax
3180; X64-NOBMI-NEXT:    movl %esi, %ecx
3181; X64-NOBMI-NEXT:    movl %edi, %ebx
3182; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3183; X64-NOBMI-NEXT:    shrl %cl, %ebx
3184; X64-NOBMI-NEXT:    negb %dl
3185; X64-NOBMI-NEXT:    movl $-1, %ebp
3186; X64-NOBMI-NEXT:    movl %edx, %ecx
3187; X64-NOBMI-NEXT:    shrl %cl, %ebp
3188; X64-NOBMI-NEXT:    movl %ebp, %edi
3189; X64-NOBMI-NEXT:    callq use32
3190; X64-NOBMI-NEXT:    andl %ebx, %ebp
3191; X64-NOBMI-NEXT:    movl %ebp, %eax
3192; X64-NOBMI-NEXT:    addq $8, %rsp
3193; X64-NOBMI-NEXT:    popq %rbx
3194; X64-NOBMI-NEXT:    popq %rbp
3195; X64-NOBMI-NEXT:    retq
3196;
3197; X64-BMI1NOTBM-LABEL: bextr32_c1_indexzext:
3198; X64-BMI1NOTBM:       # %bb.0:
3199; X64-BMI1NOTBM-NEXT:    pushq %rbp
3200; X64-BMI1NOTBM-NEXT:    pushq %rbx
3201; X64-BMI1NOTBM-NEXT:    pushq %rax
3202; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3203; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
3204; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3205; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3206; X64-BMI1NOTBM-NEXT:    negb %dl
3207; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
3208; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3209; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3210; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
3211; X64-BMI1NOTBM-NEXT:    callq use32
3212; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
3213; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
3214; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3215; X64-BMI1NOTBM-NEXT:    popq %rbx
3216; X64-BMI1NOTBM-NEXT:    popq %rbp
3217; X64-BMI1NOTBM-NEXT:    retq
3218;
3219; X64-BMI1BMI2-LABEL: bextr32_c1_indexzext:
3220; X64-BMI1BMI2:       # %bb.0:
3221; X64-BMI1BMI2-NEXT:    pushq %rbp
3222; X64-BMI1BMI2-NEXT:    pushq %rbx
3223; X64-BMI1BMI2-NEXT:    pushq %rax
3224; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3225; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
3226; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3227; X64-BMI1BMI2-NEXT:    negb %al
3228; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3229; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3230; X64-BMI1BMI2-NEXT:    callq use32
3231; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3232; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3233; X64-BMI1BMI2-NEXT:    popq %rbx
3234; X64-BMI1BMI2-NEXT:    popq %rbp
3235; X64-BMI1BMI2-NEXT:    retq
3236  %skip = zext i8 %numskipbits to i32
3237  %shifted = lshr i32 %val, %skip
3238  %numhighbits = sub i8 32, %numlowbits
3239  %sh_prom = zext i8 %numhighbits to i32
3240  %mask = lshr i32 -1, %sh_prom
3241  call void @use32(i32 %mask)
3242  %masked = and i32 %mask, %shifted
3243  ret i32 %masked
3244}
3245
3246define i32 @bextr32_c2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
3247; X86-NOBMI-LABEL: bextr32_c2_load:
3248; X86-NOBMI:       # %bb.0:
3249; X86-NOBMI-NEXT:    pushl %edi
3250; X86-NOBMI-NEXT:    pushl %esi
3251; X86-NOBMI-NEXT:    pushl %eax
3252; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3253; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3254; X86-NOBMI-NEXT:    movl (%eax), %edi
3255; X86-NOBMI-NEXT:    shrl %cl, %edi
3256; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3257; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3258; X86-NOBMI-NEXT:    movl $-1, %esi
3259; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3260; X86-NOBMI-NEXT:    shrl %cl, %esi
3261; X86-NOBMI-NEXT:    movl %esi, (%esp)
3262; X86-NOBMI-NEXT:    calll use32
3263; X86-NOBMI-NEXT:    andl %edi, %esi
3264; X86-NOBMI-NEXT:    movl %esi, %eax
3265; X86-NOBMI-NEXT:    addl $4, %esp
3266; X86-NOBMI-NEXT:    popl %esi
3267; X86-NOBMI-NEXT:    popl %edi
3268; X86-NOBMI-NEXT:    retl
3269;
3270; X86-BMI1NOTBM-LABEL: bextr32_c2_load:
3271; X86-BMI1NOTBM:       # %bb.0:
3272; X86-BMI1NOTBM-NEXT:    pushl %edi
3273; X86-BMI1NOTBM-NEXT:    pushl %esi
3274; X86-BMI1NOTBM-NEXT:    pushl %eax
3275; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3276; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3277; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
3278; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3279; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3280; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3281; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3282; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3283; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3284; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3285; X86-BMI1NOTBM-NEXT:    calll use32
3286; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3287; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3288; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3289; X86-BMI1NOTBM-NEXT:    popl %esi
3290; X86-BMI1NOTBM-NEXT:    popl %edi
3291; X86-BMI1NOTBM-NEXT:    retl
3292;
3293; X86-BMI1BMI2-LABEL: bextr32_c2_load:
3294; X86-BMI1BMI2:       # %bb.0:
3295; X86-BMI1BMI2-NEXT:    pushl %ebx
3296; X86-BMI1BMI2-NEXT:    pushl %esi
3297; X86-BMI1BMI2-NEXT:    pushl %eax
3298; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3299; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3300; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3301; X86-BMI1BMI2-NEXT:    shrxl %ecx, (%eax), %esi
3302; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3303; X86-BMI1BMI2-NEXT:    negb %al
3304; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3305; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3306; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3307; X86-BMI1BMI2-NEXT:    calll use32
3308; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3309; X86-BMI1BMI2-NEXT:    addl $4, %esp
3310; X86-BMI1BMI2-NEXT:    popl %esi
3311; X86-BMI1BMI2-NEXT:    popl %ebx
3312; X86-BMI1BMI2-NEXT:    retl
3313;
3314; X64-NOBMI-LABEL: bextr32_c2_load:
3315; X64-NOBMI:       # %bb.0:
3316; X64-NOBMI-NEXT:    pushq %rbp
3317; X64-NOBMI-NEXT:    pushq %rbx
3318; X64-NOBMI-NEXT:    pushq %rax
3319; X64-NOBMI-NEXT:    movl %esi, %ecx
3320; X64-NOBMI-NEXT:    movl (%rdi), %ebp
3321; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3322; X64-NOBMI-NEXT:    shrl %cl, %ebp
3323; X64-NOBMI-NEXT:    negb %dl
3324; X64-NOBMI-NEXT:    movl $-1, %ebx
3325; X64-NOBMI-NEXT:    movl %edx, %ecx
3326; X64-NOBMI-NEXT:    shrl %cl, %ebx
3327; X64-NOBMI-NEXT:    movl %ebx, %edi
3328; X64-NOBMI-NEXT:    callq use32
3329; X64-NOBMI-NEXT:    andl %ebp, %ebx
3330; X64-NOBMI-NEXT:    movl %ebx, %eax
3331; X64-NOBMI-NEXT:    addq $8, %rsp
3332; X64-NOBMI-NEXT:    popq %rbx
3333; X64-NOBMI-NEXT:    popq %rbp
3334; X64-NOBMI-NEXT:    retq
3335;
3336; X64-BMI1NOTBM-LABEL: bextr32_c2_load:
3337; X64-BMI1NOTBM:       # %bb.0:
3338; X64-BMI1NOTBM-NEXT:    pushq %rbp
3339; X64-BMI1NOTBM-NEXT:    pushq %rbx
3340; X64-BMI1NOTBM-NEXT:    pushq %rax
3341; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3342; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebp
3343; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3344; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3345; X64-BMI1NOTBM-NEXT:    negb %dl
3346; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
3347; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3348; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3349; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
3350; X64-BMI1NOTBM-NEXT:    callq use32
3351; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
3352; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
3353; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3354; X64-BMI1NOTBM-NEXT:    popq %rbx
3355; X64-BMI1NOTBM-NEXT:    popq %rbp
3356; X64-BMI1NOTBM-NEXT:    retq
3357;
3358; X64-BMI1BMI2-LABEL: bextr32_c2_load:
3359; X64-BMI1BMI2:       # %bb.0:
3360; X64-BMI1BMI2-NEXT:    pushq %rbp
3361; X64-BMI1BMI2-NEXT:    pushq %rbx
3362; X64-BMI1BMI2-NEXT:    pushq %rax
3363; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3364; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
3365; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3366; X64-BMI1BMI2-NEXT:    negb %al
3367; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3368; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3369; X64-BMI1BMI2-NEXT:    callq use32
3370; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3371; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3372; X64-BMI1BMI2-NEXT:    popq %rbx
3373; X64-BMI1BMI2-NEXT:    popq %rbp
3374; X64-BMI1BMI2-NEXT:    retq
3375  %val = load i32, i32* %w
3376  %shifted = lshr i32 %val, %numskipbits
3377  %numhighbits = sub i32 32, %numlowbits
3378  %mask = lshr i32 -1, %numhighbits
3379  call void @use32(i32 %mask)
3380  %masked = and i32 %mask, %shifted
3381  ret i32 %masked
3382}
3383
3384define i32 @bextr32_c3_load_indexzext(i32* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
3385; X86-NOBMI-LABEL: bextr32_c3_load_indexzext:
3386; X86-NOBMI:       # %bb.0:
3387; X86-NOBMI-NEXT:    pushl %edi
3388; X86-NOBMI-NEXT:    pushl %esi
3389; X86-NOBMI-NEXT:    pushl %eax
3390; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3391; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3392; X86-NOBMI-NEXT:    movl (%eax), %edi
3393; X86-NOBMI-NEXT:    shrl %cl, %edi
3394; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3395; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3396; X86-NOBMI-NEXT:    movl $-1, %esi
3397; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3398; X86-NOBMI-NEXT:    shrl %cl, %esi
3399; X86-NOBMI-NEXT:    movl %esi, (%esp)
3400; X86-NOBMI-NEXT:    calll use32
3401; X86-NOBMI-NEXT:    andl %edi, %esi
3402; X86-NOBMI-NEXT:    movl %esi, %eax
3403; X86-NOBMI-NEXT:    addl $4, %esp
3404; X86-NOBMI-NEXT:    popl %esi
3405; X86-NOBMI-NEXT:    popl %edi
3406; X86-NOBMI-NEXT:    retl
3407;
3408; X86-BMI1NOTBM-LABEL: bextr32_c3_load_indexzext:
3409; X86-BMI1NOTBM:       # %bb.0:
3410; X86-BMI1NOTBM-NEXT:    pushl %edi
3411; X86-BMI1NOTBM-NEXT:    pushl %esi
3412; X86-BMI1NOTBM-NEXT:    pushl %eax
3413; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3414; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3415; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
3416; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3417; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3418; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3419; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3420; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3421; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3422; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3423; X86-BMI1NOTBM-NEXT:    calll use32
3424; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3425; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3426; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3427; X86-BMI1NOTBM-NEXT:    popl %esi
3428; X86-BMI1NOTBM-NEXT:    popl %edi
3429; X86-BMI1NOTBM-NEXT:    retl
3430;
3431; X86-BMI1BMI2-LABEL: bextr32_c3_load_indexzext:
3432; X86-BMI1BMI2:       # %bb.0:
3433; X86-BMI1BMI2-NEXT:    pushl %ebx
3434; X86-BMI1BMI2-NEXT:    pushl %esi
3435; X86-BMI1BMI2-NEXT:    pushl %eax
3436; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3437; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3438; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3439; X86-BMI1BMI2-NEXT:    shrxl %ecx, (%eax), %esi
3440; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3441; X86-BMI1BMI2-NEXT:    negb %al
3442; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3443; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3444; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3445; X86-BMI1BMI2-NEXT:    calll use32
3446; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3447; X86-BMI1BMI2-NEXT:    addl $4, %esp
3448; X86-BMI1BMI2-NEXT:    popl %esi
3449; X86-BMI1BMI2-NEXT:    popl %ebx
3450; X86-BMI1BMI2-NEXT:    retl
3451;
3452; X64-NOBMI-LABEL: bextr32_c3_load_indexzext:
3453; X64-NOBMI:       # %bb.0:
3454; X64-NOBMI-NEXT:    pushq %rbp
3455; X64-NOBMI-NEXT:    pushq %rbx
3456; X64-NOBMI-NEXT:    pushq %rax
3457; X64-NOBMI-NEXT:    movl %esi, %ecx
3458; X64-NOBMI-NEXT:    movl (%rdi), %ebp
3459; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3460; X64-NOBMI-NEXT:    shrl %cl, %ebp
3461; X64-NOBMI-NEXT:    negb %dl
3462; X64-NOBMI-NEXT:    movl $-1, %ebx
3463; X64-NOBMI-NEXT:    movl %edx, %ecx
3464; X64-NOBMI-NEXT:    shrl %cl, %ebx
3465; X64-NOBMI-NEXT:    movl %ebx, %edi
3466; X64-NOBMI-NEXT:    callq use32
3467; X64-NOBMI-NEXT:    andl %ebp, %ebx
3468; X64-NOBMI-NEXT:    movl %ebx, %eax
3469; X64-NOBMI-NEXT:    addq $8, %rsp
3470; X64-NOBMI-NEXT:    popq %rbx
3471; X64-NOBMI-NEXT:    popq %rbp
3472; X64-NOBMI-NEXT:    retq
3473;
3474; X64-BMI1NOTBM-LABEL: bextr32_c3_load_indexzext:
3475; X64-BMI1NOTBM:       # %bb.0:
3476; X64-BMI1NOTBM-NEXT:    pushq %rbp
3477; X64-BMI1NOTBM-NEXT:    pushq %rbx
3478; X64-BMI1NOTBM-NEXT:    pushq %rax
3479; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3480; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebp
3481; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3482; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3483; X64-BMI1NOTBM-NEXT:    negb %dl
3484; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
3485; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3486; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3487; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
3488; X64-BMI1NOTBM-NEXT:    callq use32
3489; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
3490; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
3491; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3492; X64-BMI1NOTBM-NEXT:    popq %rbx
3493; X64-BMI1NOTBM-NEXT:    popq %rbp
3494; X64-BMI1NOTBM-NEXT:    retq
3495;
3496; X64-BMI1BMI2-LABEL: bextr32_c3_load_indexzext:
3497; X64-BMI1BMI2:       # %bb.0:
3498; X64-BMI1BMI2-NEXT:    pushq %rbp
3499; X64-BMI1BMI2-NEXT:    pushq %rbx
3500; X64-BMI1BMI2-NEXT:    pushq %rax
3501; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3502; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
3503; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3504; X64-BMI1BMI2-NEXT:    negb %al
3505; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3506; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3507; X64-BMI1BMI2-NEXT:    callq use32
3508; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3509; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3510; X64-BMI1BMI2-NEXT:    popq %rbx
3511; X64-BMI1BMI2-NEXT:    popq %rbp
3512; X64-BMI1BMI2-NEXT:    retq
3513  %val = load i32, i32* %w
3514  %skip = zext i8 %numskipbits to i32
3515  %shifted = lshr i32 %val, %skip
3516  %numhighbits = sub i8 32, %numlowbits
3517  %sh_prom = zext i8 %numhighbits to i32
3518  %mask = lshr i32 -1, %sh_prom
3519  call void @use32(i32 %mask)
3520  %masked = and i32 %mask, %shifted
3521  ret i32 %masked
3522}
3523
3524define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
3525; X86-NOBMI-LABEL: bextr32_c4_commutative:
3526; X86-NOBMI:       # %bb.0:
3527; X86-NOBMI-NEXT:    pushl %edi
3528; X86-NOBMI-NEXT:    pushl %esi
3529; X86-NOBMI-NEXT:    pushl %eax
3530; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3531; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3532; X86-NOBMI-NEXT:    shrl %cl, %edi
3533; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3534; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3535; X86-NOBMI-NEXT:    movl $-1, %esi
3536; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3537; X86-NOBMI-NEXT:    shrl %cl, %esi
3538; X86-NOBMI-NEXT:    movl %esi, (%esp)
3539; X86-NOBMI-NEXT:    calll use32
3540; X86-NOBMI-NEXT:    andl %edi, %esi
3541; X86-NOBMI-NEXT:    movl %esi, %eax
3542; X86-NOBMI-NEXT:    addl $4, %esp
3543; X86-NOBMI-NEXT:    popl %esi
3544; X86-NOBMI-NEXT:    popl %edi
3545; X86-NOBMI-NEXT:    retl
3546;
3547; X86-BMI1NOTBM-LABEL: bextr32_c4_commutative:
3548; X86-BMI1NOTBM:       # %bb.0:
3549; X86-BMI1NOTBM-NEXT:    pushl %edi
3550; X86-BMI1NOTBM-NEXT:    pushl %esi
3551; X86-BMI1NOTBM-NEXT:    pushl %eax
3552; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3553; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3554; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3555; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3556; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3557; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3558; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3559; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3560; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3561; X86-BMI1NOTBM-NEXT:    calll use32
3562; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3563; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3564; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3565; X86-BMI1NOTBM-NEXT:    popl %esi
3566; X86-BMI1NOTBM-NEXT:    popl %edi
3567; X86-BMI1NOTBM-NEXT:    retl
3568;
3569; X86-BMI1BMI2-LABEL: bextr32_c4_commutative:
3570; X86-BMI1BMI2:       # %bb.0:
3571; X86-BMI1BMI2-NEXT:    pushl %ebx
3572; X86-BMI1BMI2-NEXT:    pushl %esi
3573; X86-BMI1BMI2-NEXT:    pushl %eax
3574; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3575; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3576; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
3577; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3578; X86-BMI1BMI2-NEXT:    negb %al
3579; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3580; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3581; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3582; X86-BMI1BMI2-NEXT:    calll use32
3583; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3584; X86-BMI1BMI2-NEXT:    addl $4, %esp
3585; X86-BMI1BMI2-NEXT:    popl %esi
3586; X86-BMI1BMI2-NEXT:    popl %ebx
3587; X86-BMI1BMI2-NEXT:    retl
3588;
3589; X64-NOBMI-LABEL: bextr32_c4_commutative:
3590; X64-NOBMI:       # %bb.0:
3591; X64-NOBMI-NEXT:    pushq %rbp
3592; X64-NOBMI-NEXT:    pushq %rbx
3593; X64-NOBMI-NEXT:    pushq %rax
3594; X64-NOBMI-NEXT:    movl %esi, %ecx
3595; X64-NOBMI-NEXT:    movl %edi, %ebx
3596; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3597; X64-NOBMI-NEXT:    shrl %cl, %ebx
3598; X64-NOBMI-NEXT:    negb %dl
3599; X64-NOBMI-NEXT:    movl $-1, %ebp
3600; X64-NOBMI-NEXT:    movl %edx, %ecx
3601; X64-NOBMI-NEXT:    shrl %cl, %ebp
3602; X64-NOBMI-NEXT:    movl %ebp, %edi
3603; X64-NOBMI-NEXT:    callq use32
3604; X64-NOBMI-NEXT:    andl %ebx, %ebp
3605; X64-NOBMI-NEXT:    movl %ebp, %eax
3606; X64-NOBMI-NEXT:    addq $8, %rsp
3607; X64-NOBMI-NEXT:    popq %rbx
3608; X64-NOBMI-NEXT:    popq %rbp
3609; X64-NOBMI-NEXT:    retq
3610;
3611; X64-BMI1NOTBM-LABEL: bextr32_c4_commutative:
3612; X64-BMI1NOTBM:       # %bb.0:
3613; X64-BMI1NOTBM-NEXT:    pushq %rbp
3614; X64-BMI1NOTBM-NEXT:    pushq %rbx
3615; X64-BMI1NOTBM-NEXT:    pushq %rax
3616; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3617; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
3618; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3619; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3620; X64-BMI1NOTBM-NEXT:    negb %dl
3621; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
3622; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3623; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3624; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
3625; X64-BMI1NOTBM-NEXT:    callq use32
3626; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
3627; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
3628; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3629; X64-BMI1NOTBM-NEXT:    popq %rbx
3630; X64-BMI1NOTBM-NEXT:    popq %rbp
3631; X64-BMI1NOTBM-NEXT:    retq
3632;
3633; X64-BMI1BMI2-LABEL: bextr32_c4_commutative:
3634; X64-BMI1BMI2:       # %bb.0:
3635; X64-BMI1BMI2-NEXT:    pushq %rbp
3636; X64-BMI1BMI2-NEXT:    pushq %rbx
3637; X64-BMI1BMI2-NEXT:    pushq %rax
3638; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3639; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
3640; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3641; X64-BMI1BMI2-NEXT:    negb %al
3642; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3643; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3644; X64-BMI1BMI2-NEXT:    callq use32
3645; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3646; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3647; X64-BMI1BMI2-NEXT:    popq %rbx
3648; X64-BMI1BMI2-NEXT:    popq %rbp
3649; X64-BMI1BMI2-NEXT:    retq
3650  %shifted = lshr i32 %val, %numskipbits
3651  %numhighbits = sub i32 32, %numlowbits
3652  %mask = lshr i32 -1, %numhighbits
3653  call void @use32(i32 %mask)
3654  %masked = and i32 %shifted, %mask ; swapped order
3655  ret i32 %masked
3656}
3657
3658define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
3659; X86-NOBMI-LABEL: bextr32_c5_skipextrauses:
3660; X86-NOBMI:       # %bb.0:
3661; X86-NOBMI-NEXT:    pushl %ebx
3662; X86-NOBMI-NEXT:    pushl %edi
3663; X86-NOBMI-NEXT:    pushl %esi
3664; X86-NOBMI-NEXT:    subl $16, %esp
3665; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3666; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
3667; X86-NOBMI-NEXT:    movl %ebx, %ecx
3668; X86-NOBMI-NEXT:    shrl %cl, %edi
3669; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3670; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3671; X86-NOBMI-NEXT:    movl $-1, %esi
3672; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3673; X86-NOBMI-NEXT:    shrl %cl, %esi
3674; X86-NOBMI-NEXT:    movl %esi, (%esp)
3675; X86-NOBMI-NEXT:    calll use32
3676; X86-NOBMI-NEXT:    andl %edi, %esi
3677; X86-NOBMI-NEXT:    movl %ebx, (%esp)
3678; X86-NOBMI-NEXT:    calll use32
3679; X86-NOBMI-NEXT:    movl %esi, %eax
3680; X86-NOBMI-NEXT:    addl $16, %esp
3681; X86-NOBMI-NEXT:    popl %esi
3682; X86-NOBMI-NEXT:    popl %edi
3683; X86-NOBMI-NEXT:    popl %ebx
3684; X86-NOBMI-NEXT:    retl
3685;
3686; X86-BMI1NOTBM-LABEL: bextr32_c5_skipextrauses:
3687; X86-BMI1NOTBM:       # %bb.0:
3688; X86-BMI1NOTBM-NEXT:    pushl %ebx
3689; X86-BMI1NOTBM-NEXT:    pushl %edi
3690; X86-BMI1NOTBM-NEXT:    pushl %esi
3691; X86-BMI1NOTBM-NEXT:    subl $16, %esp
3692; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3693; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
3694; X86-BMI1NOTBM-NEXT:    movl %ebx, %ecx
3695; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3696; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3697; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3698; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3699; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3700; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3701; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3702; X86-BMI1NOTBM-NEXT:    calll use32
3703; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3704; X86-BMI1NOTBM-NEXT:    movl %ebx, (%esp)
3705; X86-BMI1NOTBM-NEXT:    calll use32
3706; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3707; X86-BMI1NOTBM-NEXT:    addl $16, %esp
3708; X86-BMI1NOTBM-NEXT:    popl %esi
3709; X86-BMI1NOTBM-NEXT:    popl %edi
3710; X86-BMI1NOTBM-NEXT:    popl %ebx
3711; X86-BMI1NOTBM-NEXT:    retl
3712;
3713; X86-BMI1BMI2-LABEL: bextr32_c5_skipextrauses:
3714; X86-BMI1BMI2:       # %bb.0:
3715; X86-BMI1BMI2-NEXT:    pushl %ebx
3716; X86-BMI1BMI2-NEXT:    pushl %edi
3717; X86-BMI1BMI2-NEXT:    pushl %esi
3718; X86-BMI1BMI2-NEXT:    subl $16, %esp
3719; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3720; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
3721; X86-BMI1BMI2-NEXT:    shrxl %edi, {{[0-9]+}}(%esp), %esi
3722; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3723; X86-BMI1BMI2-NEXT:    negb %al
3724; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3725; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3726; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3727; X86-BMI1BMI2-NEXT:    calll use32
3728; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %esi
3729; X86-BMI1BMI2-NEXT:    movl %edi, (%esp)
3730; X86-BMI1BMI2-NEXT:    calll use32
3731; X86-BMI1BMI2-NEXT:    movl %esi, %eax
3732; X86-BMI1BMI2-NEXT:    addl $16, %esp
3733; X86-BMI1BMI2-NEXT:    popl %esi
3734; X86-BMI1BMI2-NEXT:    popl %edi
3735; X86-BMI1BMI2-NEXT:    popl %ebx
3736; X86-BMI1BMI2-NEXT:    retl
3737;
3738; X64-NOBMI-LABEL: bextr32_c5_skipextrauses:
3739; X64-NOBMI:       # %bb.0:
3740; X64-NOBMI-NEXT:    pushq %rbp
3741; X64-NOBMI-NEXT:    pushq %r14
3742; X64-NOBMI-NEXT:    pushq %rbx
3743; X64-NOBMI-NEXT:    movl %esi, %r14d
3744; X64-NOBMI-NEXT:    movl %edi, %ebp
3745; X64-NOBMI-NEXT:    movl %r14d, %ecx
3746; X64-NOBMI-NEXT:    shrl %cl, %ebp
3747; X64-NOBMI-NEXT:    negb %dl
3748; X64-NOBMI-NEXT:    movl $-1, %ebx
3749; X64-NOBMI-NEXT:    movl %edx, %ecx
3750; X64-NOBMI-NEXT:    shrl %cl, %ebx
3751; X64-NOBMI-NEXT:    movl %ebx, %edi
3752; X64-NOBMI-NEXT:    callq use32
3753; X64-NOBMI-NEXT:    andl %ebp, %ebx
3754; X64-NOBMI-NEXT:    movl %r14d, %edi
3755; X64-NOBMI-NEXT:    callq use32
3756; X64-NOBMI-NEXT:    movl %ebx, %eax
3757; X64-NOBMI-NEXT:    popq %rbx
3758; X64-NOBMI-NEXT:    popq %r14
3759; X64-NOBMI-NEXT:    popq %rbp
3760; X64-NOBMI-NEXT:    retq
3761;
3762; X64-BMI1NOTBM-LABEL: bextr32_c5_skipextrauses:
3763; X64-BMI1NOTBM:       # %bb.0:
3764; X64-BMI1NOTBM-NEXT:    pushq %rbp
3765; X64-BMI1NOTBM-NEXT:    pushq %r14
3766; X64-BMI1NOTBM-NEXT:    pushq %rbx
3767; X64-BMI1NOTBM-NEXT:    movl %esi, %r14d
3768; X64-BMI1NOTBM-NEXT:    movl %edi, %ebp
3769; X64-BMI1NOTBM-NEXT:    movl %r14d, %ecx
3770; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3771; X64-BMI1NOTBM-NEXT:    negb %dl
3772; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
3773; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3774; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3775; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
3776; X64-BMI1NOTBM-NEXT:    callq use32
3777; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
3778; X64-BMI1NOTBM-NEXT:    movl %r14d, %edi
3779; X64-BMI1NOTBM-NEXT:    callq use32
3780; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
3781; X64-BMI1NOTBM-NEXT:    popq %rbx
3782; X64-BMI1NOTBM-NEXT:    popq %r14
3783; X64-BMI1NOTBM-NEXT:    popq %rbp
3784; X64-BMI1NOTBM-NEXT:    retq
3785;
3786; X64-BMI1BMI2-LABEL: bextr32_c5_skipextrauses:
3787; X64-BMI1BMI2:       # %bb.0:
3788; X64-BMI1BMI2-NEXT:    pushq %rbp
3789; X64-BMI1BMI2-NEXT:    pushq %r14
3790; X64-BMI1BMI2-NEXT:    pushq %rbx
3791; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3792; X64-BMI1BMI2-NEXT:    movl %esi, %ebp
3793; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %r14d
3794; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3795; X64-BMI1BMI2-NEXT:    negb %al
3796; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3797; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3798; X64-BMI1BMI2-NEXT:    callq use32
3799; X64-BMI1BMI2-NEXT:    bzhil %ebx, %r14d, %ebx
3800; X64-BMI1BMI2-NEXT:    movl %ebp, %edi
3801; X64-BMI1BMI2-NEXT:    callq use32
3802; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3803; X64-BMI1BMI2-NEXT:    popq %rbx
3804; X64-BMI1BMI2-NEXT:    popq %r14
3805; X64-BMI1BMI2-NEXT:    popq %rbp
3806; X64-BMI1BMI2-NEXT:    retq
3807  %shifted = lshr i32 %val, %numskipbits
3808  %numhighbits = sub i32 32, %numlowbits
3809  %mask = lshr i32 -1, %numhighbits
3810  call void @use32(i32 %mask)
3811  %masked = and i32 %mask, %shifted
3812  call void @use32(i32 %numskipbits)
3813  ret i32 %masked
3814}
3815
3816; 64-bit
3817
3818define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
3819; X86-NOBMI-LABEL: bextr64_c0:
3820; X86-NOBMI:       # %bb.0:
3821; X86-NOBMI-NEXT:    pushl %ebp
3822; X86-NOBMI-NEXT:    pushl %ebx
3823; X86-NOBMI-NEXT:    pushl %edi
3824; X86-NOBMI-NEXT:    pushl %esi
3825; X86-NOBMI-NEXT:    subl $12, %esp
3826; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3827; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3828; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3829; X86-NOBMI-NEXT:    movl %eax, %edi
3830; X86-NOBMI-NEXT:    shrl %cl, %edi
3831; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
3832; X86-NOBMI-NEXT:    testb $32, %cl
3833; X86-NOBMI-NEXT:    je .LBB32_2
3834; X86-NOBMI-NEXT:  # %bb.1:
3835; X86-NOBMI-NEXT:    movl %edi, %esi
3836; X86-NOBMI-NEXT:    xorl %edi, %edi
3837; X86-NOBMI-NEXT:  .LBB32_2:
3838; X86-NOBMI-NEXT:    movb $64, %cl
3839; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3840; X86-NOBMI-NEXT:    movl $-1, %ebp
3841; X86-NOBMI-NEXT:    movl $-1, %ebx
3842; X86-NOBMI-NEXT:    shrl %cl, %ebx
3843; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
3844; X86-NOBMI-NEXT:    testb $32, %cl
3845; X86-NOBMI-NEXT:    je .LBB32_4
3846; X86-NOBMI-NEXT:  # %bb.3:
3847; X86-NOBMI-NEXT:    movl %ebx, %ebp
3848; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3849; X86-NOBMI-NEXT:  .LBB32_4:
3850; X86-NOBMI-NEXT:    subl $8, %esp
3851; X86-NOBMI-NEXT:    pushl %ebx
3852; X86-NOBMI-NEXT:    pushl %ebp
3853; X86-NOBMI-NEXT:    calll use64
3854; X86-NOBMI-NEXT:    addl $16, %esp
3855; X86-NOBMI-NEXT:    andl %ebp, %esi
3856; X86-NOBMI-NEXT:    andl %ebx, %edi
3857; X86-NOBMI-NEXT:    movl %esi, %eax
3858; X86-NOBMI-NEXT:    movl %edi, %edx
3859; X86-NOBMI-NEXT:    addl $12, %esp
3860; X86-NOBMI-NEXT:    popl %esi
3861; X86-NOBMI-NEXT:    popl %edi
3862; X86-NOBMI-NEXT:    popl %ebx
3863; X86-NOBMI-NEXT:    popl %ebp
3864; X86-NOBMI-NEXT:    retl
3865;
3866; X86-BMI1NOTBM-LABEL: bextr64_c0:
3867; X86-BMI1NOTBM:       # %bb.0:
3868; X86-BMI1NOTBM-NEXT:    pushl %ebp
3869; X86-BMI1NOTBM-NEXT:    pushl %ebx
3870; X86-BMI1NOTBM-NEXT:    pushl %edi
3871; X86-BMI1NOTBM-NEXT:    pushl %esi
3872; X86-BMI1NOTBM-NEXT:    subl $12, %esp
3873; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3874; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
3875; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3876; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
3877; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3878; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
3879; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3880; X86-BMI1NOTBM-NEXT:    je .LBB32_2
3881; X86-BMI1NOTBM-NEXT:  # %bb.1:
3882; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
3883; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
3884; X86-BMI1NOTBM-NEXT:  .LBB32_2:
3885; X86-BMI1NOTBM-NEXT:    movb $64, %cl
3886; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3887; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
3888; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
3889; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3890; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
3891; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3892; X86-BMI1NOTBM-NEXT:    je .LBB32_4
3893; X86-BMI1NOTBM-NEXT:  # %bb.3:
3894; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
3895; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3896; X86-BMI1NOTBM-NEXT:  .LBB32_4:
3897; X86-BMI1NOTBM-NEXT:    subl $8, %esp
3898; X86-BMI1NOTBM-NEXT:    pushl %ebx
3899; X86-BMI1NOTBM-NEXT:    pushl %ebp
3900; X86-BMI1NOTBM-NEXT:    calll use64
3901; X86-BMI1NOTBM-NEXT:    addl $16, %esp
3902; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
3903; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
3904; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3905; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
3906; X86-BMI1NOTBM-NEXT:    addl $12, %esp
3907; X86-BMI1NOTBM-NEXT:    popl %esi
3908; X86-BMI1NOTBM-NEXT:    popl %edi
3909; X86-BMI1NOTBM-NEXT:    popl %ebx
3910; X86-BMI1NOTBM-NEXT:    popl %ebp
3911; X86-BMI1NOTBM-NEXT:    retl
3912;
3913; X86-BMI1BMI2-LABEL: bextr64_c0:
3914; X86-BMI1BMI2:       # %bb.0:
3915; X86-BMI1BMI2-NEXT:    pushl %ebp
3916; X86-BMI1BMI2-NEXT:    pushl %ebx
3917; X86-BMI1BMI2-NEXT:    pushl %edi
3918; X86-BMI1BMI2-NEXT:    pushl %esi
3919; X86-BMI1BMI2-NEXT:    subl $12, %esp
3920; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3921; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3922; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3923; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
3924; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
3925; X86-BMI1BMI2-NEXT:    testb $32, %cl
3926; X86-BMI1BMI2-NEXT:    je .LBB32_2
3927; X86-BMI1BMI2-NEXT:  # %bb.1:
3928; X86-BMI1BMI2-NEXT:    movl %edi, %esi
3929; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
3930; X86-BMI1BMI2-NEXT:  .LBB32_2:
3931; X86-BMI1BMI2-NEXT:    movb $64, %cl
3932; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
3933; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
3934; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
3935; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
3936; X86-BMI1BMI2-NEXT:    testb $32, %cl
3937; X86-BMI1BMI2-NEXT:    je .LBB32_4
3938; X86-BMI1BMI2-NEXT:  # %bb.3:
3939; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
3940; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
3941; X86-BMI1BMI2-NEXT:  .LBB32_4:
3942; X86-BMI1BMI2-NEXT:    subl $8, %esp
3943; X86-BMI1BMI2-NEXT:    pushl %ebp
3944; X86-BMI1BMI2-NEXT:    pushl %ebx
3945; X86-BMI1BMI2-NEXT:    calll use64
3946; X86-BMI1BMI2-NEXT:    addl $16, %esp
3947; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
3948; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
3949; X86-BMI1BMI2-NEXT:    movl %esi, %eax
3950; X86-BMI1BMI2-NEXT:    movl %edi, %edx
3951; X86-BMI1BMI2-NEXT:    addl $12, %esp
3952; X86-BMI1BMI2-NEXT:    popl %esi
3953; X86-BMI1BMI2-NEXT:    popl %edi
3954; X86-BMI1BMI2-NEXT:    popl %ebx
3955; X86-BMI1BMI2-NEXT:    popl %ebp
3956; X86-BMI1BMI2-NEXT:    retl
3957;
3958; X64-NOBMI-LABEL: bextr64_c0:
3959; X64-NOBMI:       # %bb.0:
3960; X64-NOBMI-NEXT:    pushq %r14
3961; X64-NOBMI-NEXT:    pushq %rbx
3962; X64-NOBMI-NEXT:    pushq %rax
3963; X64-NOBMI-NEXT:    movq %rsi, %rcx
3964; X64-NOBMI-NEXT:    movq %rdi, %r14
3965; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3966; X64-NOBMI-NEXT:    shrq %cl, %r14
3967; X64-NOBMI-NEXT:    negb %dl
3968; X64-NOBMI-NEXT:    movq $-1, %rbx
3969; X64-NOBMI-NEXT:    movl %edx, %ecx
3970; X64-NOBMI-NEXT:    shrq %cl, %rbx
3971; X64-NOBMI-NEXT:    movq %rbx, %rdi
3972; X64-NOBMI-NEXT:    callq use64
3973; X64-NOBMI-NEXT:    andq %r14, %rbx
3974; X64-NOBMI-NEXT:    movq %rbx, %rax
3975; X64-NOBMI-NEXT:    addq $8, %rsp
3976; X64-NOBMI-NEXT:    popq %rbx
3977; X64-NOBMI-NEXT:    popq %r14
3978; X64-NOBMI-NEXT:    retq
3979;
3980; X64-BMI1NOTBM-LABEL: bextr64_c0:
3981; X64-BMI1NOTBM:       # %bb.0:
3982; X64-BMI1NOTBM-NEXT:    pushq %r14
3983; X64-BMI1NOTBM-NEXT:    pushq %rbx
3984; X64-BMI1NOTBM-NEXT:    pushq %rax
3985; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
3986; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
3987; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
3988; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
3989; X64-BMI1NOTBM-NEXT:    negb %dl
3990; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
3991; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3992; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
3993; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
3994; X64-BMI1NOTBM-NEXT:    callq use64
3995; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
3996; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
3997; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3998; X64-BMI1NOTBM-NEXT:    popq %rbx
3999; X64-BMI1NOTBM-NEXT:    popq %r14
4000; X64-BMI1NOTBM-NEXT:    retq
4001;
4002; X64-BMI1BMI2-LABEL: bextr64_c0:
4003; X64-BMI1BMI2:       # %bb.0:
4004; X64-BMI1BMI2-NEXT:    pushq %r14
4005; X64-BMI1BMI2-NEXT:    pushq %rbx
4006; X64-BMI1BMI2-NEXT:    pushq %rax
4007; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
4008; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
4009; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4010; X64-BMI1BMI2-NEXT:    negb %al
4011; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4012; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4013; X64-BMI1BMI2-NEXT:    callq use64
4014; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4015; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4016; X64-BMI1BMI2-NEXT:    popq %rbx
4017; X64-BMI1BMI2-NEXT:    popq %r14
4018; X64-BMI1BMI2-NEXT:    retq
4019  %shifted = lshr i64 %val, %numskipbits
4020  %numhighbits = sub i64 64, %numlowbits
4021  %mask = lshr i64 -1, %numhighbits
4022  call void @use64(i64 %mask)
4023  %masked = and i64 %mask, %shifted
4024  ret i64 %masked
4025}
4026
4027define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
4028; X86-NOBMI-LABEL: bextr64_c1_indexzext:
4029; X86-NOBMI:       # %bb.0:
4030; X86-NOBMI-NEXT:    pushl %ebp
4031; X86-NOBMI-NEXT:    pushl %ebx
4032; X86-NOBMI-NEXT:    pushl %edi
4033; X86-NOBMI-NEXT:    pushl %esi
4034; X86-NOBMI-NEXT:    subl $12, %esp
4035; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4036; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4037; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4038; X86-NOBMI-NEXT:    movl %eax, %edi
4039; X86-NOBMI-NEXT:    shrl %cl, %edi
4040; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4041; X86-NOBMI-NEXT:    testb $32, %cl
4042; X86-NOBMI-NEXT:    je .LBB33_2
4043; X86-NOBMI-NEXT:  # %bb.1:
4044; X86-NOBMI-NEXT:    movl %edi, %esi
4045; X86-NOBMI-NEXT:    xorl %edi, %edi
4046; X86-NOBMI-NEXT:  .LBB33_2:
4047; X86-NOBMI-NEXT:    movb $64, %cl
4048; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4049; X86-NOBMI-NEXT:    movl $-1, %ebp
4050; X86-NOBMI-NEXT:    movl $-1, %ebx
4051; X86-NOBMI-NEXT:    shrl %cl, %ebx
4052; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4053; X86-NOBMI-NEXT:    testb $32, %cl
4054; X86-NOBMI-NEXT:    je .LBB33_4
4055; X86-NOBMI-NEXT:  # %bb.3:
4056; X86-NOBMI-NEXT:    movl %ebx, %ebp
4057; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4058; X86-NOBMI-NEXT:  .LBB33_4:
4059; X86-NOBMI-NEXT:    subl $8, %esp
4060; X86-NOBMI-NEXT:    pushl %ebx
4061; X86-NOBMI-NEXT:    pushl %ebp
4062; X86-NOBMI-NEXT:    calll use64
4063; X86-NOBMI-NEXT:    addl $16, %esp
4064; X86-NOBMI-NEXT:    andl %ebp, %esi
4065; X86-NOBMI-NEXT:    andl %ebx, %edi
4066; X86-NOBMI-NEXT:    movl %esi, %eax
4067; X86-NOBMI-NEXT:    movl %edi, %edx
4068; X86-NOBMI-NEXT:    addl $12, %esp
4069; X86-NOBMI-NEXT:    popl %esi
4070; X86-NOBMI-NEXT:    popl %edi
4071; X86-NOBMI-NEXT:    popl %ebx
4072; X86-NOBMI-NEXT:    popl %ebp
4073; X86-NOBMI-NEXT:    retl
4074;
4075; X86-BMI1NOTBM-LABEL: bextr64_c1_indexzext:
4076; X86-BMI1NOTBM:       # %bb.0:
4077; X86-BMI1NOTBM-NEXT:    pushl %ebp
4078; X86-BMI1NOTBM-NEXT:    pushl %ebx
4079; X86-BMI1NOTBM-NEXT:    pushl %edi
4080; X86-BMI1NOTBM-NEXT:    pushl %esi
4081; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4082; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4083; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
4084; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4085; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4086; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4087; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4088; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4089; X86-BMI1NOTBM-NEXT:    je .LBB33_2
4090; X86-BMI1NOTBM-NEXT:  # %bb.1:
4091; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4092; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4093; X86-BMI1NOTBM-NEXT:  .LBB33_2:
4094; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4095; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4096; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4097; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4098; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4099; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4100; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4101; X86-BMI1NOTBM-NEXT:    je .LBB33_4
4102; X86-BMI1NOTBM-NEXT:  # %bb.3:
4103; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4104; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4105; X86-BMI1NOTBM-NEXT:  .LBB33_4:
4106; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4107; X86-BMI1NOTBM-NEXT:    pushl %ebx
4108; X86-BMI1NOTBM-NEXT:    pushl %ebp
4109; X86-BMI1NOTBM-NEXT:    calll use64
4110; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4111; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4112; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4113; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4114; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4115; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4116; X86-BMI1NOTBM-NEXT:    popl %esi
4117; X86-BMI1NOTBM-NEXT:    popl %edi
4118; X86-BMI1NOTBM-NEXT:    popl %ebx
4119; X86-BMI1NOTBM-NEXT:    popl %ebp
4120; X86-BMI1NOTBM-NEXT:    retl
4121;
4122; X86-BMI1BMI2-LABEL: bextr64_c1_indexzext:
4123; X86-BMI1BMI2:       # %bb.0:
4124; X86-BMI1BMI2-NEXT:    pushl %ebp
4125; X86-BMI1BMI2-NEXT:    pushl %ebx
4126; X86-BMI1BMI2-NEXT:    pushl %edi
4127; X86-BMI1BMI2-NEXT:    pushl %esi
4128; X86-BMI1BMI2-NEXT:    subl $12, %esp
4129; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4130; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4131; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4132; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4133; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4134; X86-BMI1BMI2-NEXT:    testb $32, %cl
4135; X86-BMI1BMI2-NEXT:    je .LBB33_2
4136; X86-BMI1BMI2-NEXT:  # %bb.1:
4137; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4138; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4139; X86-BMI1BMI2-NEXT:  .LBB33_2:
4140; X86-BMI1BMI2-NEXT:    movb $64, %cl
4141; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4142; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4143; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4144; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4145; X86-BMI1BMI2-NEXT:    testb $32, %cl
4146; X86-BMI1BMI2-NEXT:    je .LBB33_4
4147; X86-BMI1BMI2-NEXT:  # %bb.3:
4148; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4149; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4150; X86-BMI1BMI2-NEXT:  .LBB33_4:
4151; X86-BMI1BMI2-NEXT:    subl $8, %esp
4152; X86-BMI1BMI2-NEXT:    pushl %ebp
4153; X86-BMI1BMI2-NEXT:    pushl %ebx
4154; X86-BMI1BMI2-NEXT:    calll use64
4155; X86-BMI1BMI2-NEXT:    addl $16, %esp
4156; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4157; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4158; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4159; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4160; X86-BMI1BMI2-NEXT:    addl $12, %esp
4161; X86-BMI1BMI2-NEXT:    popl %esi
4162; X86-BMI1BMI2-NEXT:    popl %edi
4163; X86-BMI1BMI2-NEXT:    popl %ebx
4164; X86-BMI1BMI2-NEXT:    popl %ebp
4165; X86-BMI1BMI2-NEXT:    retl
4166;
4167; X64-NOBMI-LABEL: bextr64_c1_indexzext:
4168; X64-NOBMI:       # %bb.0:
4169; X64-NOBMI-NEXT:    pushq %r14
4170; X64-NOBMI-NEXT:    pushq %rbx
4171; X64-NOBMI-NEXT:    pushq %rax
4172; X64-NOBMI-NEXT:    movl %esi, %ecx
4173; X64-NOBMI-NEXT:    movq %rdi, %r14
4174; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4175; X64-NOBMI-NEXT:    shrq %cl, %r14
4176; X64-NOBMI-NEXT:    negb %dl
4177; X64-NOBMI-NEXT:    movq $-1, %rbx
4178; X64-NOBMI-NEXT:    movl %edx, %ecx
4179; X64-NOBMI-NEXT:    shrq %cl, %rbx
4180; X64-NOBMI-NEXT:    movq %rbx, %rdi
4181; X64-NOBMI-NEXT:    callq use64
4182; X64-NOBMI-NEXT:    andq %r14, %rbx
4183; X64-NOBMI-NEXT:    movq %rbx, %rax
4184; X64-NOBMI-NEXT:    addq $8, %rsp
4185; X64-NOBMI-NEXT:    popq %rbx
4186; X64-NOBMI-NEXT:    popq %r14
4187; X64-NOBMI-NEXT:    retq
4188;
4189; X64-BMI1NOTBM-LABEL: bextr64_c1_indexzext:
4190; X64-BMI1NOTBM:       # %bb.0:
4191; X64-BMI1NOTBM-NEXT:    pushq %r14
4192; X64-BMI1NOTBM-NEXT:    pushq %rbx
4193; X64-BMI1NOTBM-NEXT:    pushq %rax
4194; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4195; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
4196; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4197; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4198; X64-BMI1NOTBM-NEXT:    negb %dl
4199; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4200; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4201; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4202; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4203; X64-BMI1NOTBM-NEXT:    callq use64
4204; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4205; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4206; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4207; X64-BMI1NOTBM-NEXT:    popq %rbx
4208; X64-BMI1NOTBM-NEXT:    popq %r14
4209; X64-BMI1NOTBM-NEXT:    retq
4210;
4211; X64-BMI1BMI2-LABEL: bextr64_c1_indexzext:
4212; X64-BMI1BMI2:       # %bb.0:
4213; X64-BMI1BMI2-NEXT:    pushq %r14
4214; X64-BMI1BMI2-NEXT:    pushq %rbx
4215; X64-BMI1BMI2-NEXT:    pushq %rax
4216; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4217; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
4218; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
4219; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4220; X64-BMI1BMI2-NEXT:    negb %al
4221; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4222; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4223; X64-BMI1BMI2-NEXT:    callq use64
4224; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4225; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4226; X64-BMI1BMI2-NEXT:    popq %rbx
4227; X64-BMI1BMI2-NEXT:    popq %r14
4228; X64-BMI1BMI2-NEXT:    retq
4229  %skip = zext i8 %numskipbits to i64
4230  %shifted = lshr i64 %val, %skip
4231  %numhighbits = sub i8 64, %numlowbits
4232  %sh_prom = zext i8 %numhighbits to i64
4233  %mask = lshr i64 -1, %sh_prom
4234  call void @use64(i64 %mask)
4235  %masked = and i64 %mask, %shifted
4236  ret i64 %masked
4237}
4238
4239define i64 @bextr64_c2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
4240; X86-NOBMI-LABEL: bextr64_c2_load:
4241; X86-NOBMI:       # %bb.0:
4242; X86-NOBMI-NEXT:    pushl %ebp
4243; X86-NOBMI-NEXT:    pushl %ebx
4244; X86-NOBMI-NEXT:    pushl %edi
4245; X86-NOBMI-NEXT:    pushl %esi
4246; X86-NOBMI-NEXT:    subl $12, %esp
4247; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4248; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4249; X86-NOBMI-NEXT:    movl (%eax), %esi
4250; X86-NOBMI-NEXT:    movl 4(%eax), %eax
4251; X86-NOBMI-NEXT:    movl %eax, %edi
4252; X86-NOBMI-NEXT:    shrl %cl, %edi
4253; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4254; X86-NOBMI-NEXT:    testb $32, %cl
4255; X86-NOBMI-NEXT:    je .LBB34_2
4256; X86-NOBMI-NEXT:  # %bb.1:
4257; X86-NOBMI-NEXT:    movl %edi, %esi
4258; X86-NOBMI-NEXT:    xorl %edi, %edi
4259; X86-NOBMI-NEXT:  .LBB34_2:
4260; X86-NOBMI-NEXT:    movb $64, %cl
4261; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4262; X86-NOBMI-NEXT:    movl $-1, %ebp
4263; X86-NOBMI-NEXT:    movl $-1, %ebx
4264; X86-NOBMI-NEXT:    shrl %cl, %ebx
4265; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4266; X86-NOBMI-NEXT:    testb $32, %cl
4267; X86-NOBMI-NEXT:    je .LBB34_4
4268; X86-NOBMI-NEXT:  # %bb.3:
4269; X86-NOBMI-NEXT:    movl %ebx, %ebp
4270; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4271; X86-NOBMI-NEXT:  .LBB34_4:
4272; X86-NOBMI-NEXT:    subl $8, %esp
4273; X86-NOBMI-NEXT:    pushl %ebx
4274; X86-NOBMI-NEXT:    pushl %ebp
4275; X86-NOBMI-NEXT:    calll use64
4276; X86-NOBMI-NEXT:    addl $16, %esp
4277; X86-NOBMI-NEXT:    andl %ebp, %esi
4278; X86-NOBMI-NEXT:    andl %ebx, %edi
4279; X86-NOBMI-NEXT:    movl %esi, %eax
4280; X86-NOBMI-NEXT:    movl %edi, %edx
4281; X86-NOBMI-NEXT:    addl $12, %esp
4282; X86-NOBMI-NEXT:    popl %esi
4283; X86-NOBMI-NEXT:    popl %edi
4284; X86-NOBMI-NEXT:    popl %ebx
4285; X86-NOBMI-NEXT:    popl %ebp
4286; X86-NOBMI-NEXT:    retl
4287;
4288; X86-BMI1NOTBM-LABEL: bextr64_c2_load:
4289; X86-BMI1NOTBM:       # %bb.0:
4290; X86-BMI1NOTBM-NEXT:    pushl %ebp
4291; X86-BMI1NOTBM-NEXT:    pushl %ebx
4292; X86-BMI1NOTBM-NEXT:    pushl %edi
4293; X86-BMI1NOTBM-NEXT:    pushl %esi
4294; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4295; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4296; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4297; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
4298; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
4299; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4300; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4301; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4302; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4303; X86-BMI1NOTBM-NEXT:    je .LBB34_2
4304; X86-BMI1NOTBM-NEXT:  # %bb.1:
4305; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4306; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4307; X86-BMI1NOTBM-NEXT:  .LBB34_2:
4308; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4309; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4310; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4311; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4312; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4313; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4314; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4315; X86-BMI1NOTBM-NEXT:    je .LBB34_4
4316; X86-BMI1NOTBM-NEXT:  # %bb.3:
4317; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4318; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4319; X86-BMI1NOTBM-NEXT:  .LBB34_4:
4320; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4321; X86-BMI1NOTBM-NEXT:    pushl %ebx
4322; X86-BMI1NOTBM-NEXT:    pushl %ebp
4323; X86-BMI1NOTBM-NEXT:    calll use64
4324; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4325; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4326; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4327; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4328; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4329; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4330; X86-BMI1NOTBM-NEXT:    popl %esi
4331; X86-BMI1NOTBM-NEXT:    popl %edi
4332; X86-BMI1NOTBM-NEXT:    popl %ebx
4333; X86-BMI1NOTBM-NEXT:    popl %ebp
4334; X86-BMI1NOTBM-NEXT:    retl
4335;
4336; X86-BMI1BMI2-LABEL: bextr64_c2_load:
4337; X86-BMI1BMI2:       # %bb.0:
4338; X86-BMI1BMI2-NEXT:    pushl %ebp
4339; X86-BMI1BMI2-NEXT:    pushl %ebx
4340; X86-BMI1BMI2-NEXT:    pushl %edi
4341; X86-BMI1BMI2-NEXT:    pushl %esi
4342; X86-BMI1BMI2-NEXT:    subl $12, %esp
4343; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4344; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4345; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
4346; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
4347; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4348; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4349; X86-BMI1BMI2-NEXT:    testb $32, %cl
4350; X86-BMI1BMI2-NEXT:    je .LBB34_2
4351; X86-BMI1BMI2-NEXT:  # %bb.1:
4352; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4353; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4354; X86-BMI1BMI2-NEXT:  .LBB34_2:
4355; X86-BMI1BMI2-NEXT:    movb $64, %cl
4356; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4357; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4358; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4359; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4360; X86-BMI1BMI2-NEXT:    testb $32, %cl
4361; X86-BMI1BMI2-NEXT:    je .LBB34_4
4362; X86-BMI1BMI2-NEXT:  # %bb.3:
4363; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4364; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4365; X86-BMI1BMI2-NEXT:  .LBB34_4:
4366; X86-BMI1BMI2-NEXT:    subl $8, %esp
4367; X86-BMI1BMI2-NEXT:    pushl %ebp
4368; X86-BMI1BMI2-NEXT:    pushl %ebx
4369; X86-BMI1BMI2-NEXT:    calll use64
4370; X86-BMI1BMI2-NEXT:    addl $16, %esp
4371; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4372; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4373; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4374; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4375; X86-BMI1BMI2-NEXT:    addl $12, %esp
4376; X86-BMI1BMI2-NEXT:    popl %esi
4377; X86-BMI1BMI2-NEXT:    popl %edi
4378; X86-BMI1BMI2-NEXT:    popl %ebx
4379; X86-BMI1BMI2-NEXT:    popl %ebp
4380; X86-BMI1BMI2-NEXT:    retl
4381;
4382; X64-NOBMI-LABEL: bextr64_c2_load:
4383; X64-NOBMI:       # %bb.0:
4384; X64-NOBMI-NEXT:    pushq %r14
4385; X64-NOBMI-NEXT:    pushq %rbx
4386; X64-NOBMI-NEXT:    pushq %rax
4387; X64-NOBMI-NEXT:    movq %rsi, %rcx
4388; X64-NOBMI-NEXT:    movq (%rdi), %r14
4389; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
4390; X64-NOBMI-NEXT:    shrq %cl, %r14
4391; X64-NOBMI-NEXT:    negb %dl
4392; X64-NOBMI-NEXT:    movq $-1, %rbx
4393; X64-NOBMI-NEXT:    movl %edx, %ecx
4394; X64-NOBMI-NEXT:    shrq %cl, %rbx
4395; X64-NOBMI-NEXT:    movq %rbx, %rdi
4396; X64-NOBMI-NEXT:    callq use64
4397; X64-NOBMI-NEXT:    andq %r14, %rbx
4398; X64-NOBMI-NEXT:    movq %rbx, %rax
4399; X64-NOBMI-NEXT:    addq $8, %rsp
4400; X64-NOBMI-NEXT:    popq %rbx
4401; X64-NOBMI-NEXT:    popq %r14
4402; X64-NOBMI-NEXT:    retq
4403;
4404; X64-BMI1NOTBM-LABEL: bextr64_c2_load:
4405; X64-BMI1NOTBM:       # %bb.0:
4406; X64-BMI1NOTBM-NEXT:    pushq %r14
4407; X64-BMI1NOTBM-NEXT:    pushq %rbx
4408; X64-BMI1NOTBM-NEXT:    pushq %rax
4409; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
4410; X64-BMI1NOTBM-NEXT:    movq (%rdi), %r14
4411; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
4412; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4413; X64-BMI1NOTBM-NEXT:    negb %dl
4414; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4415; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4416; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4417; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4418; X64-BMI1NOTBM-NEXT:    callq use64
4419; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4420; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4421; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4422; X64-BMI1NOTBM-NEXT:    popq %rbx
4423; X64-BMI1NOTBM-NEXT:    popq %r14
4424; X64-BMI1NOTBM-NEXT:    retq
4425;
4426; X64-BMI1BMI2-LABEL: bextr64_c2_load:
4427; X64-BMI1BMI2:       # %bb.0:
4428; X64-BMI1BMI2-NEXT:    pushq %r14
4429; X64-BMI1BMI2-NEXT:    pushq %rbx
4430; X64-BMI1BMI2-NEXT:    pushq %rax
4431; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
4432; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
4433; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4434; X64-BMI1BMI2-NEXT:    negb %al
4435; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4436; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4437; X64-BMI1BMI2-NEXT:    callq use64
4438; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4439; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4440; X64-BMI1BMI2-NEXT:    popq %rbx
4441; X64-BMI1BMI2-NEXT:    popq %r14
4442; X64-BMI1BMI2-NEXT:    retq
4443  %val = load i64, i64* %w
4444  %shifted = lshr i64 %val, %numskipbits
4445  %numhighbits = sub i64 64, %numlowbits
4446  %mask = lshr i64 -1, %numhighbits
4447  call void @use64(i64 %mask)
4448  %masked = and i64 %mask, %shifted
4449  ret i64 %masked
4450}
4451
4452define i64 @bextr64_c3_load_indexzext(i64* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
4453; X86-NOBMI-LABEL: bextr64_c3_load_indexzext:
4454; X86-NOBMI:       # %bb.0:
4455; X86-NOBMI-NEXT:    pushl %ebp
4456; X86-NOBMI-NEXT:    pushl %ebx
4457; X86-NOBMI-NEXT:    pushl %edi
4458; X86-NOBMI-NEXT:    pushl %esi
4459; X86-NOBMI-NEXT:    subl $12, %esp
4460; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4461; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4462; X86-NOBMI-NEXT:    movl (%eax), %esi
4463; X86-NOBMI-NEXT:    movl 4(%eax), %eax
4464; X86-NOBMI-NEXT:    movl %eax, %edi
4465; X86-NOBMI-NEXT:    shrl %cl, %edi
4466; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4467; X86-NOBMI-NEXT:    testb $32, %cl
4468; X86-NOBMI-NEXT:    je .LBB35_2
4469; X86-NOBMI-NEXT:  # %bb.1:
4470; X86-NOBMI-NEXT:    movl %edi, %esi
4471; X86-NOBMI-NEXT:    xorl %edi, %edi
4472; X86-NOBMI-NEXT:  .LBB35_2:
4473; X86-NOBMI-NEXT:    movb $64, %cl
4474; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4475; X86-NOBMI-NEXT:    movl $-1, %ebp
4476; X86-NOBMI-NEXT:    movl $-1, %ebx
4477; X86-NOBMI-NEXT:    shrl %cl, %ebx
4478; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4479; X86-NOBMI-NEXT:    testb $32, %cl
4480; X86-NOBMI-NEXT:    je .LBB35_4
4481; X86-NOBMI-NEXT:  # %bb.3:
4482; X86-NOBMI-NEXT:    movl %ebx, %ebp
4483; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4484; X86-NOBMI-NEXT:  .LBB35_4:
4485; X86-NOBMI-NEXT:    subl $8, %esp
4486; X86-NOBMI-NEXT:    pushl %ebx
4487; X86-NOBMI-NEXT:    pushl %ebp
4488; X86-NOBMI-NEXT:    calll use64
4489; X86-NOBMI-NEXT:    addl $16, %esp
4490; X86-NOBMI-NEXT:    andl %ebp, %esi
4491; X86-NOBMI-NEXT:    andl %ebx, %edi
4492; X86-NOBMI-NEXT:    movl %esi, %eax
4493; X86-NOBMI-NEXT:    movl %edi, %edx
4494; X86-NOBMI-NEXT:    addl $12, %esp
4495; X86-NOBMI-NEXT:    popl %esi
4496; X86-NOBMI-NEXT:    popl %edi
4497; X86-NOBMI-NEXT:    popl %ebx
4498; X86-NOBMI-NEXT:    popl %ebp
4499; X86-NOBMI-NEXT:    retl
4500;
4501; X86-BMI1NOTBM-LABEL: bextr64_c3_load_indexzext:
4502; X86-BMI1NOTBM:       # %bb.0:
4503; X86-BMI1NOTBM-NEXT:    pushl %ebp
4504; X86-BMI1NOTBM-NEXT:    pushl %ebx
4505; X86-BMI1NOTBM-NEXT:    pushl %edi
4506; X86-BMI1NOTBM-NEXT:    pushl %esi
4507; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4508; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4509; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4510; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
4511; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
4512; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4513; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4514; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4515; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4516; X86-BMI1NOTBM-NEXT:    je .LBB35_2
4517; X86-BMI1NOTBM-NEXT:  # %bb.1:
4518; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4519; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4520; X86-BMI1NOTBM-NEXT:  .LBB35_2:
4521; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4522; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4523; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4524; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4525; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4526; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4527; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4528; X86-BMI1NOTBM-NEXT:    je .LBB35_4
4529; X86-BMI1NOTBM-NEXT:  # %bb.3:
4530; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4531; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4532; X86-BMI1NOTBM-NEXT:  .LBB35_4:
4533; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4534; X86-BMI1NOTBM-NEXT:    pushl %ebx
4535; X86-BMI1NOTBM-NEXT:    pushl %ebp
4536; X86-BMI1NOTBM-NEXT:    calll use64
4537; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4538; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4539; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4540; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4541; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4542; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4543; X86-BMI1NOTBM-NEXT:    popl %esi
4544; X86-BMI1NOTBM-NEXT:    popl %edi
4545; X86-BMI1NOTBM-NEXT:    popl %ebx
4546; X86-BMI1NOTBM-NEXT:    popl %ebp
4547; X86-BMI1NOTBM-NEXT:    retl
4548;
4549; X86-BMI1BMI2-LABEL: bextr64_c3_load_indexzext:
4550; X86-BMI1BMI2:       # %bb.0:
4551; X86-BMI1BMI2-NEXT:    pushl %ebp
4552; X86-BMI1BMI2-NEXT:    pushl %ebx
4553; X86-BMI1BMI2-NEXT:    pushl %edi
4554; X86-BMI1BMI2-NEXT:    pushl %esi
4555; X86-BMI1BMI2-NEXT:    subl $12, %esp
4556; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4557; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4558; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
4559; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
4560; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4561; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4562; X86-BMI1BMI2-NEXT:    testb $32, %cl
4563; X86-BMI1BMI2-NEXT:    je .LBB35_2
4564; X86-BMI1BMI2-NEXT:  # %bb.1:
4565; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4566; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4567; X86-BMI1BMI2-NEXT:  .LBB35_2:
4568; X86-BMI1BMI2-NEXT:    movb $64, %cl
4569; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4570; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4571; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4572; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4573; X86-BMI1BMI2-NEXT:    testb $32, %cl
4574; X86-BMI1BMI2-NEXT:    je .LBB35_4
4575; X86-BMI1BMI2-NEXT:  # %bb.3:
4576; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4577; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4578; X86-BMI1BMI2-NEXT:  .LBB35_4:
4579; X86-BMI1BMI2-NEXT:    subl $8, %esp
4580; X86-BMI1BMI2-NEXT:    pushl %ebp
4581; X86-BMI1BMI2-NEXT:    pushl %ebx
4582; X86-BMI1BMI2-NEXT:    calll use64
4583; X86-BMI1BMI2-NEXT:    addl $16, %esp
4584; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4585; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4586; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4587; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4588; X86-BMI1BMI2-NEXT:    addl $12, %esp
4589; X86-BMI1BMI2-NEXT:    popl %esi
4590; X86-BMI1BMI2-NEXT:    popl %edi
4591; X86-BMI1BMI2-NEXT:    popl %ebx
4592; X86-BMI1BMI2-NEXT:    popl %ebp
4593; X86-BMI1BMI2-NEXT:    retl
4594;
4595; X64-NOBMI-LABEL: bextr64_c3_load_indexzext:
4596; X64-NOBMI:       # %bb.0:
4597; X64-NOBMI-NEXT:    pushq %r14
4598; X64-NOBMI-NEXT:    pushq %rbx
4599; X64-NOBMI-NEXT:    pushq %rax
4600; X64-NOBMI-NEXT:    movl %esi, %ecx
4601; X64-NOBMI-NEXT:    movq (%rdi), %r14
4602; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4603; X64-NOBMI-NEXT:    shrq %cl, %r14
4604; X64-NOBMI-NEXT:    negb %dl
4605; X64-NOBMI-NEXT:    movq $-1, %rbx
4606; X64-NOBMI-NEXT:    movl %edx, %ecx
4607; X64-NOBMI-NEXT:    shrq %cl, %rbx
4608; X64-NOBMI-NEXT:    movq %rbx, %rdi
4609; X64-NOBMI-NEXT:    callq use64
4610; X64-NOBMI-NEXT:    andq %r14, %rbx
4611; X64-NOBMI-NEXT:    movq %rbx, %rax
4612; X64-NOBMI-NEXT:    addq $8, %rsp
4613; X64-NOBMI-NEXT:    popq %rbx
4614; X64-NOBMI-NEXT:    popq %r14
4615; X64-NOBMI-NEXT:    retq
4616;
4617; X64-BMI1NOTBM-LABEL: bextr64_c3_load_indexzext:
4618; X64-BMI1NOTBM:       # %bb.0:
4619; X64-BMI1NOTBM-NEXT:    pushq %r14
4620; X64-BMI1NOTBM-NEXT:    pushq %rbx
4621; X64-BMI1NOTBM-NEXT:    pushq %rax
4622; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4623; X64-BMI1NOTBM-NEXT:    movq (%rdi), %r14
4624; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4625; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4626; X64-BMI1NOTBM-NEXT:    negb %dl
4627; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4628; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4629; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4630; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4631; X64-BMI1NOTBM-NEXT:    callq use64
4632; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4633; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4634; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4635; X64-BMI1NOTBM-NEXT:    popq %rbx
4636; X64-BMI1NOTBM-NEXT:    popq %r14
4637; X64-BMI1NOTBM-NEXT:    retq
4638;
4639; X64-BMI1BMI2-LABEL: bextr64_c3_load_indexzext:
4640; X64-BMI1BMI2:       # %bb.0:
4641; X64-BMI1BMI2-NEXT:    pushq %r14
4642; X64-BMI1BMI2-NEXT:    pushq %rbx
4643; X64-BMI1BMI2-NEXT:    pushq %rax
4644; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4645; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
4646; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
4647; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4648; X64-BMI1BMI2-NEXT:    negb %al
4649; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4650; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4651; X64-BMI1BMI2-NEXT:    callq use64
4652; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4653; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4654; X64-BMI1BMI2-NEXT:    popq %rbx
4655; X64-BMI1BMI2-NEXT:    popq %r14
4656; X64-BMI1BMI2-NEXT:    retq
4657  %val = load i64, i64* %w
4658  %skip = zext i8 %numskipbits to i64
4659  %shifted = lshr i64 %val, %skip
4660  %numhighbits = sub i8 64, %numlowbits
4661  %sh_prom = zext i8 %numhighbits to i64
4662  %mask = lshr i64 -1, %sh_prom
4663  call void @use64(i64 %mask)
4664  %masked = and i64 %mask, %shifted
4665  ret i64 %masked
4666}
4667
4668define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
4669; X86-NOBMI-LABEL: bextr64_c4_commutative:
4670; X86-NOBMI:       # %bb.0:
4671; X86-NOBMI-NEXT:    pushl %ebp
4672; X86-NOBMI-NEXT:    pushl %ebx
4673; X86-NOBMI-NEXT:    pushl %edi
4674; X86-NOBMI-NEXT:    pushl %esi
4675; X86-NOBMI-NEXT:    subl $12, %esp
4676; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4677; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4678; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4679; X86-NOBMI-NEXT:    movl %eax, %edi
4680; X86-NOBMI-NEXT:    shrl %cl, %edi
4681; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4682; X86-NOBMI-NEXT:    testb $32, %cl
4683; X86-NOBMI-NEXT:    je .LBB36_2
4684; X86-NOBMI-NEXT:  # %bb.1:
4685; X86-NOBMI-NEXT:    movl %edi, %esi
4686; X86-NOBMI-NEXT:    xorl %edi, %edi
4687; X86-NOBMI-NEXT:  .LBB36_2:
4688; X86-NOBMI-NEXT:    movb $64, %cl
4689; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4690; X86-NOBMI-NEXT:    movl $-1, %ebp
4691; X86-NOBMI-NEXT:    movl $-1, %ebx
4692; X86-NOBMI-NEXT:    shrl %cl, %ebx
4693; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4694; X86-NOBMI-NEXT:    testb $32, %cl
4695; X86-NOBMI-NEXT:    je .LBB36_4
4696; X86-NOBMI-NEXT:  # %bb.3:
4697; X86-NOBMI-NEXT:    movl %ebx, %ebp
4698; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4699; X86-NOBMI-NEXT:  .LBB36_4:
4700; X86-NOBMI-NEXT:    subl $8, %esp
4701; X86-NOBMI-NEXT:    pushl %ebx
4702; X86-NOBMI-NEXT:    pushl %ebp
4703; X86-NOBMI-NEXT:    calll use64
4704; X86-NOBMI-NEXT:    addl $16, %esp
4705; X86-NOBMI-NEXT:    andl %ebp, %esi
4706; X86-NOBMI-NEXT:    andl %ebx, %edi
4707; X86-NOBMI-NEXT:    movl %esi, %eax
4708; X86-NOBMI-NEXT:    movl %edi, %edx
4709; X86-NOBMI-NEXT:    addl $12, %esp
4710; X86-NOBMI-NEXT:    popl %esi
4711; X86-NOBMI-NEXT:    popl %edi
4712; X86-NOBMI-NEXT:    popl %ebx
4713; X86-NOBMI-NEXT:    popl %ebp
4714; X86-NOBMI-NEXT:    retl
4715;
4716; X86-BMI1NOTBM-LABEL: bextr64_c4_commutative:
4717; X86-BMI1NOTBM:       # %bb.0:
4718; X86-BMI1NOTBM-NEXT:    pushl %ebp
4719; X86-BMI1NOTBM-NEXT:    pushl %ebx
4720; X86-BMI1NOTBM-NEXT:    pushl %edi
4721; X86-BMI1NOTBM-NEXT:    pushl %esi
4722; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4723; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4724; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
4725; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4726; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4727; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4728; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4729; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4730; X86-BMI1NOTBM-NEXT:    je .LBB36_2
4731; X86-BMI1NOTBM-NEXT:  # %bb.1:
4732; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4733; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4734; X86-BMI1NOTBM-NEXT:  .LBB36_2:
4735; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4736; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4737; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4738; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4739; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4740; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4741; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4742; X86-BMI1NOTBM-NEXT:    je .LBB36_4
4743; X86-BMI1NOTBM-NEXT:  # %bb.3:
4744; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4745; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4746; X86-BMI1NOTBM-NEXT:  .LBB36_4:
4747; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4748; X86-BMI1NOTBM-NEXT:    pushl %ebx
4749; X86-BMI1NOTBM-NEXT:    pushl %ebp
4750; X86-BMI1NOTBM-NEXT:    calll use64
4751; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4752; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4753; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4754; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4755; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4756; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4757; X86-BMI1NOTBM-NEXT:    popl %esi
4758; X86-BMI1NOTBM-NEXT:    popl %edi
4759; X86-BMI1NOTBM-NEXT:    popl %ebx
4760; X86-BMI1NOTBM-NEXT:    popl %ebp
4761; X86-BMI1NOTBM-NEXT:    retl
4762;
4763; X86-BMI1BMI2-LABEL: bextr64_c4_commutative:
4764; X86-BMI1BMI2:       # %bb.0:
4765; X86-BMI1BMI2-NEXT:    pushl %ebp
4766; X86-BMI1BMI2-NEXT:    pushl %ebx
4767; X86-BMI1BMI2-NEXT:    pushl %edi
4768; X86-BMI1BMI2-NEXT:    pushl %esi
4769; X86-BMI1BMI2-NEXT:    subl $12, %esp
4770; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4771; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4772; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4773; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4774; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4775; X86-BMI1BMI2-NEXT:    testb $32, %cl
4776; X86-BMI1BMI2-NEXT:    je .LBB36_2
4777; X86-BMI1BMI2-NEXT:  # %bb.1:
4778; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4779; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4780; X86-BMI1BMI2-NEXT:  .LBB36_2:
4781; X86-BMI1BMI2-NEXT:    movb $64, %cl
4782; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4783; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4784; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4785; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4786; X86-BMI1BMI2-NEXT:    testb $32, %cl
4787; X86-BMI1BMI2-NEXT:    je .LBB36_4
4788; X86-BMI1BMI2-NEXT:  # %bb.3:
4789; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4790; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4791; X86-BMI1BMI2-NEXT:  .LBB36_4:
4792; X86-BMI1BMI2-NEXT:    subl $8, %esp
4793; X86-BMI1BMI2-NEXT:    pushl %ebp
4794; X86-BMI1BMI2-NEXT:    pushl %ebx
4795; X86-BMI1BMI2-NEXT:    calll use64
4796; X86-BMI1BMI2-NEXT:    addl $16, %esp
4797; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4798; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4799; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4800; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4801; X86-BMI1BMI2-NEXT:    addl $12, %esp
4802; X86-BMI1BMI2-NEXT:    popl %esi
4803; X86-BMI1BMI2-NEXT:    popl %edi
4804; X86-BMI1BMI2-NEXT:    popl %ebx
4805; X86-BMI1BMI2-NEXT:    popl %ebp
4806; X86-BMI1BMI2-NEXT:    retl
4807;
4808; X64-NOBMI-LABEL: bextr64_c4_commutative:
4809; X64-NOBMI:       # %bb.0:
4810; X64-NOBMI-NEXT:    pushq %r14
4811; X64-NOBMI-NEXT:    pushq %rbx
4812; X64-NOBMI-NEXT:    pushq %rax
4813; X64-NOBMI-NEXT:    movq %rsi, %rcx
4814; X64-NOBMI-NEXT:    movq %rdi, %r14
4815; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
4816; X64-NOBMI-NEXT:    shrq %cl, %r14
4817; X64-NOBMI-NEXT:    negb %dl
4818; X64-NOBMI-NEXT:    movq $-1, %rbx
4819; X64-NOBMI-NEXT:    movl %edx, %ecx
4820; X64-NOBMI-NEXT:    shrq %cl, %rbx
4821; X64-NOBMI-NEXT:    movq %rbx, %rdi
4822; X64-NOBMI-NEXT:    callq use64
4823; X64-NOBMI-NEXT:    andq %r14, %rbx
4824; X64-NOBMI-NEXT:    movq %rbx, %rax
4825; X64-NOBMI-NEXT:    addq $8, %rsp
4826; X64-NOBMI-NEXT:    popq %rbx
4827; X64-NOBMI-NEXT:    popq %r14
4828; X64-NOBMI-NEXT:    retq
4829;
4830; X64-BMI1NOTBM-LABEL: bextr64_c4_commutative:
4831; X64-BMI1NOTBM:       # %bb.0:
4832; X64-BMI1NOTBM-NEXT:    pushq %r14
4833; X64-BMI1NOTBM-NEXT:    pushq %rbx
4834; X64-BMI1NOTBM-NEXT:    pushq %rax
4835; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
4836; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
4837; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
4838; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4839; X64-BMI1NOTBM-NEXT:    negb %dl
4840; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4841; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4842; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4843; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4844; X64-BMI1NOTBM-NEXT:    callq use64
4845; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4846; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4847; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4848; X64-BMI1NOTBM-NEXT:    popq %rbx
4849; X64-BMI1NOTBM-NEXT:    popq %r14
4850; X64-BMI1NOTBM-NEXT:    retq
4851;
4852; X64-BMI1BMI2-LABEL: bextr64_c4_commutative:
4853; X64-BMI1BMI2:       # %bb.0:
4854; X64-BMI1BMI2-NEXT:    pushq %r14
4855; X64-BMI1BMI2-NEXT:    pushq %rbx
4856; X64-BMI1BMI2-NEXT:    pushq %rax
4857; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
4858; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
4859; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4860; X64-BMI1BMI2-NEXT:    negb %al
4861; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4862; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4863; X64-BMI1BMI2-NEXT:    callq use64
4864; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4865; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4866; X64-BMI1BMI2-NEXT:    popq %rbx
4867; X64-BMI1BMI2-NEXT:    popq %r14
4868; X64-BMI1BMI2-NEXT:    retq
4869  %shifted = lshr i64 %val, %numskipbits
4870  %numhighbits = sub i64 64, %numlowbits
4871  %mask = lshr i64 -1, %numhighbits
4872  call void @use64(i64 %mask)
4873  %masked = and i64 %shifted, %mask ; swapped order
4874  ret i64 %masked
4875}
4876
4877define i64 @bextr64_c5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
4878; X86-NOBMI-LABEL: bextr64_c5_skipextrauses:
4879; X86-NOBMI:       # %bb.0:
4880; X86-NOBMI-NEXT:    pushl %ebp
4881; X86-NOBMI-NEXT:    pushl %ebx
4882; X86-NOBMI-NEXT:    pushl %edi
4883; X86-NOBMI-NEXT:    pushl %esi
4884; X86-NOBMI-NEXT:    subl $12, %esp
4885; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4886; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4887; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4888; X86-NOBMI-NEXT:    movl %eax, %edi
4889; X86-NOBMI-NEXT:    shrl %cl, %edi
4890; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4891; X86-NOBMI-NEXT:    testb $32, %cl
4892; X86-NOBMI-NEXT:    je .LBB37_2
4893; X86-NOBMI-NEXT:  # %bb.1:
4894; X86-NOBMI-NEXT:    movl %edi, %esi
4895; X86-NOBMI-NEXT:    xorl %edi, %edi
4896; X86-NOBMI-NEXT:  .LBB37_2:
4897; X86-NOBMI-NEXT:    movb $64, %cl
4898; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4899; X86-NOBMI-NEXT:    movl $-1, %ebx
4900; X86-NOBMI-NEXT:    movl $-1, %ebp
4901; X86-NOBMI-NEXT:    shrl %cl, %ebp
4902; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %ebx
4903; X86-NOBMI-NEXT:    testb $32, %cl
4904; X86-NOBMI-NEXT:    je .LBB37_4
4905; X86-NOBMI-NEXT:  # %bb.3:
4906; X86-NOBMI-NEXT:    movl %ebp, %ebx
4907; X86-NOBMI-NEXT:    xorl %ebp, %ebp
4908; X86-NOBMI-NEXT:  .LBB37_4:
4909; X86-NOBMI-NEXT:    subl $8, %esp
4910; X86-NOBMI-NEXT:    pushl %ebp
4911; X86-NOBMI-NEXT:    pushl %ebx
4912; X86-NOBMI-NEXT:    calll use64
4913; X86-NOBMI-NEXT:    addl $16, %esp
4914; X86-NOBMI-NEXT:    andl %ebx, %esi
4915; X86-NOBMI-NEXT:    andl %ebp, %edi
4916; X86-NOBMI-NEXT:    subl $8, %esp
4917; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
4918; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
4919; X86-NOBMI-NEXT:    calll use64
4920; X86-NOBMI-NEXT:    addl $16, %esp
4921; X86-NOBMI-NEXT:    movl %esi, %eax
4922; X86-NOBMI-NEXT:    movl %edi, %edx
4923; X86-NOBMI-NEXT:    addl $12, %esp
4924; X86-NOBMI-NEXT:    popl %esi
4925; X86-NOBMI-NEXT:    popl %edi
4926; X86-NOBMI-NEXT:    popl %ebx
4927; X86-NOBMI-NEXT:    popl %ebp
4928; X86-NOBMI-NEXT:    retl
4929;
4930; X86-BMI1NOTBM-LABEL: bextr64_c5_skipextrauses:
4931; X86-BMI1NOTBM:       # %bb.0:
4932; X86-BMI1NOTBM-NEXT:    pushl %ebp
4933; X86-BMI1NOTBM-NEXT:    pushl %ebx
4934; X86-BMI1NOTBM-NEXT:    pushl %edi
4935; X86-BMI1NOTBM-NEXT:    pushl %esi
4936; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4937; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
4938; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4939; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4940; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4941; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4942; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4943; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4944; X86-BMI1NOTBM-NEXT:    je .LBB37_2
4945; X86-BMI1NOTBM-NEXT:  # %bb.1:
4946; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4947; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4948; X86-BMI1NOTBM-NEXT:  .LBB37_2:
4949; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4950; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4951; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4952; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4953; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebp
4954; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %ebx
4955; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4956; X86-BMI1NOTBM-NEXT:    je .LBB37_4
4957; X86-BMI1NOTBM-NEXT:  # %bb.3:
4958; X86-BMI1NOTBM-NEXT:    movl %ebp, %ebx
4959; X86-BMI1NOTBM-NEXT:    xorl %ebp, %ebp
4960; X86-BMI1NOTBM-NEXT:  .LBB37_4:
4961; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4962; X86-BMI1NOTBM-NEXT:    pushl %ebp
4963; X86-BMI1NOTBM-NEXT:    pushl %ebx
4964; X86-BMI1NOTBM-NEXT:    calll use64
4965; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4966; X86-BMI1NOTBM-NEXT:    andl %ebx, %esi
4967; X86-BMI1NOTBM-NEXT:    andl %ebp, %edi
4968; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4969; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
4970; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
4971; X86-BMI1NOTBM-NEXT:    calll use64
4972; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4973; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4974; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4975; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4976; X86-BMI1NOTBM-NEXT:    popl %esi
4977; X86-BMI1NOTBM-NEXT:    popl %edi
4978; X86-BMI1NOTBM-NEXT:    popl %ebx
4979; X86-BMI1NOTBM-NEXT:    popl %ebp
4980; X86-BMI1NOTBM-NEXT:    retl
4981;
4982; X86-BMI1BMI2-LABEL: bextr64_c5_skipextrauses:
4983; X86-BMI1BMI2:       # %bb.0:
4984; X86-BMI1BMI2-NEXT:    pushl %ebp
4985; X86-BMI1BMI2-NEXT:    pushl %ebx
4986; X86-BMI1BMI2-NEXT:    pushl %edi
4987; X86-BMI1BMI2-NEXT:    pushl %esi
4988; X86-BMI1BMI2-NEXT:    subl $12, %esp
4989; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4990; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4991; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4992; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4993; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4994; X86-BMI1BMI2-NEXT:    testb $32, %cl
4995; X86-BMI1BMI2-NEXT:    je .LBB37_2
4996; X86-BMI1BMI2-NEXT:  # %bb.1:
4997; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4998; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4999; X86-BMI1BMI2-NEXT:  .LBB37_2:
5000; X86-BMI1BMI2-NEXT:    movb $64, %cl
5001; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5002; X86-BMI1BMI2-NEXT:    movl $-1, %ebp
5003; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebp, %ebx
5004; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebp, %ebp
5005; X86-BMI1BMI2-NEXT:    testb $32, %cl
5006; X86-BMI1BMI2-NEXT:    je .LBB37_4
5007; X86-BMI1BMI2-NEXT:  # %bb.3:
5008; X86-BMI1BMI2-NEXT:    movl %ebx, %ebp
5009; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
5010; X86-BMI1BMI2-NEXT:  .LBB37_4:
5011; X86-BMI1BMI2-NEXT:    subl $8, %esp
5012; X86-BMI1BMI2-NEXT:    pushl %ebx
5013; X86-BMI1BMI2-NEXT:    pushl %ebp
5014; X86-BMI1BMI2-NEXT:    calll use64
5015; X86-BMI1BMI2-NEXT:    addl $16, %esp
5016; X86-BMI1BMI2-NEXT:    andl %ebp, %esi
5017; X86-BMI1BMI2-NEXT:    andl %ebx, %edi
5018; X86-BMI1BMI2-NEXT:    subl $8, %esp
5019; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
5020; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
5021; X86-BMI1BMI2-NEXT:    calll use64
5022; X86-BMI1BMI2-NEXT:    addl $16, %esp
5023; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5024; X86-BMI1BMI2-NEXT:    movl %edi, %edx
5025; X86-BMI1BMI2-NEXT:    addl $12, %esp
5026; X86-BMI1BMI2-NEXT:    popl %esi
5027; X86-BMI1BMI2-NEXT:    popl %edi
5028; X86-BMI1BMI2-NEXT:    popl %ebx
5029; X86-BMI1BMI2-NEXT:    popl %ebp
5030; X86-BMI1BMI2-NEXT:    retl
5031;
5032; X64-NOBMI-LABEL: bextr64_c5_skipextrauses:
5033; X64-NOBMI:       # %bb.0:
5034; X64-NOBMI-NEXT:    pushq %r15
5035; X64-NOBMI-NEXT:    pushq %r14
5036; X64-NOBMI-NEXT:    pushq %rbx
5037; X64-NOBMI-NEXT:    movq %rsi, %r14
5038; X64-NOBMI-NEXT:    movq %rdi, %r15
5039; X64-NOBMI-NEXT:    movl %r14d, %ecx
5040; X64-NOBMI-NEXT:    shrq %cl, %r15
5041; X64-NOBMI-NEXT:    negb %dl
5042; X64-NOBMI-NEXT:    movq $-1, %rbx
5043; X64-NOBMI-NEXT:    movl %edx, %ecx
5044; X64-NOBMI-NEXT:    shrq %cl, %rbx
5045; X64-NOBMI-NEXT:    movq %rbx, %rdi
5046; X64-NOBMI-NEXT:    callq use64
5047; X64-NOBMI-NEXT:    andq %r15, %rbx
5048; X64-NOBMI-NEXT:    movq %r14, %rdi
5049; X64-NOBMI-NEXT:    callq use64
5050; X64-NOBMI-NEXT:    movq %rbx, %rax
5051; X64-NOBMI-NEXT:    popq %rbx
5052; X64-NOBMI-NEXT:    popq %r14
5053; X64-NOBMI-NEXT:    popq %r15
5054; X64-NOBMI-NEXT:    retq
5055;
5056; X64-BMI1NOTBM-LABEL: bextr64_c5_skipextrauses:
5057; X64-BMI1NOTBM:       # %bb.0:
5058; X64-BMI1NOTBM-NEXT:    pushq %r15
5059; X64-BMI1NOTBM-NEXT:    pushq %r14
5060; X64-BMI1NOTBM-NEXT:    pushq %rbx
5061; X64-BMI1NOTBM-NEXT:    movq %rsi, %r14
5062; X64-BMI1NOTBM-NEXT:    movq %rdi, %r15
5063; X64-BMI1NOTBM-NEXT:    movl %r14d, %ecx
5064; X64-BMI1NOTBM-NEXT:    shrq %cl, %r15
5065; X64-BMI1NOTBM-NEXT:    negb %dl
5066; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
5067; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5068; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
5069; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
5070; X64-BMI1NOTBM-NEXT:    callq use64
5071; X64-BMI1NOTBM-NEXT:    andq %r15, %rbx
5072; X64-BMI1NOTBM-NEXT:    movq %r14, %rdi
5073; X64-BMI1NOTBM-NEXT:    callq use64
5074; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
5075; X64-BMI1NOTBM-NEXT:    popq %rbx
5076; X64-BMI1NOTBM-NEXT:    popq %r14
5077; X64-BMI1NOTBM-NEXT:    popq %r15
5078; X64-BMI1NOTBM-NEXT:    retq
5079;
5080; X64-BMI1BMI2-LABEL: bextr64_c5_skipextrauses:
5081; X64-BMI1BMI2:       # %bb.0:
5082; X64-BMI1BMI2-NEXT:    pushq %r15
5083; X64-BMI1BMI2-NEXT:    pushq %r14
5084; X64-BMI1BMI2-NEXT:    pushq %rbx
5085; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
5086; X64-BMI1BMI2-NEXT:    movq %rsi, %r14
5087; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r15
5088; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5089; X64-BMI1BMI2-NEXT:    negb %al
5090; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
5091; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
5092; X64-BMI1BMI2-NEXT:    callq use64
5093; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r15, %rbx
5094; X64-BMI1BMI2-NEXT:    movq %r14, %rdi
5095; X64-BMI1BMI2-NEXT:    callq use64
5096; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
5097; X64-BMI1BMI2-NEXT:    popq %rbx
5098; X64-BMI1BMI2-NEXT:    popq %r14
5099; X64-BMI1BMI2-NEXT:    popq %r15
5100; X64-BMI1BMI2-NEXT:    retq
5101  %shifted = lshr i64 %val, %numskipbits
5102  %numhighbits = sub i64 64, %numlowbits
5103  %mask = lshr i64 -1, %numhighbits
5104  call void @use64(i64 %mask)
5105  %masked = and i64 %mask, %shifted
5106  call void @use64(i64 %numskipbits)
5107  ret i64 %masked
5108}
5109
5110; ---------------------------------------------------------------------------- ;
5111; Pattern d. 32-bit.
5112; ---------------------------------------------------------------------------- ;
5113
5114define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
5115; X86-NOBMI-LABEL: bextr32_d0:
5116; X86-NOBMI:       # %bb.0:
5117; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5118; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5119; X86-NOBMI-NEXT:    shrl %cl, %eax
5120; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5121; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5122; X86-NOBMI-NEXT:    shll %cl, %eax
5123; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5124; X86-NOBMI-NEXT:    shrl %cl, %eax
5125; X86-NOBMI-NEXT:    retl
5126;
5127; X86-BMI1NOTBM-LABEL: bextr32_d0:
5128; X86-BMI1NOTBM:       # %bb.0:
5129; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
5130; X86-BMI1NOTBM-NEXT:    shll $8, %eax
5131; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5132; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
5133; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
5134; X86-BMI1NOTBM-NEXT:    retl
5135;
5136; X86-BMI1BMI2-LABEL: bextr32_d0:
5137; X86-BMI1BMI2:       # %bb.0:
5138; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5139; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5140; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
5141; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
5142; X86-BMI1BMI2-NEXT:    retl
5143;
5144; X64-NOBMI-LABEL: bextr32_d0:
5145; X64-NOBMI:       # %bb.0:
5146; X64-NOBMI-NEXT:    movl %esi, %ecx
5147; X64-NOBMI-NEXT:    movl %edi, %eax
5148; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5149; X64-NOBMI-NEXT:    shrl %cl, %eax
5150; X64-NOBMI-NEXT:    negb %dl
5151; X64-NOBMI-NEXT:    movl %edx, %ecx
5152; X64-NOBMI-NEXT:    shll %cl, %eax
5153; X64-NOBMI-NEXT:    shrl %cl, %eax
5154; X64-NOBMI-NEXT:    retq
5155;
5156; X64-BMI1NOTBM-LABEL: bextr32_d0:
5157; X64-BMI1NOTBM:       # %bb.0:
5158; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5159; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5160; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
5161; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
5162; X64-BMI1NOTBM-NEXT:    retq
5163;
5164; X64-BMI1BMI2-LABEL: bextr32_d0:
5165; X64-BMI1BMI2:       # %bb.0:
5166; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
5167; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
5168; X64-BMI1BMI2-NEXT:    retq
5169  %shifted = lshr i32 %val, %numskipbits
5170  %numhighbits = sub i32 32, %numlowbits
5171  %highbitscleared = shl i32 %shifted, %numhighbits
5172  %masked = lshr i32 %highbitscleared, %numhighbits
5173  ret i32 %masked
5174}
5175
5176define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
5177; X86-NOBMI-LABEL: bextr32_d1_indexzext:
5178; X86-NOBMI:       # %bb.0:
5179; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5180; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5181; X86-NOBMI-NEXT:    shrl %cl, %eax
5182; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5183; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5184; X86-NOBMI-NEXT:    shll %cl, %eax
5185; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5186; X86-NOBMI-NEXT:    shrl %cl, %eax
5187; X86-NOBMI-NEXT:    retl
5188;
5189; X86-BMI1NOTBM-LABEL: bextr32_d1_indexzext:
5190; X86-BMI1NOTBM:       # %bb.0:
5191; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
5192; X86-BMI1NOTBM-NEXT:    shll $8, %eax
5193; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5194; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
5195; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
5196; X86-BMI1NOTBM-NEXT:    retl
5197;
5198; X86-BMI1BMI2-LABEL: bextr32_d1_indexzext:
5199; X86-BMI1BMI2:       # %bb.0:
5200; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5201; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5202; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
5203; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
5204; X86-BMI1BMI2-NEXT:    retl
5205;
5206; X64-NOBMI-LABEL: bextr32_d1_indexzext:
5207; X64-NOBMI:       # %bb.0:
5208; X64-NOBMI-NEXT:    movl %esi, %ecx
5209; X64-NOBMI-NEXT:    movl %edi, %eax
5210; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5211; X64-NOBMI-NEXT:    shrl %cl, %eax
5212; X64-NOBMI-NEXT:    negb %dl
5213; X64-NOBMI-NEXT:    movl %edx, %ecx
5214; X64-NOBMI-NEXT:    shll %cl, %eax
5215; X64-NOBMI-NEXT:    shrl %cl, %eax
5216; X64-NOBMI-NEXT:    retq
5217;
5218; X64-BMI1NOTBM-LABEL: bextr32_d1_indexzext:
5219; X64-BMI1NOTBM:       # %bb.0:
5220; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5221; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5222; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
5223; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
5224; X64-BMI1NOTBM-NEXT:    retq
5225;
5226; X64-BMI1BMI2-LABEL: bextr32_d1_indexzext:
5227; X64-BMI1BMI2:       # %bb.0:
5228; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
5229; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
5230; X64-BMI1BMI2-NEXT:    retq
5231  %skip = zext i8 %numskipbits to i32
5232  %shifted = lshr i32 %val, %skip
5233  %numhighbits = sub i8 32, %numlowbits
5234  %sh_prom = zext i8 %numhighbits to i32
5235  %highbitscleared = shl i32 %shifted, %sh_prom
5236  %masked = lshr i32 %highbitscleared, %sh_prom
5237  ret i32 %masked
5238}
5239
5240define i32 @bextr32_d2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
5241; X86-NOBMI-LABEL: bextr32_d2_load:
5242; X86-NOBMI:       # %bb.0:
5243; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5244; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5245; X86-NOBMI-NEXT:    movl (%eax), %eax
5246; X86-NOBMI-NEXT:    shrl %cl, %eax
5247; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5248; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5249; X86-NOBMI-NEXT:    shll %cl, %eax
5250; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5251; X86-NOBMI-NEXT:    shrl %cl, %eax
5252; X86-NOBMI-NEXT:    retl
5253;
5254; X86-BMI1NOTBM-LABEL: bextr32_d2_load:
5255; X86-BMI1NOTBM:       # %bb.0:
5256; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5257; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5258; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
5259; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
5260; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
5261; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
5262; X86-BMI1NOTBM-NEXT:    retl
5263;
5264; X86-BMI1BMI2-LABEL: bextr32_d2_load:
5265; X86-BMI1BMI2:       # %bb.0:
5266; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5267; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5268; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
5269; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
5270; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
5271; X86-BMI1BMI2-NEXT:    retl
5272;
5273; X64-NOBMI-LABEL: bextr32_d2_load:
5274; X64-NOBMI:       # %bb.0:
5275; X64-NOBMI-NEXT:    movl %esi, %ecx
5276; X64-NOBMI-NEXT:    movl (%rdi), %eax
5277; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5278; X64-NOBMI-NEXT:    shrl %cl, %eax
5279; X64-NOBMI-NEXT:    negb %dl
5280; X64-NOBMI-NEXT:    movl %edx, %ecx
5281; X64-NOBMI-NEXT:    shll %cl, %eax
5282; X64-NOBMI-NEXT:    shrl %cl, %eax
5283; X64-NOBMI-NEXT:    retq
5284;
5285; X64-BMI1NOTBM-LABEL: bextr32_d2_load:
5286; X64-BMI1NOTBM:       # %bb.0:
5287; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5288; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5289; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
5290; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
5291; X64-BMI1NOTBM-NEXT:    retq
5292;
5293; X64-BMI1BMI2-LABEL: bextr32_d2_load:
5294; X64-BMI1BMI2:       # %bb.0:
5295; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
5296; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
5297; X64-BMI1BMI2-NEXT:    retq
5298  %val = load i32, i32* %w
5299  %shifted = lshr i32 %val, %numskipbits
5300  %numhighbits = sub i32 32, %numlowbits
5301  %highbitscleared = shl i32 %shifted, %numhighbits
5302  %masked = lshr i32 %highbitscleared, %numhighbits
5303  ret i32 %masked
5304}
5305
5306define i32 @bextr32_d3_load_indexzext(i32* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
5307; X86-NOBMI-LABEL: bextr32_d3_load_indexzext:
5308; X86-NOBMI:       # %bb.0:
5309; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5310; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5311; X86-NOBMI-NEXT:    movl (%eax), %eax
5312; X86-NOBMI-NEXT:    shrl %cl, %eax
5313; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5314; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5315; X86-NOBMI-NEXT:    shll %cl, %eax
5316; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5317; X86-NOBMI-NEXT:    shrl %cl, %eax
5318; X86-NOBMI-NEXT:    retl
5319;
5320; X86-BMI1NOTBM-LABEL: bextr32_d3_load_indexzext:
5321; X86-BMI1NOTBM:       # %bb.0:
5322; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5323; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5324; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
5325; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
5326; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
5327; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
5328; X86-BMI1NOTBM-NEXT:    retl
5329;
5330; X86-BMI1BMI2-LABEL: bextr32_d3_load_indexzext:
5331; X86-BMI1BMI2:       # %bb.0:
5332; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5333; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5334; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
5335; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
5336; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
5337; X86-BMI1BMI2-NEXT:    retl
5338;
5339; X64-NOBMI-LABEL: bextr32_d3_load_indexzext:
5340; X64-NOBMI:       # %bb.0:
5341; X64-NOBMI-NEXT:    movl %esi, %ecx
5342; X64-NOBMI-NEXT:    movl (%rdi), %eax
5343; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5344; X64-NOBMI-NEXT:    shrl %cl, %eax
5345; X64-NOBMI-NEXT:    negb %dl
5346; X64-NOBMI-NEXT:    movl %edx, %ecx
5347; X64-NOBMI-NEXT:    shll %cl, %eax
5348; X64-NOBMI-NEXT:    shrl %cl, %eax
5349; X64-NOBMI-NEXT:    retq
5350;
5351; X64-BMI1NOTBM-LABEL: bextr32_d3_load_indexzext:
5352; X64-BMI1NOTBM:       # %bb.0:
5353; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5354; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5355; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
5356; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
5357; X64-BMI1NOTBM-NEXT:    retq
5358;
5359; X64-BMI1BMI2-LABEL: bextr32_d3_load_indexzext:
5360; X64-BMI1BMI2:       # %bb.0:
5361; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
5362; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
5363; X64-BMI1BMI2-NEXT:    retq
5364  %val = load i32, i32* %w
5365  %skip = zext i8 %numskipbits to i32
5366  %shifted = lshr i32 %val, %skip
5367  %numhighbits = sub i8 32, %numlowbits
5368  %sh_prom = zext i8 %numhighbits to i32
5369  %highbitscleared = shl i32 %shifted, %sh_prom
5370  %masked = lshr i32 %highbitscleared, %sh_prom
5371  ret i32 %masked
5372}
5373
5374define i32 @bextr32_d5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
5375; X86-NOBMI-LABEL: bextr32_d5_skipextrauses:
5376; X86-NOBMI:       # %bb.0:
5377; X86-NOBMI-NEXT:    pushl %esi
5378; X86-NOBMI-NEXT:    subl $8, %esp
5379; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5380; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5381; X86-NOBMI-NEXT:    movl %eax, %ecx
5382; X86-NOBMI-NEXT:    shrl %cl, %esi
5383; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5384; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5385; X86-NOBMI-NEXT:    shll %cl, %esi
5386; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5387; X86-NOBMI-NEXT:    shrl %cl, %esi
5388; X86-NOBMI-NEXT:    movl %eax, (%esp)
5389; X86-NOBMI-NEXT:    calll use32
5390; X86-NOBMI-NEXT:    movl %esi, %eax
5391; X86-NOBMI-NEXT:    addl $8, %esp
5392; X86-NOBMI-NEXT:    popl %esi
5393; X86-NOBMI-NEXT:    retl
5394;
5395; X86-BMI1NOTBM-LABEL: bextr32_d5_skipextrauses:
5396; X86-BMI1NOTBM:       # %bb.0:
5397; X86-BMI1NOTBM-NEXT:    pushl %esi
5398; X86-BMI1NOTBM-NEXT:    subl $8, %esp
5399; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5400; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5401; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
5402; X86-BMI1NOTBM-NEXT:    movzbl %al, %edx
5403; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
5404; X86-BMI1NOTBM-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
5405; X86-BMI1NOTBM-NEXT:    movl %eax, (%esp)
5406; X86-BMI1NOTBM-NEXT:    calll use32
5407; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5408; X86-BMI1NOTBM-NEXT:    addl $8, %esp
5409; X86-BMI1NOTBM-NEXT:    popl %esi
5410; X86-BMI1NOTBM-NEXT:    retl
5411;
5412; X86-BMI1BMI2-LABEL: bextr32_d5_skipextrauses:
5413; X86-BMI1BMI2:       # %bb.0:
5414; X86-BMI1BMI2-NEXT:    pushl %esi
5415; X86-BMI1BMI2-NEXT:    subl $8, %esp
5416; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5417; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5418; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
5419; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %esi
5420; X86-BMI1BMI2-NEXT:    movl %ecx, (%esp)
5421; X86-BMI1BMI2-NEXT:    calll use32
5422; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5423; X86-BMI1BMI2-NEXT:    addl $8, %esp
5424; X86-BMI1BMI2-NEXT:    popl %esi
5425; X86-BMI1BMI2-NEXT:    retl
5426;
5427; X64-NOBMI-LABEL: bextr32_d5_skipextrauses:
5428; X64-NOBMI:       # %bb.0:
5429; X64-NOBMI-NEXT:    pushq %rbx
5430; X64-NOBMI-NEXT:    movl %edi, %ebx
5431; X64-NOBMI-NEXT:    movl %esi, %ecx
5432; X64-NOBMI-NEXT:    shrl %cl, %ebx
5433; X64-NOBMI-NEXT:    negb %dl
5434; X64-NOBMI-NEXT:    movl %edx, %ecx
5435; X64-NOBMI-NEXT:    shll %cl, %ebx
5436; X64-NOBMI-NEXT:    shrl %cl, %ebx
5437; X64-NOBMI-NEXT:    movl %esi, %edi
5438; X64-NOBMI-NEXT:    callq use32
5439; X64-NOBMI-NEXT:    movl %ebx, %eax
5440; X64-NOBMI-NEXT:    popq %rbx
5441; X64-NOBMI-NEXT:    retq
5442;
5443; X64-BMI1NOTBM-LABEL: bextr32_d5_skipextrauses:
5444; X64-BMI1NOTBM:       # %bb.0:
5445; X64-BMI1NOTBM-NEXT:    pushq %rbx
5446; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5447; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5448; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
5449; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %ebx
5450; X64-BMI1NOTBM-NEXT:    movl %esi, %edi
5451; X64-BMI1NOTBM-NEXT:    callq use32
5452; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
5453; X64-BMI1NOTBM-NEXT:    popq %rbx
5454; X64-BMI1NOTBM-NEXT:    retq
5455;
5456; X64-BMI1BMI2-LABEL: bextr32_d5_skipextrauses:
5457; X64-BMI1BMI2:       # %bb.0:
5458; X64-BMI1BMI2-NEXT:    pushq %rbx
5459; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
5460; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %ebx
5461; X64-BMI1BMI2-NEXT:    movl %esi, %edi
5462; X64-BMI1BMI2-NEXT:    callq use32
5463; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5464; X64-BMI1BMI2-NEXT:    popq %rbx
5465; X64-BMI1BMI2-NEXT:    retq
5466  %shifted = lshr i32 %val, %numskipbits
5467  %numhighbits = sub i32 32, %numlowbits
5468  %highbitscleared = shl i32 %shifted, %numhighbits
5469  %masked = lshr i32 %highbitscleared, %numhighbits
5470  call void @use32(i32 %numskipbits)
5471  ret i32 %masked
5472}
5473
5474; 64-bit.
5475
5476define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5477; X86-NOBMI-LABEL: bextr64_d0:
5478; X86-NOBMI:       # %bb.0:
5479; X86-NOBMI-NEXT:    pushl %ebx
5480; X86-NOBMI-NEXT:    pushl %edi
5481; X86-NOBMI-NEXT:    pushl %esi
5482; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5483; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
5484; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
5485; X86-NOBMI-NEXT:    movl %edx, %eax
5486; X86-NOBMI-NEXT:    shrl %cl, %eax
5487; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
5488; X86-NOBMI-NEXT:    xorl %esi, %esi
5489; X86-NOBMI-NEXT:    testb $32, %cl
5490; X86-NOBMI-NEXT:    je .LBB43_2
5491; X86-NOBMI-NEXT:  # %bb.1:
5492; X86-NOBMI-NEXT:    movl %eax, %edi
5493; X86-NOBMI-NEXT:    xorl %eax, %eax
5494; X86-NOBMI-NEXT:  .LBB43_2:
5495; X86-NOBMI-NEXT:    movb $64, %cl
5496; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5497; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
5498; X86-NOBMI-NEXT:    shll %cl, %edi
5499; X86-NOBMI-NEXT:    testb $32, %cl
5500; X86-NOBMI-NEXT:    movl %edi, %ebx
5501; X86-NOBMI-NEXT:    jne .LBB43_4
5502; X86-NOBMI-NEXT:  # %bb.3:
5503; X86-NOBMI-NEXT:    movl %eax, %ebx
5504; X86-NOBMI-NEXT:  .LBB43_4:
5505; X86-NOBMI-NEXT:    movl %ebx, %eax
5506; X86-NOBMI-NEXT:    shrl %cl, %eax
5507; X86-NOBMI-NEXT:    testb $32, %cl
5508; X86-NOBMI-NEXT:    movl $0, %edx
5509; X86-NOBMI-NEXT:    jne .LBB43_6
5510; X86-NOBMI-NEXT:  # %bb.5:
5511; X86-NOBMI-NEXT:    movl %edi, %esi
5512; X86-NOBMI-NEXT:    movl %eax, %edx
5513; X86-NOBMI-NEXT:  .LBB43_6:
5514; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
5515; X86-NOBMI-NEXT:    testb $32, %cl
5516; X86-NOBMI-NEXT:    jne .LBB43_8
5517; X86-NOBMI-NEXT:  # %bb.7:
5518; X86-NOBMI-NEXT:    movl %esi, %eax
5519; X86-NOBMI-NEXT:  .LBB43_8:
5520; X86-NOBMI-NEXT:    popl %esi
5521; X86-NOBMI-NEXT:    popl %edi
5522; X86-NOBMI-NEXT:    popl %ebx
5523; X86-NOBMI-NEXT:    retl
5524;
5525; X86-BMI1NOTBM-LABEL: bextr64_d0:
5526; X86-BMI1NOTBM:       # %bb.0:
5527; X86-BMI1NOTBM-NEXT:    pushl %ebx
5528; X86-BMI1NOTBM-NEXT:    pushl %edi
5529; X86-BMI1NOTBM-NEXT:    pushl %esi
5530; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5531; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
5532; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
5533; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
5534; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5535; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
5536; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
5537; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5538; X86-BMI1NOTBM-NEXT:    je .LBB43_2
5539; X86-BMI1NOTBM-NEXT:  # %bb.1:
5540; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5541; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
5542; X86-BMI1NOTBM-NEXT:  .LBB43_2:
5543; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5544; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5545; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
5546; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
5547; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5548; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
5549; X86-BMI1NOTBM-NEXT:    jne .LBB43_4
5550; X86-BMI1NOTBM-NEXT:  # %bb.3:
5551; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
5552; X86-BMI1NOTBM-NEXT:  .LBB43_4:
5553; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
5554; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5555; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5556; X86-BMI1NOTBM-NEXT:    movl $0, %edx
5557; X86-BMI1NOTBM-NEXT:    jne .LBB43_6
5558; X86-BMI1NOTBM-NEXT:  # %bb.5:
5559; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5560; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
5561; X86-BMI1NOTBM-NEXT:  .LBB43_6:
5562; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
5563; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5564; X86-BMI1NOTBM-NEXT:    jne .LBB43_8
5565; X86-BMI1NOTBM-NEXT:  # %bb.7:
5566; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5567; X86-BMI1NOTBM-NEXT:  .LBB43_8:
5568; X86-BMI1NOTBM-NEXT:    popl %esi
5569; X86-BMI1NOTBM-NEXT:    popl %edi
5570; X86-BMI1NOTBM-NEXT:    popl %ebx
5571; X86-BMI1NOTBM-NEXT:    retl
5572;
5573; X86-BMI1BMI2-LABEL: bextr64_d0:
5574; X86-BMI1BMI2:       # %bb.0:
5575; X86-BMI1BMI2-NEXT:    pushl %edi
5576; X86-BMI1BMI2-NEXT:    pushl %esi
5577; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5578; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5579; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
5580; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
5581; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
5582; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
5583; X86-BMI1BMI2-NEXT:    testb $32, %cl
5584; X86-BMI1BMI2-NEXT:    je .LBB43_2
5585; X86-BMI1BMI2-NEXT:  # %bb.1:
5586; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5587; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
5588; X86-BMI1BMI2-NEXT:  .LBB43_2:
5589; X86-BMI1BMI2-NEXT:    movb $64, %cl
5590; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5591; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
5592; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
5593; X86-BMI1BMI2-NEXT:    testb $32, %cl
5594; X86-BMI1BMI2-NEXT:    je .LBB43_4
5595; X86-BMI1BMI2-NEXT:  # %bb.3:
5596; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5597; X86-BMI1BMI2-NEXT:    movl $0, %edi
5598; X86-BMI1BMI2-NEXT:  .LBB43_4:
5599; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
5600; X86-BMI1BMI2-NEXT:    jne .LBB43_6
5601; X86-BMI1BMI2-NEXT:  # %bb.5:
5602; X86-BMI1BMI2-NEXT:    movl %eax, %edx
5603; X86-BMI1BMI2-NEXT:  .LBB43_6:
5604; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
5605; X86-BMI1BMI2-NEXT:    testb $32, %cl
5606; X86-BMI1BMI2-NEXT:    jne .LBB43_8
5607; X86-BMI1BMI2-NEXT:  # %bb.7:
5608; X86-BMI1BMI2-NEXT:    movl %edi, %eax
5609; X86-BMI1BMI2-NEXT:  .LBB43_8:
5610; X86-BMI1BMI2-NEXT:    popl %esi
5611; X86-BMI1BMI2-NEXT:    popl %edi
5612; X86-BMI1BMI2-NEXT:    retl
5613;
5614; X64-NOBMI-LABEL: bextr64_d0:
5615; X64-NOBMI:       # %bb.0:
5616; X64-NOBMI-NEXT:    movq %rsi, %rcx
5617; X64-NOBMI-NEXT:    movq %rdi, %rax
5618; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5619; X64-NOBMI-NEXT:    shrq %cl, %rax
5620; X64-NOBMI-NEXT:    negb %dl
5621; X64-NOBMI-NEXT:    movl %edx, %ecx
5622; X64-NOBMI-NEXT:    shlq %cl, %rax
5623; X64-NOBMI-NEXT:    shrq %cl, %rax
5624; X64-NOBMI-NEXT:    retq
5625;
5626; X64-BMI1NOTBM-LABEL: bextr64_d0:
5627; X64-BMI1NOTBM:       # %bb.0:
5628; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
5629; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5630; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
5631; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
5632; X64-BMI1NOTBM-NEXT:    retq
5633;
5634; X64-BMI1BMI2-LABEL: bextr64_d0:
5635; X64-BMI1BMI2:       # %bb.0:
5636; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
5637; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
5638; X64-BMI1BMI2-NEXT:    retq
5639  %shifted = lshr i64 %val, %numskipbits
5640  %numhighbits = sub i64 64, %numlowbits
5641  %highbitscleared = shl i64 %shifted, %numhighbits
5642  %masked = lshr i64 %highbitscleared, %numhighbits
5643  ret i64 %masked
5644}
5645
5646define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
5647; X86-NOBMI-LABEL: bextr64_d1_indexzext:
5648; X86-NOBMI:       # %bb.0:
5649; X86-NOBMI-NEXT:    pushl %ebx
5650; X86-NOBMI-NEXT:    pushl %edi
5651; X86-NOBMI-NEXT:    pushl %esi
5652; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5653; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
5654; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
5655; X86-NOBMI-NEXT:    movl %edx, %eax
5656; X86-NOBMI-NEXT:    shrl %cl, %eax
5657; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
5658; X86-NOBMI-NEXT:    xorl %esi, %esi
5659; X86-NOBMI-NEXT:    testb $32, %cl
5660; X86-NOBMI-NEXT:    je .LBB44_2
5661; X86-NOBMI-NEXT:  # %bb.1:
5662; X86-NOBMI-NEXT:    movl %eax, %edi
5663; X86-NOBMI-NEXT:    xorl %eax, %eax
5664; X86-NOBMI-NEXT:  .LBB44_2:
5665; X86-NOBMI-NEXT:    movb $64, %cl
5666; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5667; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
5668; X86-NOBMI-NEXT:    shll %cl, %edi
5669; X86-NOBMI-NEXT:    testb $32, %cl
5670; X86-NOBMI-NEXT:    movl %edi, %ebx
5671; X86-NOBMI-NEXT:    jne .LBB44_4
5672; X86-NOBMI-NEXT:  # %bb.3:
5673; X86-NOBMI-NEXT:    movl %eax, %ebx
5674; X86-NOBMI-NEXT:  .LBB44_4:
5675; X86-NOBMI-NEXT:    movl %ebx, %eax
5676; X86-NOBMI-NEXT:    shrl %cl, %eax
5677; X86-NOBMI-NEXT:    testb $32, %cl
5678; X86-NOBMI-NEXT:    movl $0, %edx
5679; X86-NOBMI-NEXT:    jne .LBB44_6
5680; X86-NOBMI-NEXT:  # %bb.5:
5681; X86-NOBMI-NEXT:    movl %edi, %esi
5682; X86-NOBMI-NEXT:    movl %eax, %edx
5683; X86-NOBMI-NEXT:  .LBB44_6:
5684; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
5685; X86-NOBMI-NEXT:    testb $32, %cl
5686; X86-NOBMI-NEXT:    jne .LBB44_8
5687; X86-NOBMI-NEXT:  # %bb.7:
5688; X86-NOBMI-NEXT:    movl %esi, %eax
5689; X86-NOBMI-NEXT:  .LBB44_8:
5690; X86-NOBMI-NEXT:    popl %esi
5691; X86-NOBMI-NEXT:    popl %edi
5692; X86-NOBMI-NEXT:    popl %ebx
5693; X86-NOBMI-NEXT:    retl
5694;
5695; X86-BMI1NOTBM-LABEL: bextr64_d1_indexzext:
5696; X86-BMI1NOTBM:       # %bb.0:
5697; X86-BMI1NOTBM-NEXT:    pushl %ebx
5698; X86-BMI1NOTBM-NEXT:    pushl %edi
5699; X86-BMI1NOTBM-NEXT:    pushl %esi
5700; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5701; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
5702; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
5703; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
5704; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5705; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
5706; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
5707; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5708; X86-BMI1NOTBM-NEXT:    je .LBB44_2
5709; X86-BMI1NOTBM-NEXT:  # %bb.1:
5710; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5711; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
5712; X86-BMI1NOTBM-NEXT:  .LBB44_2:
5713; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5714; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5715; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
5716; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
5717; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5718; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
5719; X86-BMI1NOTBM-NEXT:    jne .LBB44_4
5720; X86-BMI1NOTBM-NEXT:  # %bb.3:
5721; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
5722; X86-BMI1NOTBM-NEXT:  .LBB44_4:
5723; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
5724; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5725; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5726; X86-BMI1NOTBM-NEXT:    movl $0, %edx
5727; X86-BMI1NOTBM-NEXT:    jne .LBB44_6
5728; X86-BMI1NOTBM-NEXT:  # %bb.5:
5729; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5730; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
5731; X86-BMI1NOTBM-NEXT:  .LBB44_6:
5732; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
5733; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5734; X86-BMI1NOTBM-NEXT:    jne .LBB44_8
5735; X86-BMI1NOTBM-NEXT:  # %bb.7:
5736; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5737; X86-BMI1NOTBM-NEXT:  .LBB44_8:
5738; X86-BMI1NOTBM-NEXT:    popl %esi
5739; X86-BMI1NOTBM-NEXT:    popl %edi
5740; X86-BMI1NOTBM-NEXT:    popl %ebx
5741; X86-BMI1NOTBM-NEXT:    retl
5742;
5743; X86-BMI1BMI2-LABEL: bextr64_d1_indexzext:
5744; X86-BMI1BMI2:       # %bb.0:
5745; X86-BMI1BMI2-NEXT:    pushl %edi
5746; X86-BMI1BMI2-NEXT:    pushl %esi
5747; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5748; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5749; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
5750; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
5751; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
5752; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
5753; X86-BMI1BMI2-NEXT:    testb $32, %cl
5754; X86-BMI1BMI2-NEXT:    je .LBB44_2
5755; X86-BMI1BMI2-NEXT:  # %bb.1:
5756; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5757; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
5758; X86-BMI1BMI2-NEXT:  .LBB44_2:
5759; X86-BMI1BMI2-NEXT:    movb $64, %cl
5760; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5761; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
5762; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
5763; X86-BMI1BMI2-NEXT:    testb $32, %cl
5764; X86-BMI1BMI2-NEXT:    je .LBB44_4
5765; X86-BMI1BMI2-NEXT:  # %bb.3:
5766; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5767; X86-BMI1BMI2-NEXT:    movl $0, %edi
5768; X86-BMI1BMI2-NEXT:  .LBB44_4:
5769; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
5770; X86-BMI1BMI2-NEXT:    jne .LBB44_6
5771; X86-BMI1BMI2-NEXT:  # %bb.5:
5772; X86-BMI1BMI2-NEXT:    movl %eax, %edx
5773; X86-BMI1BMI2-NEXT:  .LBB44_6:
5774; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
5775; X86-BMI1BMI2-NEXT:    testb $32, %cl
5776; X86-BMI1BMI2-NEXT:    jne .LBB44_8
5777; X86-BMI1BMI2-NEXT:  # %bb.7:
5778; X86-BMI1BMI2-NEXT:    movl %edi, %eax
5779; X86-BMI1BMI2-NEXT:  .LBB44_8:
5780; X86-BMI1BMI2-NEXT:    popl %esi
5781; X86-BMI1BMI2-NEXT:    popl %edi
5782; X86-BMI1BMI2-NEXT:    retl
5783;
5784; X64-NOBMI-LABEL: bextr64_d1_indexzext:
5785; X64-NOBMI:       # %bb.0:
5786; X64-NOBMI-NEXT:    movl %esi, %ecx
5787; X64-NOBMI-NEXT:    movq %rdi, %rax
5788; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5789; X64-NOBMI-NEXT:    shrq %cl, %rax
5790; X64-NOBMI-NEXT:    negb %dl
5791; X64-NOBMI-NEXT:    movl %edx, %ecx
5792; X64-NOBMI-NEXT:    shlq %cl, %rax
5793; X64-NOBMI-NEXT:    shrq %cl, %rax
5794; X64-NOBMI-NEXT:    retq
5795;
5796; X64-BMI1NOTBM-LABEL: bextr64_d1_indexzext:
5797; X64-BMI1NOTBM:       # %bb.0:
5798; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
5799; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
5800; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5801; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
5802; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
5803; X64-BMI1NOTBM-NEXT:    retq
5804;
5805; X64-BMI1BMI2-LABEL: bextr64_d1_indexzext:
5806; X64-BMI1BMI2:       # %bb.0:
5807; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
5808; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
5809; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
5810; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
5811; X64-BMI1BMI2-NEXT:    retq
5812  %skip = zext i8 %numskipbits to i64
5813  %shifted = lshr i64 %val, %skip
5814  %numhighbits = sub i8 64, %numlowbits
5815  %sh_prom = zext i8 %numhighbits to i64
5816  %highbitscleared = shl i64 %shifted, %sh_prom
5817  %masked = lshr i64 %highbitscleared, %sh_prom
5818  ret i64 %masked
5819}
5820
5821define i64 @bextr64_d2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
5822; X86-NOBMI-LABEL: bextr64_d2_load:
5823; X86-NOBMI:       # %bb.0:
5824; X86-NOBMI-NEXT:    pushl %ebx
5825; X86-NOBMI-NEXT:    pushl %edi
5826; X86-NOBMI-NEXT:    pushl %esi
5827; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5828; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5829; X86-NOBMI-NEXT:    movl (%eax), %edi
5830; X86-NOBMI-NEXT:    movl 4(%eax), %edx
5831; X86-NOBMI-NEXT:    movl %edx, %eax
5832; X86-NOBMI-NEXT:    shrl %cl, %eax
5833; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
5834; X86-NOBMI-NEXT:    xorl %esi, %esi
5835; X86-NOBMI-NEXT:    testb $32, %cl
5836; X86-NOBMI-NEXT:    je .LBB45_2
5837; X86-NOBMI-NEXT:  # %bb.1:
5838; X86-NOBMI-NEXT:    movl %eax, %edi
5839; X86-NOBMI-NEXT:    xorl %eax, %eax
5840; X86-NOBMI-NEXT:  .LBB45_2:
5841; X86-NOBMI-NEXT:    movb $64, %cl
5842; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5843; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
5844; X86-NOBMI-NEXT:    shll %cl, %edi
5845; X86-NOBMI-NEXT:    testb $32, %cl
5846; X86-NOBMI-NEXT:    movl %edi, %ebx
5847; X86-NOBMI-NEXT:    jne .LBB45_4
5848; X86-NOBMI-NEXT:  # %bb.3:
5849; X86-NOBMI-NEXT:    movl %eax, %ebx
5850; X86-NOBMI-NEXT:  .LBB45_4:
5851; X86-NOBMI-NEXT:    movl %ebx, %eax
5852; X86-NOBMI-NEXT:    shrl %cl, %eax
5853; X86-NOBMI-NEXT:    testb $32, %cl
5854; X86-NOBMI-NEXT:    movl $0, %edx
5855; X86-NOBMI-NEXT:    jne .LBB45_6
5856; X86-NOBMI-NEXT:  # %bb.5:
5857; X86-NOBMI-NEXT:    movl %edi, %esi
5858; X86-NOBMI-NEXT:    movl %eax, %edx
5859; X86-NOBMI-NEXT:  .LBB45_6:
5860; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
5861; X86-NOBMI-NEXT:    testb $32, %cl
5862; X86-NOBMI-NEXT:    jne .LBB45_8
5863; X86-NOBMI-NEXT:  # %bb.7:
5864; X86-NOBMI-NEXT:    movl %esi, %eax
5865; X86-NOBMI-NEXT:  .LBB45_8:
5866; X86-NOBMI-NEXT:    popl %esi
5867; X86-NOBMI-NEXT:    popl %edi
5868; X86-NOBMI-NEXT:    popl %ebx
5869; X86-NOBMI-NEXT:    retl
5870;
5871; X86-BMI1NOTBM-LABEL: bextr64_d2_load:
5872; X86-BMI1NOTBM:       # %bb.0:
5873; X86-BMI1NOTBM-NEXT:    pushl %ebx
5874; X86-BMI1NOTBM-NEXT:    pushl %edi
5875; X86-BMI1NOTBM-NEXT:    pushl %esi
5876; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5877; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5878; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
5879; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %edx
5880; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
5881; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5882; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
5883; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
5884; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5885; X86-BMI1NOTBM-NEXT:    je .LBB45_2
5886; X86-BMI1NOTBM-NEXT:  # %bb.1:
5887; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5888; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
5889; X86-BMI1NOTBM-NEXT:  .LBB45_2:
5890; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5891; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5892; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
5893; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
5894; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5895; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
5896; X86-BMI1NOTBM-NEXT:    jne .LBB45_4
5897; X86-BMI1NOTBM-NEXT:  # %bb.3:
5898; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
5899; X86-BMI1NOTBM-NEXT:  .LBB45_4:
5900; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
5901; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5902; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5903; X86-BMI1NOTBM-NEXT:    movl $0, %edx
5904; X86-BMI1NOTBM-NEXT:    jne .LBB45_6
5905; X86-BMI1NOTBM-NEXT:  # %bb.5:
5906; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5907; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
5908; X86-BMI1NOTBM-NEXT:  .LBB45_6:
5909; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
5910; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5911; X86-BMI1NOTBM-NEXT:    jne .LBB45_8
5912; X86-BMI1NOTBM-NEXT:  # %bb.7:
5913; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5914; X86-BMI1NOTBM-NEXT:  .LBB45_8:
5915; X86-BMI1NOTBM-NEXT:    popl %esi
5916; X86-BMI1NOTBM-NEXT:    popl %edi
5917; X86-BMI1NOTBM-NEXT:    popl %ebx
5918; X86-BMI1NOTBM-NEXT:    retl
5919;
5920; X86-BMI1BMI2-LABEL: bextr64_d2_load:
5921; X86-BMI1BMI2:       # %bb.0:
5922; X86-BMI1BMI2-NEXT:    pushl %edi
5923; X86-BMI1BMI2-NEXT:    pushl %esi
5924; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5925; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
5926; X86-BMI1BMI2-NEXT:    movl (%edx), %eax
5927; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edx
5928; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
5929; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
5930; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
5931; X86-BMI1BMI2-NEXT:    testb $32, %cl
5932; X86-BMI1BMI2-NEXT:    je .LBB45_2
5933; X86-BMI1BMI2-NEXT:  # %bb.1:
5934; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5935; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
5936; X86-BMI1BMI2-NEXT:  .LBB45_2:
5937; X86-BMI1BMI2-NEXT:    movb $64, %cl
5938; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5939; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
5940; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
5941; X86-BMI1BMI2-NEXT:    testb $32, %cl
5942; X86-BMI1BMI2-NEXT:    je .LBB45_4
5943; X86-BMI1BMI2-NEXT:  # %bb.3:
5944; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5945; X86-BMI1BMI2-NEXT:    movl $0, %edi
5946; X86-BMI1BMI2-NEXT:  .LBB45_4:
5947; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
5948; X86-BMI1BMI2-NEXT:    jne .LBB45_6
5949; X86-BMI1BMI2-NEXT:  # %bb.5:
5950; X86-BMI1BMI2-NEXT:    movl %eax, %edx
5951; X86-BMI1BMI2-NEXT:  .LBB45_6:
5952; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
5953; X86-BMI1BMI2-NEXT:    testb $32, %cl
5954; X86-BMI1BMI2-NEXT:    jne .LBB45_8
5955; X86-BMI1BMI2-NEXT:  # %bb.7:
5956; X86-BMI1BMI2-NEXT:    movl %edi, %eax
5957; X86-BMI1BMI2-NEXT:  .LBB45_8:
5958; X86-BMI1BMI2-NEXT:    popl %esi
5959; X86-BMI1BMI2-NEXT:    popl %edi
5960; X86-BMI1BMI2-NEXT:    retl
5961;
5962; X64-NOBMI-LABEL: bextr64_d2_load:
5963; X64-NOBMI:       # %bb.0:
5964; X64-NOBMI-NEXT:    movq %rsi, %rcx
5965; X64-NOBMI-NEXT:    movq (%rdi), %rax
5966; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5967; X64-NOBMI-NEXT:    shrq %cl, %rax
5968; X64-NOBMI-NEXT:    negb %dl
5969; X64-NOBMI-NEXT:    movl %edx, %ecx
5970; X64-NOBMI-NEXT:    shlq %cl, %rax
5971; X64-NOBMI-NEXT:    shrq %cl, %rax
5972; X64-NOBMI-NEXT:    retq
5973;
5974; X64-BMI1NOTBM-LABEL: bextr64_d2_load:
5975; X64-BMI1NOTBM:       # %bb.0:
5976; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
5977; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
5978; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
5979; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
5980; X64-BMI1NOTBM-NEXT:    retq
5981;
5982; X64-BMI1BMI2-LABEL: bextr64_d2_load:
5983; X64-BMI1BMI2:       # %bb.0:
5984; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
5985; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
5986; X64-BMI1BMI2-NEXT:    retq
5987  %val = load i64, i64* %w
5988  %shifted = lshr i64 %val, %numskipbits
5989  %numhighbits = sub i64 64, %numlowbits
5990  %highbitscleared = shl i64 %shifted, %numhighbits
5991  %masked = lshr i64 %highbitscleared, %numhighbits
5992  ret i64 %masked
5993}
5994
5995define i64 @bextr64_d3_load_indexzext(i64* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
5996; X86-NOBMI-LABEL: bextr64_d3_load_indexzext:
5997; X86-NOBMI:       # %bb.0:
5998; X86-NOBMI-NEXT:    pushl %ebx
5999; X86-NOBMI-NEXT:    pushl %edi
6000; X86-NOBMI-NEXT:    pushl %esi
6001; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6002; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6003; X86-NOBMI-NEXT:    movl (%eax), %edi
6004; X86-NOBMI-NEXT:    movl 4(%eax), %edx
6005; X86-NOBMI-NEXT:    movl %edx, %eax
6006; X86-NOBMI-NEXT:    shrl %cl, %eax
6007; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
6008; X86-NOBMI-NEXT:    xorl %esi, %esi
6009; X86-NOBMI-NEXT:    testb $32, %cl
6010; X86-NOBMI-NEXT:    je .LBB46_2
6011; X86-NOBMI-NEXT:  # %bb.1:
6012; X86-NOBMI-NEXT:    movl %eax, %edi
6013; X86-NOBMI-NEXT:    xorl %eax, %eax
6014; X86-NOBMI-NEXT:  .LBB46_2:
6015; X86-NOBMI-NEXT:    movb $64, %cl
6016; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6017; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
6018; X86-NOBMI-NEXT:    shll %cl, %edi
6019; X86-NOBMI-NEXT:    testb $32, %cl
6020; X86-NOBMI-NEXT:    movl %edi, %ebx
6021; X86-NOBMI-NEXT:    jne .LBB46_4
6022; X86-NOBMI-NEXT:  # %bb.3:
6023; X86-NOBMI-NEXT:    movl %eax, %ebx
6024; X86-NOBMI-NEXT:  .LBB46_4:
6025; X86-NOBMI-NEXT:    movl %ebx, %eax
6026; X86-NOBMI-NEXT:    shrl %cl, %eax
6027; X86-NOBMI-NEXT:    testb $32, %cl
6028; X86-NOBMI-NEXT:    movl $0, %edx
6029; X86-NOBMI-NEXT:    jne .LBB46_6
6030; X86-NOBMI-NEXT:  # %bb.5:
6031; X86-NOBMI-NEXT:    movl %edi, %esi
6032; X86-NOBMI-NEXT:    movl %eax, %edx
6033; X86-NOBMI-NEXT:  .LBB46_6:
6034; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
6035; X86-NOBMI-NEXT:    testb $32, %cl
6036; X86-NOBMI-NEXT:    jne .LBB46_8
6037; X86-NOBMI-NEXT:  # %bb.7:
6038; X86-NOBMI-NEXT:    movl %esi, %eax
6039; X86-NOBMI-NEXT:  .LBB46_8:
6040; X86-NOBMI-NEXT:    popl %esi
6041; X86-NOBMI-NEXT:    popl %edi
6042; X86-NOBMI-NEXT:    popl %ebx
6043; X86-NOBMI-NEXT:    retl
6044;
6045; X86-BMI1NOTBM-LABEL: bextr64_d3_load_indexzext:
6046; X86-BMI1NOTBM:       # %bb.0:
6047; X86-BMI1NOTBM-NEXT:    pushl %ebx
6048; X86-BMI1NOTBM-NEXT:    pushl %edi
6049; X86-BMI1NOTBM-NEXT:    pushl %esi
6050; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6051; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6052; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
6053; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %edx
6054; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
6055; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6056; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
6057; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
6058; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6059; X86-BMI1NOTBM-NEXT:    je .LBB46_2
6060; X86-BMI1NOTBM-NEXT:  # %bb.1:
6061; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
6062; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
6063; X86-BMI1NOTBM-NEXT:  .LBB46_2:
6064; X86-BMI1NOTBM-NEXT:    movb $64, %cl
6065; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
6066; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
6067; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
6068; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6069; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
6070; X86-BMI1NOTBM-NEXT:    jne .LBB46_4
6071; X86-BMI1NOTBM-NEXT:  # %bb.3:
6072; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
6073; X86-BMI1NOTBM-NEXT:  .LBB46_4:
6074; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
6075; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6076; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6077; X86-BMI1NOTBM-NEXT:    movl $0, %edx
6078; X86-BMI1NOTBM-NEXT:    jne .LBB46_6
6079; X86-BMI1NOTBM-NEXT:  # %bb.5:
6080; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
6081; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
6082; X86-BMI1NOTBM-NEXT:  .LBB46_6:
6083; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
6084; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6085; X86-BMI1NOTBM-NEXT:    jne .LBB46_8
6086; X86-BMI1NOTBM-NEXT:  # %bb.7:
6087; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6088; X86-BMI1NOTBM-NEXT:  .LBB46_8:
6089; X86-BMI1NOTBM-NEXT:    popl %esi
6090; X86-BMI1NOTBM-NEXT:    popl %edi
6091; X86-BMI1NOTBM-NEXT:    popl %ebx
6092; X86-BMI1NOTBM-NEXT:    retl
6093;
6094; X86-BMI1BMI2-LABEL: bextr64_d3_load_indexzext:
6095; X86-BMI1BMI2:       # %bb.0:
6096; X86-BMI1BMI2-NEXT:    pushl %edi
6097; X86-BMI1BMI2-NEXT:    pushl %esi
6098; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6099; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6100; X86-BMI1BMI2-NEXT:    movl (%edx), %eax
6101; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edx
6102; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
6103; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
6104; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
6105; X86-BMI1BMI2-NEXT:    testb $32, %cl
6106; X86-BMI1BMI2-NEXT:    je .LBB46_2
6107; X86-BMI1BMI2-NEXT:  # %bb.1:
6108; X86-BMI1BMI2-NEXT:    movl %esi, %eax
6109; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
6110; X86-BMI1BMI2-NEXT:  .LBB46_2:
6111; X86-BMI1BMI2-NEXT:    movb $64, %cl
6112; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6113; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
6114; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
6115; X86-BMI1BMI2-NEXT:    testb $32, %cl
6116; X86-BMI1BMI2-NEXT:    je .LBB46_4
6117; X86-BMI1BMI2-NEXT:  # %bb.3:
6118; X86-BMI1BMI2-NEXT:    movl %edi, %esi
6119; X86-BMI1BMI2-NEXT:    movl $0, %edi
6120; X86-BMI1BMI2-NEXT:  .LBB46_4:
6121; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
6122; X86-BMI1BMI2-NEXT:    jne .LBB46_6
6123; X86-BMI1BMI2-NEXT:  # %bb.5:
6124; X86-BMI1BMI2-NEXT:    movl %eax, %edx
6125; X86-BMI1BMI2-NEXT:  .LBB46_6:
6126; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
6127; X86-BMI1BMI2-NEXT:    testb $32, %cl
6128; X86-BMI1BMI2-NEXT:    jne .LBB46_8
6129; X86-BMI1BMI2-NEXT:  # %bb.7:
6130; X86-BMI1BMI2-NEXT:    movl %edi, %eax
6131; X86-BMI1BMI2-NEXT:  .LBB46_8:
6132; X86-BMI1BMI2-NEXT:    popl %esi
6133; X86-BMI1BMI2-NEXT:    popl %edi
6134; X86-BMI1BMI2-NEXT:    retl
6135;
6136; X64-NOBMI-LABEL: bextr64_d3_load_indexzext:
6137; X64-NOBMI:       # %bb.0:
6138; X64-NOBMI-NEXT:    movl %esi, %ecx
6139; X64-NOBMI-NEXT:    movq (%rdi), %rax
6140; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6141; X64-NOBMI-NEXT:    shrq %cl, %rax
6142; X64-NOBMI-NEXT:    negb %dl
6143; X64-NOBMI-NEXT:    movl %edx, %ecx
6144; X64-NOBMI-NEXT:    shlq %cl, %rax
6145; X64-NOBMI-NEXT:    shrq %cl, %rax
6146; X64-NOBMI-NEXT:    retq
6147;
6148; X64-BMI1NOTBM-LABEL: bextr64_d3_load_indexzext:
6149; X64-BMI1NOTBM:       # %bb.0:
6150; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
6151; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
6152; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6153; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
6154; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
6155; X64-BMI1NOTBM-NEXT:    retq
6156;
6157; X64-BMI1BMI2-LABEL: bextr64_d3_load_indexzext:
6158; X64-BMI1BMI2:       # %bb.0:
6159; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
6160; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
6161; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
6162; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
6163; X64-BMI1BMI2-NEXT:    retq
6164  %val = load i64, i64* %w
6165  %skip = zext i8 %numskipbits to i64
6166  %shifted = lshr i64 %val, %skip
6167  %numhighbits = sub i8 64, %numlowbits
6168  %sh_prom = zext i8 %numhighbits to i64
6169  %highbitscleared = shl i64 %shifted, %sh_prom
6170  %masked = lshr i64 %highbitscleared, %sh_prom
6171  ret i64 %masked
6172}
6173
6174define i64 @bextr64_d5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
6175; X86-NOBMI-LABEL: bextr64_d5_skipextrauses:
6176; X86-NOBMI:       # %bb.0:
6177; X86-NOBMI-NEXT:    pushl %ebp
6178; X86-NOBMI-NEXT:    pushl %ebx
6179; X86-NOBMI-NEXT:    pushl %edi
6180; X86-NOBMI-NEXT:    pushl %esi
6181; X86-NOBMI-NEXT:    subl $12, %esp
6182; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
6183; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6184; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6185; X86-NOBMI-NEXT:    movl %edx, %esi
6186; X86-NOBMI-NEXT:    movl %eax, %ecx
6187; X86-NOBMI-NEXT:    shrl %cl, %esi
6188; X86-NOBMI-NEXT:    shrdl %cl, %edx, %ebx
6189; X86-NOBMI-NEXT:    xorl %edx, %edx
6190; X86-NOBMI-NEXT:    testb $32, %al
6191; X86-NOBMI-NEXT:    je .LBB47_2
6192; X86-NOBMI-NEXT:  # %bb.1:
6193; X86-NOBMI-NEXT:    movl %esi, %ebx
6194; X86-NOBMI-NEXT:    xorl %esi, %esi
6195; X86-NOBMI-NEXT:  .LBB47_2:
6196; X86-NOBMI-NEXT:    movb $64, %cl
6197; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6198; X86-NOBMI-NEXT:    shldl %cl, %ebx, %esi
6199; X86-NOBMI-NEXT:    shll %cl, %ebx
6200; X86-NOBMI-NEXT:    testb $32, %cl
6201; X86-NOBMI-NEXT:    movl %ebx, %ebp
6202; X86-NOBMI-NEXT:    jne .LBB47_4
6203; X86-NOBMI-NEXT:  # %bb.3:
6204; X86-NOBMI-NEXT:    movl %esi, %ebp
6205; X86-NOBMI-NEXT:  .LBB47_4:
6206; X86-NOBMI-NEXT:    movl %ebp, %esi
6207; X86-NOBMI-NEXT:    shrl %cl, %esi
6208; X86-NOBMI-NEXT:    testb $32, %cl
6209; X86-NOBMI-NEXT:    movl $0, %edi
6210; X86-NOBMI-NEXT:    jne .LBB47_6
6211; X86-NOBMI-NEXT:  # %bb.5:
6212; X86-NOBMI-NEXT:    movl %ebx, %edx
6213; X86-NOBMI-NEXT:    movl %esi, %edi
6214; X86-NOBMI-NEXT:  .LBB47_6:
6215; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %edx
6216; X86-NOBMI-NEXT:    testb $32, %cl
6217; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6218; X86-NOBMI-NEXT:    jne .LBB47_8
6219; X86-NOBMI-NEXT:  # %bb.7:
6220; X86-NOBMI-NEXT:    movl %edx, %esi
6221; X86-NOBMI-NEXT:  .LBB47_8:
6222; X86-NOBMI-NEXT:    subl $8, %esp
6223; X86-NOBMI-NEXT:    pushl %ecx
6224; X86-NOBMI-NEXT:    pushl %eax
6225; X86-NOBMI-NEXT:    calll use64
6226; X86-NOBMI-NEXT:    addl $16, %esp
6227; X86-NOBMI-NEXT:    movl %esi, %eax
6228; X86-NOBMI-NEXT:    movl %edi, %edx
6229; X86-NOBMI-NEXT:    addl $12, %esp
6230; X86-NOBMI-NEXT:    popl %esi
6231; X86-NOBMI-NEXT:    popl %edi
6232; X86-NOBMI-NEXT:    popl %ebx
6233; X86-NOBMI-NEXT:    popl %ebp
6234; X86-NOBMI-NEXT:    retl
6235;
6236; X86-BMI1NOTBM-LABEL: bextr64_d5_skipextrauses:
6237; X86-BMI1NOTBM:       # %bb.0:
6238; X86-BMI1NOTBM-NEXT:    pushl %ebp
6239; X86-BMI1NOTBM-NEXT:    pushl %ebx
6240; X86-BMI1NOTBM-NEXT:    pushl %edi
6241; X86-BMI1NOTBM-NEXT:    pushl %esi
6242; X86-BMI1NOTBM-NEXT:    subl $12, %esp
6243; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
6244; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
6245; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6246; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
6247; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
6248; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
6249; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %ebx
6250; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
6251; X86-BMI1NOTBM-NEXT:    testb $32, %al
6252; X86-BMI1NOTBM-NEXT:    je .LBB47_2
6253; X86-BMI1NOTBM-NEXT:  # %bb.1:
6254; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
6255; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
6256; X86-BMI1NOTBM-NEXT:  .LBB47_2:
6257; X86-BMI1NOTBM-NEXT:    movb $64, %cl
6258; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
6259; X86-BMI1NOTBM-NEXT:    shldl %cl, %ebx, %esi
6260; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
6261; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6262; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
6263; X86-BMI1NOTBM-NEXT:    jne .LBB47_4
6264; X86-BMI1NOTBM-NEXT:  # %bb.3:
6265; X86-BMI1NOTBM-NEXT:    movl %esi, %ebp
6266; X86-BMI1NOTBM-NEXT:  .LBB47_4:
6267; X86-BMI1NOTBM-NEXT:    movl %ebp, %esi
6268; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
6269; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6270; X86-BMI1NOTBM-NEXT:    movl $0, %edi
6271; X86-BMI1NOTBM-NEXT:    jne .LBB47_6
6272; X86-BMI1NOTBM-NEXT:  # %bb.5:
6273; X86-BMI1NOTBM-NEXT:    movl %ebx, %edx
6274; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
6275; X86-BMI1NOTBM-NEXT:  .LBB47_6:
6276; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %edx
6277; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6278; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6279; X86-BMI1NOTBM-NEXT:    jne .LBB47_8
6280; X86-BMI1NOTBM-NEXT:  # %bb.7:
6281; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
6282; X86-BMI1NOTBM-NEXT:  .LBB47_8:
6283; X86-BMI1NOTBM-NEXT:    subl $8, %esp
6284; X86-BMI1NOTBM-NEXT:    pushl %ecx
6285; X86-BMI1NOTBM-NEXT:    pushl %eax
6286; X86-BMI1NOTBM-NEXT:    calll use64
6287; X86-BMI1NOTBM-NEXT:    addl $16, %esp
6288; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6289; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
6290; X86-BMI1NOTBM-NEXT:    addl $12, %esp
6291; X86-BMI1NOTBM-NEXT:    popl %esi
6292; X86-BMI1NOTBM-NEXT:    popl %edi
6293; X86-BMI1NOTBM-NEXT:    popl %ebx
6294; X86-BMI1NOTBM-NEXT:    popl %ebp
6295; X86-BMI1NOTBM-NEXT:    retl
6296;
6297; X86-BMI1BMI2-LABEL: bextr64_d5_skipextrauses:
6298; X86-BMI1BMI2:       # %bb.0:
6299; X86-BMI1BMI2-NEXT:    pushl %ebx
6300; X86-BMI1BMI2-NEXT:    pushl %edi
6301; X86-BMI1BMI2-NEXT:    pushl %esi
6302; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
6303; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6304; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6305; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
6306; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %edi
6307; X86-BMI1BMI2-NEXT:    shrxl %eax, %edx, %edx
6308; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
6309; X86-BMI1BMI2-NEXT:    testb $32, %al
6310; X86-BMI1BMI2-NEXT:    je .LBB47_2
6311; X86-BMI1BMI2-NEXT:  # %bb.1:
6312; X86-BMI1BMI2-NEXT:    movl %edx, %edi
6313; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
6314; X86-BMI1BMI2-NEXT:  .LBB47_2:
6315; X86-BMI1BMI2-NEXT:    movb $64, %cl
6316; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6317; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edx
6318; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edi, %ebx
6319; X86-BMI1BMI2-NEXT:    testb $32, %cl
6320; X86-BMI1BMI2-NEXT:    je .LBB47_4
6321; X86-BMI1BMI2-NEXT:  # %bb.3:
6322; X86-BMI1BMI2-NEXT:    movl %ebx, %edx
6323; X86-BMI1BMI2-NEXT:    movl $0, %ebx
6324; X86-BMI1BMI2-NEXT:  .LBB47_4:
6325; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edi
6326; X86-BMI1BMI2-NEXT:    jne .LBB47_6
6327; X86-BMI1BMI2-NEXT:  # %bb.5:
6328; X86-BMI1BMI2-NEXT:    movl %edi, %esi
6329; X86-BMI1BMI2-NEXT:  .LBB47_6:
6330; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %ebx
6331; X86-BMI1BMI2-NEXT:    testb $32, %cl
6332; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6333; X86-BMI1BMI2-NEXT:    jne .LBB47_8
6334; X86-BMI1BMI2-NEXT:  # %bb.7:
6335; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
6336; X86-BMI1BMI2-NEXT:  .LBB47_8:
6337; X86-BMI1BMI2-NEXT:    subl $8, %esp
6338; X86-BMI1BMI2-NEXT:    pushl %ecx
6339; X86-BMI1BMI2-NEXT:    pushl %eax
6340; X86-BMI1BMI2-NEXT:    calll use64
6341; X86-BMI1BMI2-NEXT:    addl $16, %esp
6342; X86-BMI1BMI2-NEXT:    movl %edi, %eax
6343; X86-BMI1BMI2-NEXT:    movl %esi, %edx
6344; X86-BMI1BMI2-NEXT:    popl %esi
6345; X86-BMI1BMI2-NEXT:    popl %edi
6346; X86-BMI1BMI2-NEXT:    popl %ebx
6347; X86-BMI1BMI2-NEXT:    retl
6348;
6349; X64-NOBMI-LABEL: bextr64_d5_skipextrauses:
6350; X64-NOBMI:       # %bb.0:
6351; X64-NOBMI-NEXT:    pushq %rbx
6352; X64-NOBMI-NEXT:    movq %rdi, %rbx
6353; X64-NOBMI-NEXT:    movl %esi, %ecx
6354; X64-NOBMI-NEXT:    shrq %cl, %rbx
6355; X64-NOBMI-NEXT:    negb %dl
6356; X64-NOBMI-NEXT:    movl %edx, %ecx
6357; X64-NOBMI-NEXT:    shlq %cl, %rbx
6358; X64-NOBMI-NEXT:    shrq %cl, %rbx
6359; X64-NOBMI-NEXT:    movq %rsi, %rdi
6360; X64-NOBMI-NEXT:    callq use64
6361; X64-NOBMI-NEXT:    movq %rbx, %rax
6362; X64-NOBMI-NEXT:    popq %rbx
6363; X64-NOBMI-NEXT:    retq
6364;
6365; X64-BMI1NOTBM-LABEL: bextr64_d5_skipextrauses:
6366; X64-BMI1NOTBM:       # %bb.0:
6367; X64-BMI1NOTBM-NEXT:    pushq %rbx
6368; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
6369; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6370; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
6371; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rbx
6372; X64-BMI1NOTBM-NEXT:    movq %rsi, %rdi
6373; X64-BMI1NOTBM-NEXT:    callq use64
6374; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
6375; X64-BMI1NOTBM-NEXT:    popq %rbx
6376; X64-BMI1NOTBM-NEXT:    retq
6377;
6378; X64-BMI1BMI2-LABEL: bextr64_d5_skipextrauses:
6379; X64-BMI1BMI2:       # %bb.0:
6380; X64-BMI1BMI2-NEXT:    pushq %rbx
6381; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6382; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
6383; X64-BMI1BMI2-NEXT:    movq %rsi, %rdi
6384; X64-BMI1BMI2-NEXT:    callq use64
6385; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
6386; X64-BMI1BMI2-NEXT:    popq %rbx
6387; X64-BMI1BMI2-NEXT:    retq
6388  %shifted = lshr i64 %val, %numskipbits
6389  %numhighbits = sub i64 64, %numlowbits
6390  %highbitscleared = shl i64 %shifted, %numhighbits
6391  %masked = lshr i64 %highbitscleared, %numhighbits
6392  call void @use64(i64 %numskipbits)
6393  ret i64 %masked
6394}
6395
6396; ---------------------------------------------------------------------------- ;
6397; Constant
6398; ---------------------------------------------------------------------------- ;
6399
6400; https://bugs.llvm.org/show_bug.cgi?id=38938
6401define void @pr38938(i32* %a0, i64* %a1) {
6402; X86-NOBMI-LABEL: pr38938:
6403; X86-NOBMI:       # %bb.0:
6404; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6405; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6406; X86-NOBMI-NEXT:    movl (%ecx), %ecx
6407; X86-NOBMI-NEXT:    shrl $19, %ecx
6408; X86-NOBMI-NEXT:    andl $4092, %ecx # imm = 0xFFC
6409; X86-NOBMI-NEXT:    incl (%eax,%ecx)
6410; X86-NOBMI-NEXT:    retl
6411;
6412; X86-BMI1NOTBM-LABEL: pr38938:
6413; X86-BMI1NOTBM:       # %bb.0:
6414; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6415; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6416; X86-BMI1NOTBM-NEXT:    movl $2581, %edx # imm = 0xA15
6417; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%ecx), %ecx
6418; X86-BMI1NOTBM-NEXT:    incl (%eax,%ecx,4)
6419; X86-BMI1NOTBM-NEXT:    retl
6420;
6421; X86-BMI1TBM-LABEL: pr38938:
6422; X86-BMI1TBM:       # %bb.0:
6423; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6424; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6425; X86-BMI1TBM-NEXT:    bextrl $2581, (%ecx), %ecx # imm = 0xA15
6426; X86-BMI1TBM-NEXT:    incl (%eax,%ecx,4)
6427; X86-BMI1TBM-NEXT:    retl
6428;
6429; X86-BMI1NOTBMBMI2-LABEL: pr38938:
6430; X86-BMI1NOTBMBMI2:       # %bb.0:
6431; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6432; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6433; X86-BMI1NOTBMBMI2-NEXT:    movl $2581, %edx # imm = 0xA15
6434; X86-BMI1NOTBMBMI2-NEXT:    bextrl %edx, (%ecx), %ecx
6435; X86-BMI1NOTBMBMI2-NEXT:    incl (%eax,%ecx,4)
6436; X86-BMI1NOTBMBMI2-NEXT:    retl
6437;
6438; X64-NOBMI-LABEL: pr38938:
6439; X64-NOBMI:       # %bb.0:
6440; X64-NOBMI-NEXT:    movq (%rsi), %rax
6441; X64-NOBMI-NEXT:    shrq $19, %rax
6442; X64-NOBMI-NEXT:    andl $4092, %eax # imm = 0xFFC
6443; X64-NOBMI-NEXT:    incl (%rdi,%rax)
6444; X64-NOBMI-NEXT:    retq
6445;
6446; X64-BMI1NOTBM-LABEL: pr38938:
6447; X64-BMI1NOTBM:       # %bb.0:
6448; X64-BMI1NOTBM-NEXT:    movl $2581, %eax # imm = 0xA15
6449; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rsi), %rax
6450; X64-BMI1NOTBM-NEXT:    incl (%rdi,%rax,4)
6451; X64-BMI1NOTBM-NEXT:    retq
6452;
6453; X64-BMI1TBM-LABEL: pr38938:
6454; X64-BMI1TBM:       # %bb.0:
6455; X64-BMI1TBM-NEXT:    bextrq $2581, (%rsi), %rax # imm = 0xA15
6456; X64-BMI1TBM-NEXT:    incl (%rdi,%rax,4)
6457; X64-BMI1TBM-NEXT:    retq
6458;
6459; X64-BMI1NOTBMBMI2-LABEL: pr38938:
6460; X64-BMI1NOTBMBMI2:       # %bb.0:
6461; X64-BMI1NOTBMBMI2-NEXT:    movl $2581, %eax # imm = 0xA15
6462; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, (%rsi), %rax
6463; X64-BMI1NOTBMBMI2-NEXT:    incl (%rdi,%rax,4)
6464; X64-BMI1NOTBMBMI2-NEXT:    retq
6465  %tmp = load i64, i64* %a1, align 8
6466  %tmp1 = lshr i64 %tmp, 21
6467  %tmp2 = and i64 %tmp1, 1023
6468  %tmp3 = getelementptr inbounds i32, i32* %a0, i64 %tmp2
6469  %tmp4 = load i32, i32* %tmp3, align 4
6470  %tmp5 = add nsw i32 %tmp4, 1
6471  store i32 %tmp5, i32* %tmp3, align 4
6472  ret void
6473}
6474
6475; The most canonical variant
6476define i32 @c0_i32(i32 %arg) {
6477; X86-NOBMI-LABEL: c0_i32:
6478; X86-NOBMI:       # %bb.0:
6479; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6480; X86-NOBMI-NEXT:    shrl $19, %eax
6481; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
6482; X86-NOBMI-NEXT:    retl
6483;
6484; X86-BMI1NOTBM-LABEL: c0_i32:
6485; X86-BMI1NOTBM:       # %bb.0:
6486; X86-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
6487; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
6488; X86-BMI1NOTBM-NEXT:    retl
6489;
6490; X86-BMI1TBM-LABEL: c0_i32:
6491; X86-BMI1TBM:       # %bb.0:
6492; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
6493; X86-BMI1TBM-NEXT:    retl
6494;
6495; X86-BMI1NOTBMBMI2-LABEL: c0_i32:
6496; X86-BMI1NOTBMBMI2:       # %bb.0:
6497; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
6498; X86-BMI1NOTBMBMI2-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
6499; X86-BMI1NOTBMBMI2-NEXT:    retl
6500;
6501; X64-NOBMI-LABEL: c0_i32:
6502; X64-NOBMI:       # %bb.0:
6503; X64-NOBMI-NEXT:    movl %edi, %eax
6504; X64-NOBMI-NEXT:    shrl $19, %eax
6505; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
6506; X64-NOBMI-NEXT:    retq
6507;
6508; X64-BMI1NOTBM-LABEL: c0_i32:
6509; X64-BMI1NOTBM:       # %bb.0:
6510; X64-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
6511; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
6512; X64-BMI1NOTBM-NEXT:    retq
6513;
6514; X64-BMI1TBM-LABEL: c0_i32:
6515; X64-BMI1TBM:       # %bb.0:
6516; X64-BMI1TBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
6517; X64-BMI1TBM-NEXT:    retq
6518;
6519; X64-BMI1NOTBMBMI2-LABEL: c0_i32:
6520; X64-BMI1NOTBMBMI2:       # %bb.0:
6521; X64-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
6522; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
6523; X64-BMI1NOTBMBMI2-NEXT:    retq
6524  %tmp0 = lshr i32 %arg, 19
6525  %tmp1 = and i32 %tmp0, 1023
6526  ret i32 %tmp1
6527}
6528
6529; Should be still fine, but the mask is shifted
6530define i32 @c1_i32(i32 %arg) {
6531; X86-LABEL: c1_i32:
6532; X86:       # %bb.0:
6533; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6534; X86-NEXT:    shrl $19, %eax
6535; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
6536; X86-NEXT:    retl
6537;
6538; X64-LABEL: c1_i32:
6539; X64:       # %bb.0:
6540; X64-NEXT:    movl %edi, %eax
6541; X64-NEXT:    shrl $19, %eax
6542; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
6543; X64-NEXT:    retq
6544  %tmp0 = lshr i32 %arg, 19
6545  %tmp1 = and i32 %tmp0, 4092
6546  ret i32 %tmp1
6547}
6548
6549; Should be still fine, but the result is shifted left afterwards
6550define i32 @c2_i32(i32 %arg) {
6551; X86-LABEL: c2_i32:
6552; X86:       # %bb.0:
6553; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6554; X86-NEXT:    shrl $17, %eax
6555; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
6556; X86-NEXT:    retl
6557;
6558; X64-LABEL: c2_i32:
6559; X64:       # %bb.0:
6560; X64-NEXT:    movl %edi, %eax
6561; X64-NEXT:    shrl $17, %eax
6562; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
6563; X64-NEXT:    retq
6564  %tmp0 = lshr i32 %arg, 19
6565  %tmp1 = and i32 %tmp0, 1023
6566  %tmp2 = shl i32 %tmp1, 2
6567  ret i32 %tmp2
6568}
6569
6570; The mask covers newly shifted-in bit
6571define i32 @c4_i32_bad(i32 %arg) {
6572; X86-LABEL: c4_i32_bad:
6573; X86:       # %bb.0:
6574; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6575; X86-NEXT:    shrl $19, %eax
6576; X86-NEXT:    andl $-2, %eax
6577; X86-NEXT:    retl
6578;
6579; X64-LABEL: c4_i32_bad:
6580; X64:       # %bb.0:
6581; X64-NEXT:    movl %edi, %eax
6582; X64-NEXT:    shrl $19, %eax
6583; X64-NEXT:    andl $-2, %eax
6584; X64-NEXT:    retq
6585  %tmp0 = lshr i32 %arg, 19
6586  %tmp1 = and i32 %tmp0, 16382
6587  ret i32 %tmp1
6588}
6589
6590; i64
6591
6592; The most canonical variant
6593define i64 @c0_i64(i64 %arg) {
6594; X86-NOBMI-LABEL: c0_i64:
6595; X86-NOBMI:       # %bb.0:
6596; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6597; X86-NOBMI-NEXT:    shrl $19, %eax
6598; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
6599; X86-NOBMI-NEXT:    xorl %edx, %edx
6600; X86-NOBMI-NEXT:    retl
6601;
6602; X86-BMI1NOTBM-LABEL: c0_i64:
6603; X86-BMI1NOTBM:       # %bb.0:
6604; X86-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
6605; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
6606; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
6607; X86-BMI1NOTBM-NEXT:    retl
6608;
6609; X86-BMI1TBM-LABEL: c0_i64:
6610; X86-BMI1TBM:       # %bb.0:
6611; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
6612; X86-BMI1TBM-NEXT:    xorl %edx, %edx
6613; X86-BMI1TBM-NEXT:    retl
6614;
6615; X86-BMI1NOTBMBMI2-LABEL: c0_i64:
6616; X86-BMI1NOTBMBMI2:       # %bb.0:
6617; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
6618; X86-BMI1NOTBMBMI2-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
6619; X86-BMI1NOTBMBMI2-NEXT:    xorl %edx, %edx
6620; X86-BMI1NOTBMBMI2-NEXT:    retl
6621;
6622; X64-NOBMI-LABEL: c0_i64:
6623; X64-NOBMI:       # %bb.0:
6624; X64-NOBMI-NEXT:    movq %rdi, %rax
6625; X64-NOBMI-NEXT:    shrq $51, %rax
6626; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
6627; X64-NOBMI-NEXT:    retq
6628;
6629; X64-BMI1NOTBM-LABEL: c0_i64:
6630; X64-BMI1NOTBM:       # %bb.0:
6631; X64-BMI1NOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
6632; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
6633; X64-BMI1NOTBM-NEXT:    retq
6634;
6635; X64-BMI1TBM-LABEL: c0_i64:
6636; X64-BMI1TBM:       # %bb.0:
6637; X64-BMI1TBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
6638; X64-BMI1TBM-NEXT:    retq
6639;
6640; X64-BMI1NOTBMBMI2-LABEL: c0_i64:
6641; X64-BMI1NOTBMBMI2:       # %bb.0:
6642; X64-BMI1NOTBMBMI2-NEXT:    movl $2611, %eax # imm = 0xA33
6643; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
6644; X64-BMI1NOTBMBMI2-NEXT:    retq
6645  %tmp0 = lshr i64 %arg, 51
6646  %tmp1 = and i64 %tmp0, 1023
6647  ret i64 %tmp1
6648}
6649
6650; Should be still fine, but the mask is shifted
6651define i64 @c1_i64(i64 %arg) {
6652; X86-LABEL: c1_i64:
6653; X86:       # %bb.0:
6654; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6655; X86-NEXT:    shrl $19, %eax
6656; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
6657; X86-NEXT:    xorl %edx, %edx
6658; X86-NEXT:    retl
6659;
6660; X64-LABEL: c1_i64:
6661; X64:       # %bb.0:
6662; X64-NEXT:    movq %rdi, %rax
6663; X64-NEXT:    shrq $51, %rax
6664; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
6665; X64-NEXT:    retq
6666  %tmp0 = lshr i64 %arg, 51
6667  %tmp1 = and i64 %tmp0, 4092
6668  ret i64 %tmp1
6669}
6670
6671; Should be still fine, but the result is shifted left afterwards
6672define i64 @c2_i64(i64 %arg) {
6673; X86-LABEL: c2_i64:
6674; X86:       # %bb.0:
6675; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6676; X86-NEXT:    shrl $17, %eax
6677; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
6678; X86-NEXT:    xorl %edx, %edx
6679; X86-NEXT:    retl
6680;
6681; X64-LABEL: c2_i64:
6682; X64:       # %bb.0:
6683; X64-NEXT:    movq %rdi, %rax
6684; X64-NEXT:    shrq $49, %rax
6685; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
6686; X64-NEXT:    retq
6687  %tmp0 = lshr i64 %arg, 51
6688  %tmp1 = and i64 %tmp0, 1023
6689  %tmp2 = shl i64 %tmp1, 2
6690  ret i64 %tmp2
6691}
6692
6693; The mask covers newly shifted-in bit
6694define i64 @c4_i64_bad(i64 %arg) {
6695; X86-LABEL: c4_i64_bad:
6696; X86:       # %bb.0:
6697; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6698; X86-NEXT:    shrl $19, %eax
6699; X86-NEXT:    andl $-2, %eax
6700; X86-NEXT:    xorl %edx, %edx
6701; X86-NEXT:    retl
6702;
6703; X64-LABEL: c4_i64_bad:
6704; X64:       # %bb.0:
6705; X64-NEXT:    movq %rdi, %rax
6706; X64-NEXT:    shrq $51, %rax
6707; X64-NEXT:    andl $-2, %eax
6708; X64-NEXT:    retq
6709  %tmp0 = lshr i64 %arg, 51
6710  %tmp1 = and i64 %tmp0, 16382
6711  ret i64 %tmp1
6712}
6713
6714; ---------------------------------------------------------------------------- ;
6715; Constant, storing the result afterwards.
6716; ---------------------------------------------------------------------------- ;
6717
6718; i32
6719
6720; The most canonical variant
6721define void @c5_i32(i32 %arg, i32* %ptr) {
6722; X86-NOBMI-LABEL: c5_i32:
6723; X86-NOBMI:       # %bb.0:
6724; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6725; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6726; X86-NOBMI-NEXT:    shrl $19, %ecx
6727; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
6728; X86-NOBMI-NEXT:    movl %ecx, (%eax)
6729; X86-NOBMI-NEXT:    retl
6730;
6731; X86-BMI1NOTBM-LABEL: c5_i32:
6732; X86-BMI1NOTBM:       # %bb.0:
6733; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6734; X86-BMI1NOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
6735; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6736; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
6737; X86-BMI1NOTBM-NEXT:    retl
6738;
6739; X86-BMI1TBM-LABEL: c5_i32:
6740; X86-BMI1TBM:       # %bb.0:
6741; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6742; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
6743; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
6744; X86-BMI1TBM-NEXT:    retl
6745;
6746; X86-BMI1NOTBMBMI2-LABEL: c5_i32:
6747; X86-BMI1NOTBMBMI2:       # %bb.0:
6748; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6749; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %ecx # imm = 0xA13
6750; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6751; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
6752; X86-BMI1NOTBMBMI2-NEXT:    retl
6753;
6754; X64-NOBMI-LABEL: c5_i32:
6755; X64-NOBMI:       # %bb.0:
6756; X64-NOBMI-NEXT:    shrl $19, %edi
6757; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
6758; X64-NOBMI-NEXT:    movl %edi, (%rsi)
6759; X64-NOBMI-NEXT:    retq
6760;
6761; X64-BMI1NOTBM-LABEL: c5_i32:
6762; X64-BMI1NOTBM:       # %bb.0:
6763; X64-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
6764; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
6765; X64-BMI1NOTBM-NEXT:    movl %eax, (%rsi)
6766; X64-BMI1NOTBM-NEXT:    retq
6767;
6768; X64-BMI1TBM-LABEL: c5_i32:
6769; X64-BMI1TBM:       # %bb.0:
6770; X64-BMI1TBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
6771; X64-BMI1TBM-NEXT:    movl %eax, (%rsi)
6772; X64-BMI1TBM-NEXT:    retq
6773;
6774; X64-BMI1NOTBMBMI2-LABEL: c5_i32:
6775; X64-BMI1NOTBMBMI2:       # %bb.0:
6776; X64-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
6777; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
6778; X64-BMI1NOTBMBMI2-NEXT:    movl %eax, (%rsi)
6779; X64-BMI1NOTBMBMI2-NEXT:    retq
6780  %tmp0 = lshr i32 %arg, 19
6781  %tmp1 = and i32 %tmp0, 1023
6782  store i32 %tmp1, i32* %ptr
6783  ret void
6784}
6785
6786; Should be still fine, but the mask is shifted
6787define void @c6_i32(i32 %arg, i32* %ptr) {
6788; X86-NOBMI-LABEL: c6_i32:
6789; X86-NOBMI:       # %bb.0:
6790; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6791; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6792; X86-NOBMI-NEXT:    shrl $19, %ecx
6793; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
6794; X86-NOBMI-NEXT:    movl %ecx, (%eax)
6795; X86-NOBMI-NEXT:    retl
6796;
6797; X86-BMI1NOTBM-LABEL: c6_i32:
6798; X86-BMI1NOTBM:       # %bb.0:
6799; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6800; X86-BMI1NOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
6801; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6802; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
6803; X86-BMI1NOTBM-NEXT:    retl
6804;
6805; X86-BMI1TBM-LABEL: c6_i32:
6806; X86-BMI1TBM:       # %bb.0:
6807; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6808; X86-BMI1TBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
6809; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
6810; X86-BMI1TBM-NEXT:    retl
6811;
6812; X86-BMI1NOTBMBMI2-LABEL: c6_i32:
6813; X86-BMI1NOTBMBMI2:       # %bb.0:
6814; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6815; X86-BMI1NOTBMBMI2-NEXT:    movl $3091, %ecx # imm = 0xC13
6816; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6817; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
6818; X86-BMI1NOTBMBMI2-NEXT:    retl
6819;
6820; X64-NOBMI-LABEL: c6_i32:
6821; X64-NOBMI:       # %bb.0:
6822; X64-NOBMI-NEXT:    shrl $19, %edi
6823; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
6824; X64-NOBMI-NEXT:    movl %edi, (%rsi)
6825; X64-NOBMI-NEXT:    retq
6826;
6827; X64-BMI1NOTBM-LABEL: c6_i32:
6828; X64-BMI1NOTBM:       # %bb.0:
6829; X64-BMI1NOTBM-NEXT:    movl $3091, %eax # imm = 0xC13
6830; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
6831; X64-BMI1NOTBM-NEXT:    movl %eax, (%rsi)
6832; X64-BMI1NOTBM-NEXT:    retq
6833;
6834; X64-BMI1TBM-LABEL: c6_i32:
6835; X64-BMI1TBM:       # %bb.0:
6836; X64-BMI1TBM-NEXT:    bextrl $3091, %edi, %eax # imm = 0xC13
6837; X64-BMI1TBM-NEXT:    movl %eax, (%rsi)
6838; X64-BMI1TBM-NEXT:    retq
6839;
6840; X64-BMI1NOTBMBMI2-LABEL: c6_i32:
6841; X64-BMI1NOTBMBMI2:       # %bb.0:
6842; X64-BMI1NOTBMBMI2-NEXT:    movl $3091, %eax # imm = 0xC13
6843; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
6844; X64-BMI1NOTBMBMI2-NEXT:    movl %eax, (%rsi)
6845; X64-BMI1NOTBMBMI2-NEXT:    retq
6846  %tmp0 = lshr i32 %arg, 19
6847  %tmp1 = and i32 %tmp0, 4095
6848  store i32 %tmp1, i32* %ptr
6849  ret void
6850}
6851
6852; Should be still fine, but the result is shifted left afterwards
6853define void @c7_i32(i32 %arg, i32* %ptr) {
6854; X86-LABEL: c7_i32:
6855; X86:       # %bb.0:
6856; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6857; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6858; X86-NEXT:    shrl $17, %ecx
6859; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
6860; X86-NEXT:    movl %ecx, (%eax)
6861; X86-NEXT:    retl
6862;
6863; X64-LABEL: c7_i32:
6864; X64:       # %bb.0:
6865; X64-NEXT:    shrl $17, %edi
6866; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
6867; X64-NEXT:    movl %edi, (%rsi)
6868; X64-NEXT:    retq
6869  %tmp0 = lshr i32 %arg, 19
6870  %tmp1 = and i32 %tmp0, 1023
6871  %tmp2 = shl i32 %tmp1, 2
6872  store i32 %tmp2, i32* %ptr
6873  ret void
6874}
6875
6876; i64
6877
6878; The most canonical variant
6879define void @c5_i64(i64 %arg, i64* %ptr) {
6880; X86-NOBMI-LABEL: c5_i64:
6881; X86-NOBMI:       # %bb.0:
6882; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6883; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6884; X86-NOBMI-NEXT:    shrl $19, %ecx
6885; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
6886; X86-NOBMI-NEXT:    movl %ecx, (%eax)
6887; X86-NOBMI-NEXT:    movl $0, 4(%eax)
6888; X86-NOBMI-NEXT:    retl
6889;
6890; X86-BMI1NOTBM-LABEL: c5_i64:
6891; X86-BMI1NOTBM:       # %bb.0:
6892; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6893; X86-BMI1NOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
6894; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6895; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
6896; X86-BMI1NOTBM-NEXT:    movl $0, 4(%eax)
6897; X86-BMI1NOTBM-NEXT:    retl
6898;
6899; X86-BMI1TBM-LABEL: c5_i64:
6900; X86-BMI1TBM:       # %bb.0:
6901; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6902; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
6903; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
6904; X86-BMI1TBM-NEXT:    movl $0, 4(%eax)
6905; X86-BMI1TBM-NEXT:    retl
6906;
6907; X86-BMI1NOTBMBMI2-LABEL: c5_i64:
6908; X86-BMI1NOTBMBMI2:       # %bb.0:
6909; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6910; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %ecx # imm = 0xA13
6911; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6912; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
6913; X86-BMI1NOTBMBMI2-NEXT:    movl $0, 4(%eax)
6914; X86-BMI1NOTBMBMI2-NEXT:    retl
6915;
6916; X64-NOBMI-LABEL: c5_i64:
6917; X64-NOBMI:       # %bb.0:
6918; X64-NOBMI-NEXT:    shrq $51, %rdi
6919; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
6920; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
6921; X64-NOBMI-NEXT:    retq
6922;
6923; X64-BMI1NOTBM-LABEL: c5_i64:
6924; X64-BMI1NOTBM:       # %bb.0:
6925; X64-BMI1NOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
6926; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
6927; X64-BMI1NOTBM-NEXT:    movq %rax, (%rsi)
6928; X64-BMI1NOTBM-NEXT:    retq
6929;
6930; X64-BMI1TBM-LABEL: c5_i64:
6931; X64-BMI1TBM:       # %bb.0:
6932; X64-BMI1TBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
6933; X64-BMI1TBM-NEXT:    movq %rax, (%rsi)
6934; X64-BMI1TBM-NEXT:    retq
6935;
6936; X64-BMI1NOTBMBMI2-LABEL: c5_i64:
6937; X64-BMI1NOTBMBMI2:       # %bb.0:
6938; X64-BMI1NOTBMBMI2-NEXT:    movl $2611, %eax # imm = 0xA33
6939; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
6940; X64-BMI1NOTBMBMI2-NEXT:    movq %rax, (%rsi)
6941; X64-BMI1NOTBMBMI2-NEXT:    retq
6942  %tmp0 = lshr i64 %arg, 51
6943  %tmp1 = and i64 %tmp0, 1023
6944  store i64 %tmp1, i64* %ptr
6945  ret void
6946}
6947
6948; Should be still fine, but the mask is shifted
6949define void @c6_i64(i64 %arg, i64* %ptr) {
6950; X86-NOBMI-LABEL: c6_i64:
6951; X86-NOBMI:       # %bb.0:
6952; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6953; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6954; X86-NOBMI-NEXT:    shrl $19, %ecx
6955; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
6956; X86-NOBMI-NEXT:    movl %ecx, (%eax)
6957; X86-NOBMI-NEXT:    movl $0, 4(%eax)
6958; X86-NOBMI-NEXT:    retl
6959;
6960; X86-BMI1NOTBM-LABEL: c6_i64:
6961; X86-BMI1NOTBM:       # %bb.0:
6962; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6963; X86-BMI1NOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
6964; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6965; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
6966; X86-BMI1NOTBM-NEXT:    movl $0, 4(%eax)
6967; X86-BMI1NOTBM-NEXT:    retl
6968;
6969; X86-BMI1TBM-LABEL: c6_i64:
6970; X86-BMI1TBM:       # %bb.0:
6971; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6972; X86-BMI1TBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
6973; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
6974; X86-BMI1TBM-NEXT:    movl $0, 4(%eax)
6975; X86-BMI1TBM-NEXT:    retl
6976;
6977; X86-BMI1NOTBMBMI2-LABEL: c6_i64:
6978; X86-BMI1NOTBMBMI2:       # %bb.0:
6979; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6980; X86-BMI1NOTBMBMI2-NEXT:    movl $3091, %ecx # imm = 0xC13
6981; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
6982; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
6983; X86-BMI1NOTBMBMI2-NEXT:    movl $0, 4(%eax)
6984; X86-BMI1NOTBMBMI2-NEXT:    retl
6985;
6986; X64-NOBMI-LABEL: c6_i64:
6987; X64-NOBMI:       # %bb.0:
6988; X64-NOBMI-NEXT:    shrq $51, %rdi
6989; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
6990; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
6991; X64-NOBMI-NEXT:    retq
6992;
6993; X64-BMI1NOTBM-LABEL: c6_i64:
6994; X64-BMI1NOTBM:       # %bb.0:
6995; X64-BMI1NOTBM-NEXT:    movl $3123, %eax # imm = 0xC33
6996; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
6997; X64-BMI1NOTBM-NEXT:    movq %rax, (%rsi)
6998; X64-BMI1NOTBM-NEXT:    retq
6999;
7000; X64-BMI1TBM-LABEL: c6_i64:
7001; X64-BMI1TBM:       # %bb.0:
7002; X64-BMI1TBM-NEXT:    bextrq $3123, %rdi, %rax # imm = 0xC33
7003; X64-BMI1TBM-NEXT:    movq %rax, (%rsi)
7004; X64-BMI1TBM-NEXT:    retq
7005;
7006; X64-BMI1NOTBMBMI2-LABEL: c6_i64:
7007; X64-BMI1NOTBMBMI2:       # %bb.0:
7008; X64-BMI1NOTBMBMI2-NEXT:    movl $3123, %eax # imm = 0xC33
7009; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
7010; X64-BMI1NOTBMBMI2-NEXT:    movq %rax, (%rsi)
7011; X64-BMI1NOTBMBMI2-NEXT:    retq
7012  %tmp0 = lshr i64 %arg, 51
7013  %tmp1 = and i64 %tmp0, 4095
7014  store i64 %tmp1, i64* %ptr
7015  ret void
7016}
7017
7018; Should be still fine, but the result is shifted left afterwards
7019define void @c7_i64(i64 %arg, i64* %ptr) {
7020; X86-LABEL: c7_i64:
7021; X86:       # %bb.0:
7022; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7023; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7024; X86-NEXT:    shrl $17, %ecx
7025; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
7026; X86-NEXT:    movl %ecx, (%eax)
7027; X86-NEXT:    movl $0, 4(%eax)
7028; X86-NEXT:    retl
7029;
7030; X64-LABEL: c7_i64:
7031; X64:       # %bb.0:
7032; X64-NEXT:    shrq $49, %rdi
7033; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
7034; X64-NEXT:    movq %rdi, (%rsi)
7035; X64-NEXT:    retq
7036  %tmp0 = lshr i64 %arg, 51
7037  %tmp1 = and i64 %tmp0, 1023
7038  %tmp2 = shl i64 %tmp1, 2
7039  store i64 %tmp2, i64* %ptr
7040  ret void
7041}
7042