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; 64-bit, but with 32-bit output
1618
1619; Everything done in 64-bit, truncation happens last.
1620define i32 @bextr64_32_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1621; X86-NOBMI-LABEL: bextr64_32_a0:
1622; X86-NOBMI:       # %bb.0:
1623; X86-NOBMI-NEXT:    pushl %edi
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), %eax
1628; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1629; X86-NOBMI-NEXT:    movl %edi, %esi
1630; X86-NOBMI-NEXT:    shrl %cl, %esi
1631; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1632; X86-NOBMI-NEXT:    testb $32, %cl
1633; X86-NOBMI-NEXT:    jne .LBB14_2
1634; X86-NOBMI-NEXT:  # %bb.1:
1635; X86-NOBMI-NEXT:    movl %eax, %esi
1636; X86-NOBMI-NEXT:  .LBB14_2:
1637; X86-NOBMI-NEXT:    movl $1, %edi
1638; X86-NOBMI-NEXT:    movl %edx, %ecx
1639; X86-NOBMI-NEXT:    shll %cl, %edi
1640; X86-NOBMI-NEXT:    xorl %eax, %eax
1641; X86-NOBMI-NEXT:    testb $32, %dl
1642; X86-NOBMI-NEXT:    jne .LBB14_4
1643; X86-NOBMI-NEXT:  # %bb.3:
1644; X86-NOBMI-NEXT:    movl %edi, %eax
1645; X86-NOBMI-NEXT:  .LBB14_4:
1646; X86-NOBMI-NEXT:    decl %eax
1647; X86-NOBMI-NEXT:    andl %esi, %eax
1648; X86-NOBMI-NEXT:    popl %esi
1649; X86-NOBMI-NEXT:    popl %edi
1650; X86-NOBMI-NEXT:    retl
1651;
1652; X86-BMI1NOTBM-LABEL: bextr64_32_a0:
1653; X86-BMI1NOTBM:       # %bb.0:
1654; X86-BMI1NOTBM-NEXT:    pushl %edi
1655; X86-BMI1NOTBM-NEXT:    pushl %esi
1656; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %dl
1657; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1658; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
1659; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
1660; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
1661; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
1662; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %eax
1663; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1664; X86-BMI1NOTBM-NEXT:    jne .LBB14_2
1665; X86-BMI1NOTBM-NEXT:  # %bb.1:
1666; X86-BMI1NOTBM-NEXT:    movl %eax, %esi
1667; X86-BMI1NOTBM-NEXT:  .LBB14_2:
1668; X86-BMI1NOTBM-NEXT:    movl $1, %edi
1669; X86-BMI1NOTBM-NEXT:    movl %edx, %ecx
1670; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
1671; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
1672; X86-BMI1NOTBM-NEXT:    testb $32, %dl
1673; X86-BMI1NOTBM-NEXT:    jne .LBB14_4
1674; X86-BMI1NOTBM-NEXT:  # %bb.3:
1675; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
1676; X86-BMI1NOTBM-NEXT:  .LBB14_4:
1677; X86-BMI1NOTBM-NEXT:    decl %eax
1678; X86-BMI1NOTBM-NEXT:    andl %esi, %eax
1679; X86-BMI1NOTBM-NEXT:    popl %esi
1680; X86-BMI1NOTBM-NEXT:    popl %edi
1681; X86-BMI1NOTBM-NEXT:    retl
1682;
1683; X86-BMI1BMI2-LABEL: bextr64_32_a0:
1684; X86-BMI1BMI2:       # %bb.0:
1685; X86-BMI1BMI2-NEXT:    pushl %ebx
1686; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
1687; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1688; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1689; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1690; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %edx
1691; X86-BMI1BMI2-NEXT:    testb $32, %cl
1692; X86-BMI1BMI2-NEXT:    je .LBB14_2
1693; X86-BMI1BMI2-NEXT:  # %bb.1:
1694; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edx
1695; X86-BMI1BMI2-NEXT:  .LBB14_2:
1696; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
1697; X86-BMI1BMI2-NEXT:    testb $32, %bl
1698; X86-BMI1BMI2-NEXT:    jne .LBB14_4
1699; X86-BMI1BMI2-NEXT:  # %bb.3:
1700; X86-BMI1BMI2-NEXT:    movl $1, %eax
1701; X86-BMI1BMI2-NEXT:    shlxl %ebx, %eax, %eax
1702; X86-BMI1BMI2-NEXT:  .LBB14_4:
1703; X86-BMI1BMI2-NEXT:    decl %eax
1704; X86-BMI1BMI2-NEXT:    andl %edx, %eax
1705; X86-BMI1BMI2-NEXT:    popl %ebx
1706; X86-BMI1BMI2-NEXT:    retl
1707;
1708; X64-NOBMI-LABEL: bextr64_32_a0:
1709; X64-NOBMI:       # %bb.0:
1710; X64-NOBMI-NEXT:    movq %rsi, %rcx
1711; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1712; X64-NOBMI-NEXT:    shrq %cl, %rdi
1713; X64-NOBMI-NEXT:    movl $1, %eax
1714; X64-NOBMI-NEXT:    movl %edx, %ecx
1715; X64-NOBMI-NEXT:    shlq %cl, %rax
1716; X64-NOBMI-NEXT:    decl %eax
1717; X64-NOBMI-NEXT:    andl %edi, %eax
1718; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
1719; X64-NOBMI-NEXT:    retq
1720;
1721; X64-BMI1NOTBM-LABEL: bextr64_32_a0:
1722; X64-BMI1NOTBM:       # %bb.0:
1723; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
1724; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
1725; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
1726; X64-BMI1NOTBM-NEXT:    movl $1, %eax
1727; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
1728; X64-BMI1NOTBM-NEXT:    shlq %cl, %rax
1729; X64-BMI1NOTBM-NEXT:    decl %eax
1730; X64-BMI1NOTBM-NEXT:    andl %edi, %eax
1731; X64-BMI1NOTBM-NEXT:    # kill: def $eax killed $eax killed $rax
1732; X64-BMI1NOTBM-NEXT:    retq
1733;
1734; X64-BMI1BMI2-LABEL: bextr64_32_a0:
1735; X64-BMI1BMI2:       # %bb.0:
1736; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1737; X64-BMI1BMI2-NEXT:    movl $1, %ecx
1738; X64-BMI1BMI2-NEXT:    shlxq %rdx, %rcx, %rcx
1739; X64-BMI1BMI2-NEXT:    decl %ecx
1740; X64-BMI1BMI2-NEXT:    andl %ecx, %eax
1741; X64-BMI1BMI2-NEXT:    # kill: def $eax killed $eax killed $rax
1742; X64-BMI1BMI2-NEXT:    retq
1743  %shifted = lshr i64 %val, %numskipbits
1744  %onebit = shl i64 1, %numlowbits
1745  %mask = add nsw i64 %onebit, -1
1746  %masked = and i64 %mask, %shifted
1747  %res = trunc i64 %masked to i32
1748  ret i32 %res
1749}
1750
1751; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
1752define i32 @bextr64_32_a1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
1753; X86-NOBMI-LABEL: bextr64_32_a1:
1754; X86-NOBMI:       # %bb.0:
1755; X86-NOBMI-NEXT:    pushl %edi
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 {{[0-9]+}}(%esp), %edi
1761; X86-NOBMI-NEXT:    movl %edi, %esi
1762; X86-NOBMI-NEXT:    shrl %cl, %esi
1763; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1764; X86-NOBMI-NEXT:    testb $32, %cl
1765; X86-NOBMI-NEXT:    jne .LBB15_2
1766; X86-NOBMI-NEXT:  # %bb.1:
1767; X86-NOBMI-NEXT:    movl %eax, %esi
1768; X86-NOBMI-NEXT:  .LBB15_2:
1769; X86-NOBMI-NEXT:    movl $1, %eax
1770; X86-NOBMI-NEXT:    movl %edx, %ecx
1771; X86-NOBMI-NEXT:    shll %cl, %eax
1772; X86-NOBMI-NEXT:    decl %eax
1773; X86-NOBMI-NEXT:    andl %esi, %eax
1774; X86-NOBMI-NEXT:    popl %esi
1775; X86-NOBMI-NEXT:    popl %edi
1776; X86-NOBMI-NEXT:    retl
1777;
1778; X86-BMI1NOTBM-LABEL: bextr64_32_a1:
1779; X86-BMI1NOTBM:       # %bb.0:
1780; X86-BMI1NOTBM-NEXT:    pushl %edi
1781; X86-BMI1NOTBM-NEXT:    pushl %esi
1782; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1783; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1784; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
1785; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
1786; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
1787; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
1788; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
1789; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1790; X86-BMI1NOTBM-NEXT:    jne .LBB15_2
1791; X86-BMI1NOTBM-NEXT:  # %bb.1:
1792; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
1793; X86-BMI1NOTBM-NEXT:  .LBB15_2:
1794; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1795; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
1796; X86-BMI1NOTBM-NEXT:    popl %esi
1797; X86-BMI1NOTBM-NEXT:    popl %edi
1798; X86-BMI1NOTBM-NEXT:    retl
1799;
1800; X86-BMI1BMI2-LABEL: bextr64_32_a1:
1801; X86-BMI1BMI2:       # %bb.0:
1802; X86-BMI1BMI2-NEXT:    pushl %esi
1803; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1804; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1805; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1806; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1807; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
1808; X86-BMI1BMI2-NEXT:    testb $32, %cl
1809; X86-BMI1BMI2-NEXT:    je .LBB15_2
1810; X86-BMI1BMI2-NEXT:  # %bb.1:
1811; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
1812; X86-BMI1BMI2-NEXT:  .LBB15_2:
1813; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
1814; X86-BMI1BMI2-NEXT:    popl %esi
1815; X86-BMI1BMI2-NEXT:    retl
1816;
1817; X64-NOBMI-LABEL: bextr64_32_a1:
1818; X64-NOBMI:       # %bb.0:
1819; X64-NOBMI-NEXT:    movq %rsi, %rcx
1820; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1821; X64-NOBMI-NEXT:    shrq %cl, %rdi
1822; X64-NOBMI-NEXT:    movl $1, %eax
1823; X64-NOBMI-NEXT:    movl %edx, %ecx
1824; X64-NOBMI-NEXT:    shll %cl, %eax
1825; X64-NOBMI-NEXT:    decl %eax
1826; X64-NOBMI-NEXT:    andl %edi, %eax
1827; X64-NOBMI-NEXT:    retq
1828;
1829; X64-BMI1NOTBM-LABEL: bextr64_32_a1:
1830; X64-BMI1NOTBM:       # %bb.0:
1831; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
1832; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
1833; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
1834; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1835; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
1836; X64-BMI1NOTBM-NEXT:    retq
1837;
1838; X64-BMI1BMI2-LABEL: bextr64_32_a1:
1839; X64-BMI1BMI2:       # %bb.0:
1840; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1841; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1842; X64-BMI1BMI2-NEXT:    retq
1843  %shifted = lshr i64 %val, %numskipbits
1844  %truncshifted = trunc i64 %shifted to i32
1845  %onebit = shl i32 1, %numlowbits
1846  %mask = add nsw i32 %onebit, -1
1847  %masked = and i32 %mask, %truncshifted
1848  ret i32 %masked
1849}
1850
1851; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
1852; Masking is 64-bit. Then truncation.
1853define i32 @bextr64_32_a2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
1854; X86-NOBMI-LABEL: bextr64_32_a2:
1855; X86-NOBMI:       # %bb.0:
1856; X86-NOBMI-NEXT:    pushl %edi
1857; X86-NOBMI-NEXT:    pushl %esi
1858; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1859; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1860; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1861; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1862; X86-NOBMI-NEXT:    movl %edi, %esi
1863; X86-NOBMI-NEXT:    shrl %cl, %esi
1864; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1865; X86-NOBMI-NEXT:    testb $32, %cl
1866; X86-NOBMI-NEXT:    jne .LBB16_2
1867; X86-NOBMI-NEXT:  # %bb.1:
1868; X86-NOBMI-NEXT:    movl %eax, %esi
1869; X86-NOBMI-NEXT:  .LBB16_2:
1870; X86-NOBMI-NEXT:    movl $1, %eax
1871; X86-NOBMI-NEXT:    movl %edx, %ecx
1872; X86-NOBMI-NEXT:    shll %cl, %eax
1873; X86-NOBMI-NEXT:    decl %eax
1874; X86-NOBMI-NEXT:    andl %esi, %eax
1875; X86-NOBMI-NEXT:    popl %esi
1876; X86-NOBMI-NEXT:    popl %edi
1877; X86-NOBMI-NEXT:    retl
1878;
1879; X86-BMI1NOTBM-LABEL: bextr64_32_a2:
1880; X86-BMI1NOTBM:       # %bb.0:
1881; X86-BMI1NOTBM-NEXT:    pushl %edi
1882; X86-BMI1NOTBM-NEXT:    pushl %esi
1883; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1884; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
1885; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
1886; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
1887; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
1888; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
1889; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
1890; X86-BMI1NOTBM-NEXT:    testb $32, %cl
1891; X86-BMI1NOTBM-NEXT:    jne .LBB16_2
1892; X86-BMI1NOTBM-NEXT:  # %bb.1:
1893; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
1894; X86-BMI1NOTBM-NEXT:  .LBB16_2:
1895; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1896; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
1897; X86-BMI1NOTBM-NEXT:    popl %esi
1898; X86-BMI1NOTBM-NEXT:    popl %edi
1899; X86-BMI1NOTBM-NEXT:    retl
1900;
1901; X86-BMI1BMI2-LABEL: bextr64_32_a2:
1902; X86-BMI1BMI2:       # %bb.0:
1903; X86-BMI1BMI2-NEXT:    pushl %esi
1904; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1905; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1906; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1907; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1908; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
1909; X86-BMI1BMI2-NEXT:    testb $32, %cl
1910; X86-BMI1BMI2-NEXT:    je .LBB16_2
1911; X86-BMI1BMI2-NEXT:  # %bb.1:
1912; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
1913; X86-BMI1BMI2-NEXT:  .LBB16_2:
1914; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
1915; X86-BMI1BMI2-NEXT:    popl %esi
1916; X86-BMI1BMI2-NEXT:    retl
1917;
1918; X64-NOBMI-LABEL: bextr64_32_a2:
1919; X64-NOBMI:       # %bb.0:
1920; X64-NOBMI-NEXT:    movq %rsi, %rcx
1921; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1922; X64-NOBMI-NEXT:    shrq %cl, %rdi
1923; X64-NOBMI-NEXT:    movl $1, %eax
1924; X64-NOBMI-NEXT:    movl %edx, %ecx
1925; X64-NOBMI-NEXT:    shll %cl, %eax
1926; X64-NOBMI-NEXT:    decl %eax
1927; X64-NOBMI-NEXT:    andl %edi, %eax
1928; X64-NOBMI-NEXT:    retq
1929;
1930; X64-BMI1NOTBM-LABEL: bextr64_32_a2:
1931; X64-BMI1NOTBM:       # %bb.0:
1932; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
1933; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
1934; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
1935; X64-BMI1NOTBM-NEXT:    shll $8, %edx
1936; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
1937; X64-BMI1NOTBM-NEXT:    retq
1938;
1939; X64-BMI1BMI2-LABEL: bextr64_32_a2:
1940; X64-BMI1BMI2:       # %bb.0:
1941; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1942; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
1943; X64-BMI1BMI2-NEXT:    retq
1944  %shifted = lshr i64 %val, %numskipbits
1945  %onebit = shl i32 1, %numlowbits
1946  %mask = add nsw i32 %onebit, -1
1947  %zextmask = zext i32 %mask to i64
1948  %masked = and i64 %zextmask, %shifted
1949  %truncmasked = trunc i64 %masked to i32
1950  ret i32 %truncmasked
1951}
1952
1953; ---------------------------------------------------------------------------- ;
1954; Pattern b. 32-bit
1955; ---------------------------------------------------------------------------- ;
1956
1957define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
1958; X86-NOBMI-LABEL: bextr32_b0:
1959; X86-NOBMI:       # %bb.0:
1960; X86-NOBMI-NEXT:    pushl %esi
1961; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
1962; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1963; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1964; X86-NOBMI-NEXT:    shrl %cl, %esi
1965; X86-NOBMI-NEXT:    movl $-1, %eax
1966; X86-NOBMI-NEXT:    movl %edx, %ecx
1967; X86-NOBMI-NEXT:    shll %cl, %eax
1968; X86-NOBMI-NEXT:    notl %eax
1969; X86-NOBMI-NEXT:    andl %esi, %eax
1970; X86-NOBMI-NEXT:    popl %esi
1971; X86-NOBMI-NEXT:    retl
1972;
1973; X86-BMI1NOTBM-LABEL: bextr32_b0:
1974; X86-BMI1NOTBM:       # %bb.0:
1975; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
1976; X86-BMI1NOTBM-NEXT:    shll $8, %eax
1977; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1978; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
1979; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
1980; X86-BMI1NOTBM-NEXT:    retl
1981;
1982; X86-BMI1BMI2-LABEL: bextr32_b0:
1983; X86-BMI1BMI2:       # %bb.0:
1984; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
1985; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
1986; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
1987; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
1988; X86-BMI1BMI2-NEXT:    retl
1989;
1990; X64-NOBMI-LABEL: bextr32_b0:
1991; X64-NOBMI:       # %bb.0:
1992; X64-NOBMI-NEXT:    movl %esi, %ecx
1993; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1994; X64-NOBMI-NEXT:    shrl %cl, %edi
1995; X64-NOBMI-NEXT:    movl $-1, %eax
1996; X64-NOBMI-NEXT:    movl %edx, %ecx
1997; X64-NOBMI-NEXT:    shll %cl, %eax
1998; X64-NOBMI-NEXT:    notl %eax
1999; X64-NOBMI-NEXT:    andl %edi, %eax
2000; X64-NOBMI-NEXT:    retq
2001;
2002; X64-BMI1NOTBM-LABEL: bextr32_b0:
2003; X64-BMI1NOTBM:       # %bb.0:
2004; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2005; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2006; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2007; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
2008; X64-BMI1NOTBM-NEXT:    retq
2009;
2010; X64-BMI1BMI2-LABEL: bextr32_b0:
2011; X64-BMI1BMI2:       # %bb.0:
2012; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
2013; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
2014; X64-BMI1BMI2-NEXT:    retq
2015  %shifted = lshr i32 %val, %numskipbits
2016  %notmask = shl i32 -1, %numlowbits
2017  %mask = xor i32 %notmask, -1
2018  %masked = and i32 %mask, %shifted
2019  ret i32 %masked
2020}
2021
2022define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2023; X86-NOBMI-LABEL: bextr32_b1_indexzext:
2024; X86-NOBMI:       # %bb.0:
2025; X86-NOBMI-NEXT:    pushl %esi
2026; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2027; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2028; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2029; X86-NOBMI-NEXT:    shrl %cl, %esi
2030; X86-NOBMI-NEXT:    movl $-1, %eax
2031; X86-NOBMI-NEXT:    movl %edx, %ecx
2032; X86-NOBMI-NEXT:    shll %cl, %eax
2033; X86-NOBMI-NEXT:    notl %eax
2034; X86-NOBMI-NEXT:    andl %esi, %eax
2035; X86-NOBMI-NEXT:    popl %esi
2036; X86-NOBMI-NEXT:    retl
2037;
2038; X86-BMI1NOTBM-LABEL: bextr32_b1_indexzext:
2039; X86-BMI1NOTBM:       # %bb.0:
2040; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2041; X86-BMI1NOTBM-NEXT:    shll $8, %eax
2042; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2043; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
2044; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
2045; X86-BMI1NOTBM-NEXT:    retl
2046;
2047; X86-BMI1BMI2-LABEL: bextr32_b1_indexzext:
2048; X86-BMI1BMI2:       # %bb.0:
2049; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2050; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2051; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
2052; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
2053; X86-BMI1BMI2-NEXT:    retl
2054;
2055; X64-NOBMI-LABEL: bextr32_b1_indexzext:
2056; X64-NOBMI:       # %bb.0:
2057; X64-NOBMI-NEXT:    movl %esi, %ecx
2058; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2059; X64-NOBMI-NEXT:    shrl %cl, %edi
2060; X64-NOBMI-NEXT:    movl $-1, %eax
2061; X64-NOBMI-NEXT:    movl %edx, %ecx
2062; X64-NOBMI-NEXT:    shll %cl, %eax
2063; X64-NOBMI-NEXT:    notl %eax
2064; X64-NOBMI-NEXT:    andl %edi, %eax
2065; X64-NOBMI-NEXT:    retq
2066;
2067; X64-BMI1NOTBM-LABEL: bextr32_b1_indexzext:
2068; X64-BMI1NOTBM:       # %bb.0:
2069; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2070; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2071; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2072; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
2073; X64-BMI1NOTBM-NEXT:    retq
2074;
2075; X64-BMI1BMI2-LABEL: bextr32_b1_indexzext:
2076; X64-BMI1BMI2:       # %bb.0:
2077; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
2078; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
2079; X64-BMI1BMI2-NEXT:    retq
2080  %skip = zext i8 %numskipbits to i32
2081  %shifted = lshr i32 %val, %skip
2082  %conv = zext i8 %numlowbits to i32
2083  %notmask = shl i32 -1, %conv
2084  %mask = xor i32 %notmask, -1
2085  %masked = and i32 %mask, %shifted
2086  ret i32 %masked
2087}
2088
2089define i32 @bextr32_b2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
2090; X86-NOBMI-LABEL: bextr32_b2_load:
2091; X86-NOBMI:       # %bb.0:
2092; X86-NOBMI-NEXT:    pushl %esi
2093; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2094; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2095; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2096; X86-NOBMI-NEXT:    movl (%eax), %esi
2097; X86-NOBMI-NEXT:    shrl %cl, %esi
2098; X86-NOBMI-NEXT:    movl $-1, %eax
2099; X86-NOBMI-NEXT:    movl %edx, %ecx
2100; X86-NOBMI-NEXT:    shll %cl, %eax
2101; X86-NOBMI-NEXT:    notl %eax
2102; X86-NOBMI-NEXT:    andl %esi, %eax
2103; X86-NOBMI-NEXT:    popl %esi
2104; X86-NOBMI-NEXT:    retl
2105;
2106; X86-BMI1NOTBM-LABEL: bextr32_b2_load:
2107; X86-BMI1NOTBM:       # %bb.0:
2108; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2109; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2110; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
2111; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2112; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
2113; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
2114; X86-BMI1NOTBM-NEXT:    retl
2115;
2116; X86-BMI1BMI2-LABEL: bextr32_b2_load:
2117; X86-BMI1BMI2:       # %bb.0:
2118; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2119; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2120; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
2121; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
2122; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
2123; X86-BMI1BMI2-NEXT:    retl
2124;
2125; X64-NOBMI-LABEL: bextr32_b2_load:
2126; X64-NOBMI:       # %bb.0:
2127; X64-NOBMI-NEXT:    movl %esi, %ecx
2128; X64-NOBMI-NEXT:    movl (%rdi), %esi
2129; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2130; X64-NOBMI-NEXT:    shrl %cl, %esi
2131; X64-NOBMI-NEXT:    movl $-1, %eax
2132; X64-NOBMI-NEXT:    movl %edx, %ecx
2133; X64-NOBMI-NEXT:    shll %cl, %eax
2134; X64-NOBMI-NEXT:    notl %eax
2135; X64-NOBMI-NEXT:    andl %esi, %eax
2136; X64-NOBMI-NEXT:    retq
2137;
2138; X64-BMI1NOTBM-LABEL: bextr32_b2_load:
2139; X64-BMI1NOTBM:       # %bb.0:
2140; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2141; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2142; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2143; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
2144; X64-BMI1NOTBM-NEXT:    retq
2145;
2146; X64-BMI1BMI2-LABEL: bextr32_b2_load:
2147; X64-BMI1BMI2:       # %bb.0:
2148; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
2149; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
2150; X64-BMI1BMI2-NEXT:    retq
2151  %val = load i32, i32* %w
2152  %shifted = lshr i32 %val, %numskipbits
2153  %notmask = shl i32 -1, %numlowbits
2154  %mask = xor i32 %notmask, -1
2155  %masked = and i32 %mask, %shifted
2156  ret i32 %masked
2157}
2158
2159define i32 @bextr32_b3_load_indexzext(i32* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2160; X86-NOBMI-LABEL: bextr32_b3_load_indexzext:
2161; X86-NOBMI:       # %bb.0:
2162; X86-NOBMI-NEXT:    pushl %esi
2163; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2164; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2165; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2166; X86-NOBMI-NEXT:    movl (%eax), %esi
2167; X86-NOBMI-NEXT:    shrl %cl, %esi
2168; X86-NOBMI-NEXT:    movl $-1, %eax
2169; X86-NOBMI-NEXT:    movl %edx, %ecx
2170; X86-NOBMI-NEXT:    shll %cl, %eax
2171; X86-NOBMI-NEXT:    notl %eax
2172; X86-NOBMI-NEXT:    andl %esi, %eax
2173; X86-NOBMI-NEXT:    popl %esi
2174; X86-NOBMI-NEXT:    retl
2175;
2176; X86-BMI1NOTBM-LABEL: bextr32_b3_load_indexzext:
2177; X86-BMI1NOTBM:       # %bb.0:
2178; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2179; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2180; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
2181; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2182; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
2183; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
2184; X86-BMI1NOTBM-NEXT:    retl
2185;
2186; X86-BMI1BMI2-LABEL: bextr32_b3_load_indexzext:
2187; X86-BMI1BMI2:       # %bb.0:
2188; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2189; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2190; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
2191; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
2192; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
2193; X86-BMI1BMI2-NEXT:    retl
2194;
2195; X64-NOBMI-LABEL: bextr32_b3_load_indexzext:
2196; X64-NOBMI:       # %bb.0:
2197; X64-NOBMI-NEXT:    movl %esi, %ecx
2198; X64-NOBMI-NEXT:    movl (%rdi), %esi
2199; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2200; X64-NOBMI-NEXT:    shrl %cl, %esi
2201; X64-NOBMI-NEXT:    movl $-1, %eax
2202; X64-NOBMI-NEXT:    movl %edx, %ecx
2203; X64-NOBMI-NEXT:    shll %cl, %eax
2204; X64-NOBMI-NEXT:    notl %eax
2205; X64-NOBMI-NEXT:    andl %esi, %eax
2206; X64-NOBMI-NEXT:    retq
2207;
2208; X64-BMI1NOTBM-LABEL: bextr32_b3_load_indexzext:
2209; X64-BMI1NOTBM:       # %bb.0:
2210; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2211; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2212; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2213; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
2214; X64-BMI1NOTBM-NEXT:    retq
2215;
2216; X64-BMI1BMI2-LABEL: bextr32_b3_load_indexzext:
2217; X64-BMI1BMI2:       # %bb.0:
2218; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
2219; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
2220; X64-BMI1BMI2-NEXT:    retq
2221  %val = load i32, i32* %w
2222  %skip = zext i8 %numskipbits to i32
2223  %shifted = lshr i32 %val, %skip
2224  %conv = zext i8 %numlowbits to i32
2225  %notmask = shl i32 -1, %conv
2226  %mask = xor i32 %notmask, -1
2227  %masked = and i32 %mask, %shifted
2228  ret i32 %masked
2229}
2230
2231define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2232; X86-NOBMI-LABEL: bextr32_b4_commutative:
2233; X86-NOBMI:       # %bb.0:
2234; X86-NOBMI-NEXT:    pushl %esi
2235; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2236; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2237; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2238; X86-NOBMI-NEXT:    shrl %cl, %esi
2239; X86-NOBMI-NEXT:    movl $-1, %eax
2240; X86-NOBMI-NEXT:    movl %edx, %ecx
2241; X86-NOBMI-NEXT:    shll %cl, %eax
2242; X86-NOBMI-NEXT:    notl %eax
2243; X86-NOBMI-NEXT:    andl %esi, %eax
2244; X86-NOBMI-NEXT:    popl %esi
2245; X86-NOBMI-NEXT:    retl
2246;
2247; X86-BMI1NOTBM-LABEL: bextr32_b4_commutative:
2248; X86-BMI1NOTBM:       # %bb.0:
2249; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2250; X86-BMI1NOTBM-NEXT:    shll $8, %eax
2251; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2252; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
2253; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
2254; X86-BMI1NOTBM-NEXT:    retl
2255;
2256; X86-BMI1BMI2-LABEL: bextr32_b4_commutative:
2257; X86-BMI1BMI2:       # %bb.0:
2258; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2259; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2260; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
2261; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
2262; X86-BMI1BMI2-NEXT:    retl
2263;
2264; X64-NOBMI-LABEL: bextr32_b4_commutative:
2265; X64-NOBMI:       # %bb.0:
2266; X64-NOBMI-NEXT:    movl %esi, %ecx
2267; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2268; X64-NOBMI-NEXT:    shrl %cl, %edi
2269; X64-NOBMI-NEXT:    movl $-1, %eax
2270; X64-NOBMI-NEXT:    movl %edx, %ecx
2271; X64-NOBMI-NEXT:    shll %cl, %eax
2272; X64-NOBMI-NEXT:    notl %eax
2273; X64-NOBMI-NEXT:    andl %edi, %eax
2274; X64-NOBMI-NEXT:    retq
2275;
2276; X64-BMI1NOTBM-LABEL: bextr32_b4_commutative:
2277; X64-BMI1NOTBM:       # %bb.0:
2278; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2279; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2280; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2281; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
2282; X64-BMI1NOTBM-NEXT:    retq
2283;
2284; X64-BMI1BMI2-LABEL: bextr32_b4_commutative:
2285; X64-BMI1BMI2:       # %bb.0:
2286; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
2287; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
2288; X64-BMI1BMI2-NEXT:    retq
2289  %shifted = lshr i32 %val, %numskipbits
2290  %notmask = shl i32 -1, %numlowbits
2291  %mask = xor i32 %notmask, -1
2292  %masked = and i32 %shifted, %mask ; swapped order
2293  ret i32 %masked
2294}
2295
2296define i32 @bextr32_b5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2297; X86-NOBMI-LABEL: bextr32_b5_skipextrauses:
2298; X86-NOBMI:       # %bb.0:
2299; X86-NOBMI-NEXT:    pushl %edi
2300; X86-NOBMI-NEXT:    pushl %esi
2301; X86-NOBMI-NEXT:    pushl %eax
2302; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
2303; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
2304; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2305; X86-NOBMI-NEXT:    movl %eax, %ecx
2306; X86-NOBMI-NEXT:    shrl %cl, %edi
2307; X86-NOBMI-NEXT:    movl $-1, %esi
2308; X86-NOBMI-NEXT:    movl %edx, %ecx
2309; X86-NOBMI-NEXT:    shll %cl, %esi
2310; X86-NOBMI-NEXT:    notl %esi
2311; X86-NOBMI-NEXT:    andl %edi, %esi
2312; X86-NOBMI-NEXT:    movl %eax, (%esp)
2313; X86-NOBMI-NEXT:    calll use32
2314; X86-NOBMI-NEXT:    movl %esi, %eax
2315; X86-NOBMI-NEXT:    addl $4, %esp
2316; X86-NOBMI-NEXT:    popl %esi
2317; X86-NOBMI-NEXT:    popl %edi
2318; X86-NOBMI-NEXT:    retl
2319;
2320; X86-BMI1NOTBM-LABEL: bextr32_b5_skipextrauses:
2321; X86-BMI1NOTBM:       # %bb.0:
2322; X86-BMI1NOTBM-NEXT:    pushl %esi
2323; X86-BMI1NOTBM-NEXT:    subl $8, %esp
2324; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2325; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
2326; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
2327; X86-BMI1NOTBM-NEXT:    movzbl %al, %edx
2328; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
2329; X86-BMI1NOTBM-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
2330; X86-BMI1NOTBM-NEXT:    movl %eax, (%esp)
2331; X86-BMI1NOTBM-NEXT:    calll use32
2332; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
2333; X86-BMI1NOTBM-NEXT:    addl $8, %esp
2334; X86-BMI1NOTBM-NEXT:    popl %esi
2335; X86-BMI1NOTBM-NEXT:    retl
2336;
2337; X86-BMI1BMI2-LABEL: bextr32_b5_skipextrauses:
2338; X86-BMI1BMI2:       # %bb.0:
2339; X86-BMI1BMI2-NEXT:    pushl %esi
2340; X86-BMI1BMI2-NEXT:    subl $8, %esp
2341; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2342; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2343; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
2344; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %esi
2345; X86-BMI1BMI2-NEXT:    movl %ecx, (%esp)
2346; X86-BMI1BMI2-NEXT:    calll use32
2347; X86-BMI1BMI2-NEXT:    movl %esi, %eax
2348; X86-BMI1BMI2-NEXT:    addl $8, %esp
2349; X86-BMI1BMI2-NEXT:    popl %esi
2350; X86-BMI1BMI2-NEXT:    retl
2351;
2352; X64-NOBMI-LABEL: bextr32_b5_skipextrauses:
2353; X64-NOBMI:       # %bb.0:
2354; X64-NOBMI-NEXT:    pushq %rbx
2355; X64-NOBMI-NEXT:    movl %esi, %ecx
2356; X64-NOBMI-NEXT:    shrl %cl, %edi
2357; X64-NOBMI-NEXT:    movl $-1, %ebx
2358; X64-NOBMI-NEXT:    movl %edx, %ecx
2359; X64-NOBMI-NEXT:    shll %cl, %ebx
2360; X64-NOBMI-NEXT:    notl %ebx
2361; X64-NOBMI-NEXT:    andl %edi, %ebx
2362; X64-NOBMI-NEXT:    movl %esi, %edi
2363; X64-NOBMI-NEXT:    callq use32
2364; X64-NOBMI-NEXT:    movl %ebx, %eax
2365; X64-NOBMI-NEXT:    popq %rbx
2366; X64-NOBMI-NEXT:    retq
2367;
2368; X64-BMI1NOTBM-LABEL: bextr32_b5_skipextrauses:
2369; X64-BMI1NOTBM:       # %bb.0:
2370; X64-BMI1NOTBM-NEXT:    pushq %rbx
2371; X64-BMI1NOTBM-NEXT:    shll $8, %edx
2372; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2373; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
2374; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %ebx
2375; X64-BMI1NOTBM-NEXT:    movl %esi, %edi
2376; X64-BMI1NOTBM-NEXT:    callq use32
2377; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
2378; X64-BMI1NOTBM-NEXT:    popq %rbx
2379; X64-BMI1NOTBM-NEXT:    retq
2380;
2381; X64-BMI1BMI2-LABEL: bextr32_b5_skipextrauses:
2382; X64-BMI1BMI2:       # %bb.0:
2383; X64-BMI1BMI2-NEXT:    pushq %rbx
2384; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
2385; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %ebx
2386; X64-BMI1BMI2-NEXT:    movl %esi, %edi
2387; X64-BMI1BMI2-NEXT:    callq use32
2388; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
2389; X64-BMI1BMI2-NEXT:    popq %rbx
2390; X64-BMI1BMI2-NEXT:    retq
2391  %shifted = lshr i32 %val, %numskipbits
2392  %notmask = shl i32 -1, %numlowbits
2393  %mask = xor i32 %notmask, -1
2394  %masked = and i32 %mask, %shifted
2395  call void @use32(i32 %numskipbits)
2396  ret i32 %masked
2397}
2398
2399; 64-bit
2400
2401define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2402; X86-NOBMI-LABEL: bextr64_b0:
2403; X86-NOBMI:       # %bb.0:
2404; X86-NOBMI-NEXT:    pushl %edi
2405; X86-NOBMI-NEXT:    pushl %esi
2406; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2407; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2408; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2409; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2410; X86-NOBMI-NEXT:    movl %eax, %edi
2411; X86-NOBMI-NEXT:    shrl %cl, %edi
2412; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2413; X86-NOBMI-NEXT:    testb $32, %cl
2414; X86-NOBMI-NEXT:    je .LBB23_2
2415; X86-NOBMI-NEXT:  # %bb.1:
2416; X86-NOBMI-NEXT:    movl %edi, %esi
2417; X86-NOBMI-NEXT:    xorl %edi, %edi
2418; X86-NOBMI-NEXT:  .LBB23_2:
2419; X86-NOBMI-NEXT:    movl $-1, %edx
2420; X86-NOBMI-NEXT:    movl $-1, %eax
2421; X86-NOBMI-NEXT:    movb %ch, %cl
2422; X86-NOBMI-NEXT:    shll %cl, %eax
2423; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2424; X86-NOBMI-NEXT:    testb $32, %ch
2425; X86-NOBMI-NEXT:    je .LBB23_4
2426; X86-NOBMI-NEXT:  # %bb.3:
2427; X86-NOBMI-NEXT:    movl %eax, %edx
2428; X86-NOBMI-NEXT:    xorl %eax, %eax
2429; X86-NOBMI-NEXT:  .LBB23_4:
2430; X86-NOBMI-NEXT:    notl %edx
2431; X86-NOBMI-NEXT:    andl %edi, %edx
2432; X86-NOBMI-NEXT:    notl %eax
2433; X86-NOBMI-NEXT:    andl %esi, %eax
2434; X86-NOBMI-NEXT:    popl %esi
2435; X86-NOBMI-NEXT:    popl %edi
2436; X86-NOBMI-NEXT:    retl
2437;
2438; X86-BMI1NOTBM-LABEL: bextr64_b0:
2439; X86-BMI1NOTBM:       # %bb.0:
2440; X86-BMI1NOTBM-NEXT:    pushl %ebx
2441; X86-BMI1NOTBM-NEXT:    pushl %edi
2442; X86-BMI1NOTBM-NEXT:    pushl %esi
2443; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2444; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2445; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
2446; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2447; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2448; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2449; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2450; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2451; X86-BMI1NOTBM-NEXT:    je .LBB23_2
2452; X86-BMI1NOTBM-NEXT:  # %bb.1:
2453; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2454; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2455; X86-BMI1NOTBM-NEXT:  .LBB23_2:
2456; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2457; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2458; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2459; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2460; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2461; X86-BMI1NOTBM-NEXT:    testb $32, %al
2462; X86-BMI1NOTBM-NEXT:    je .LBB23_4
2463; X86-BMI1NOTBM-NEXT:  # %bb.3:
2464; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2465; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2466; X86-BMI1NOTBM-NEXT:  .LBB23_4:
2467; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2468; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2469; X86-BMI1NOTBM-NEXT:    popl %esi
2470; X86-BMI1NOTBM-NEXT:    popl %edi
2471; X86-BMI1NOTBM-NEXT:    popl %ebx
2472; X86-BMI1NOTBM-NEXT:    retl
2473;
2474; X86-BMI1BMI2-LABEL: bextr64_b0:
2475; X86-BMI1BMI2:       # %bb.0:
2476; X86-BMI1BMI2-NEXT:    pushl %ebx
2477; X86-BMI1BMI2-NEXT:    pushl %edi
2478; X86-BMI1BMI2-NEXT:    pushl %esi
2479; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2480; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2481; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2482; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2483; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
2484; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
2485; X86-BMI1BMI2-NEXT:    testb $32, %cl
2486; X86-BMI1BMI2-NEXT:    je .LBB23_2
2487; X86-BMI1BMI2-NEXT:  # %bb.1:
2488; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2489; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2490; X86-BMI1BMI2-NEXT:  .LBB23_2:
2491; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2492; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2493; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2494; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2495; X86-BMI1BMI2-NEXT:    testb $32, %al
2496; X86-BMI1BMI2-NEXT:    je .LBB23_4
2497; X86-BMI1BMI2-NEXT:  # %bb.3:
2498; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2499; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2500; X86-BMI1BMI2-NEXT:  .LBB23_4:
2501; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2502; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2503; X86-BMI1BMI2-NEXT:    popl %esi
2504; X86-BMI1BMI2-NEXT:    popl %edi
2505; X86-BMI1BMI2-NEXT:    popl %ebx
2506; X86-BMI1BMI2-NEXT:    retl
2507;
2508; X64-NOBMI-LABEL: bextr64_b0:
2509; X64-NOBMI:       # %bb.0:
2510; X64-NOBMI-NEXT:    movq %rsi, %rcx
2511; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2512; X64-NOBMI-NEXT:    shrq %cl, %rdi
2513; X64-NOBMI-NEXT:    movq $-1, %rax
2514; X64-NOBMI-NEXT:    movl %edx, %ecx
2515; X64-NOBMI-NEXT:    shlq %cl, %rax
2516; X64-NOBMI-NEXT:    notq %rax
2517; X64-NOBMI-NEXT:    andq %rdi, %rax
2518; X64-NOBMI-NEXT:    retq
2519;
2520; X64-BMI1NOTBM-LABEL: bextr64_b0:
2521; X64-BMI1NOTBM:       # %bb.0:
2522; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2523; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2524; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2525; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
2526; X64-BMI1NOTBM-NEXT:    retq
2527;
2528; X64-BMI1BMI2-LABEL: bextr64_b0:
2529; X64-BMI1BMI2:       # %bb.0:
2530; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2531; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2532; X64-BMI1BMI2-NEXT:    retq
2533  %shifted = lshr i64 %val, %numskipbits
2534  %notmask = shl i64 -1, %numlowbits
2535  %mask = xor i64 %notmask, -1
2536  %masked = and i64 %mask, %shifted
2537  ret i64 %masked
2538}
2539
2540define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2541; X86-NOBMI-LABEL: bextr64_b1_indexzext:
2542; X86-NOBMI:       # %bb.0:
2543; X86-NOBMI-NEXT:    pushl %edi
2544; X86-NOBMI-NEXT:    pushl %esi
2545; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2546; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2547; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2548; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2549; X86-NOBMI-NEXT:    movl %eax, %edi
2550; X86-NOBMI-NEXT:    shrl %cl, %edi
2551; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2552; X86-NOBMI-NEXT:    testb $32, %cl
2553; X86-NOBMI-NEXT:    je .LBB24_2
2554; X86-NOBMI-NEXT:  # %bb.1:
2555; X86-NOBMI-NEXT:    movl %edi, %esi
2556; X86-NOBMI-NEXT:    xorl %edi, %edi
2557; X86-NOBMI-NEXT:  .LBB24_2:
2558; X86-NOBMI-NEXT:    movl $-1, %edx
2559; X86-NOBMI-NEXT:    movl $-1, %eax
2560; X86-NOBMI-NEXT:    movb %ch, %cl
2561; X86-NOBMI-NEXT:    shll %cl, %eax
2562; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2563; X86-NOBMI-NEXT:    testb $32, %ch
2564; X86-NOBMI-NEXT:    je .LBB24_4
2565; X86-NOBMI-NEXT:  # %bb.3:
2566; X86-NOBMI-NEXT:    movl %eax, %edx
2567; X86-NOBMI-NEXT:    xorl %eax, %eax
2568; X86-NOBMI-NEXT:  .LBB24_4:
2569; X86-NOBMI-NEXT:    notl %edx
2570; X86-NOBMI-NEXT:    andl %edi, %edx
2571; X86-NOBMI-NEXT:    notl %eax
2572; X86-NOBMI-NEXT:    andl %esi, %eax
2573; X86-NOBMI-NEXT:    popl %esi
2574; X86-NOBMI-NEXT:    popl %edi
2575; X86-NOBMI-NEXT:    retl
2576;
2577; X86-BMI1NOTBM-LABEL: bextr64_b1_indexzext:
2578; X86-BMI1NOTBM:       # %bb.0:
2579; X86-BMI1NOTBM-NEXT:    pushl %ebx
2580; X86-BMI1NOTBM-NEXT:    pushl %edi
2581; X86-BMI1NOTBM-NEXT:    pushl %esi
2582; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2583; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2584; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
2585; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
2586; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2587; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2588; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2589; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2590; X86-BMI1NOTBM-NEXT:    je .LBB24_2
2591; X86-BMI1NOTBM-NEXT:  # %bb.1:
2592; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2593; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2594; X86-BMI1NOTBM-NEXT:  .LBB24_2:
2595; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2596; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2597; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2598; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2599; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2600; X86-BMI1NOTBM-NEXT:    testb $32, %al
2601; X86-BMI1NOTBM-NEXT:    je .LBB24_4
2602; X86-BMI1NOTBM-NEXT:  # %bb.3:
2603; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2604; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2605; X86-BMI1NOTBM-NEXT:  .LBB24_4:
2606; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2607; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2608; X86-BMI1NOTBM-NEXT:    popl %esi
2609; X86-BMI1NOTBM-NEXT:    popl %edi
2610; X86-BMI1NOTBM-NEXT:    popl %ebx
2611; X86-BMI1NOTBM-NEXT:    retl
2612;
2613; X86-BMI1BMI2-LABEL: bextr64_b1_indexzext:
2614; X86-BMI1BMI2:       # %bb.0:
2615; X86-BMI1BMI2-NEXT:    pushl %ebx
2616; X86-BMI1BMI2-NEXT:    pushl %edi
2617; X86-BMI1BMI2-NEXT:    pushl %esi
2618; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2619; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2620; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2621; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2622; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
2623; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
2624; X86-BMI1BMI2-NEXT:    testb $32, %cl
2625; X86-BMI1BMI2-NEXT:    je .LBB24_2
2626; X86-BMI1BMI2-NEXT:  # %bb.1:
2627; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2628; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2629; X86-BMI1BMI2-NEXT:  .LBB24_2:
2630; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2631; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2632; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2633; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2634; X86-BMI1BMI2-NEXT:    testb $32, %al
2635; X86-BMI1BMI2-NEXT:    je .LBB24_4
2636; X86-BMI1BMI2-NEXT:  # %bb.3:
2637; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2638; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2639; X86-BMI1BMI2-NEXT:  .LBB24_4:
2640; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2641; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2642; X86-BMI1BMI2-NEXT:    popl %esi
2643; X86-BMI1BMI2-NEXT:    popl %edi
2644; X86-BMI1BMI2-NEXT:    popl %ebx
2645; X86-BMI1BMI2-NEXT:    retl
2646;
2647; X64-NOBMI-LABEL: bextr64_b1_indexzext:
2648; X64-NOBMI:       # %bb.0:
2649; X64-NOBMI-NEXT:    movl %esi, %ecx
2650; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2651; X64-NOBMI-NEXT:    shrq %cl, %rdi
2652; X64-NOBMI-NEXT:    movq $-1, %rax
2653; X64-NOBMI-NEXT:    movl %edx, %ecx
2654; X64-NOBMI-NEXT:    shlq %cl, %rax
2655; X64-NOBMI-NEXT:    notq %rax
2656; X64-NOBMI-NEXT:    andq %rdi, %rax
2657; X64-NOBMI-NEXT:    retq
2658;
2659; X64-BMI1NOTBM-LABEL: bextr64_b1_indexzext:
2660; X64-BMI1NOTBM:       # %bb.0:
2661; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
2662; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2663; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2664; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2665; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
2666; X64-BMI1NOTBM-NEXT:    retq
2667;
2668; X64-BMI1BMI2-LABEL: bextr64_b1_indexzext:
2669; X64-BMI1BMI2:       # %bb.0:
2670; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
2671; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2672; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2673; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2674; X64-BMI1BMI2-NEXT:    retq
2675  %skip = zext i8 %numskipbits to i64
2676  %shifted = lshr i64 %val, %skip
2677  %conv = zext i8 %numlowbits to i64
2678  %notmask = shl i64 -1, %conv
2679  %mask = xor i64 %notmask, -1
2680  %masked = and i64 %mask, %shifted
2681  ret i64 %masked
2682}
2683
2684define i64 @bextr64_b2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
2685; X86-NOBMI-LABEL: bextr64_b2_load:
2686; X86-NOBMI:       # %bb.0:
2687; X86-NOBMI-NEXT:    pushl %edi
2688; X86-NOBMI-NEXT:    pushl %esi
2689; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2690; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2691; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2692; X86-NOBMI-NEXT:    movl (%eax), %esi
2693; X86-NOBMI-NEXT:    movl 4(%eax), %eax
2694; X86-NOBMI-NEXT:    movl %eax, %edi
2695; X86-NOBMI-NEXT:    shrl %cl, %edi
2696; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2697; X86-NOBMI-NEXT:    testb $32, %cl
2698; X86-NOBMI-NEXT:    je .LBB25_2
2699; X86-NOBMI-NEXT:  # %bb.1:
2700; X86-NOBMI-NEXT:    movl %edi, %esi
2701; X86-NOBMI-NEXT:    xorl %edi, %edi
2702; X86-NOBMI-NEXT:  .LBB25_2:
2703; X86-NOBMI-NEXT:    movl $-1, %edx
2704; X86-NOBMI-NEXT:    movl $-1, %eax
2705; X86-NOBMI-NEXT:    movb %ch, %cl
2706; X86-NOBMI-NEXT:    shll %cl, %eax
2707; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2708; X86-NOBMI-NEXT:    testb $32, %ch
2709; X86-NOBMI-NEXT:    je .LBB25_4
2710; X86-NOBMI-NEXT:  # %bb.3:
2711; X86-NOBMI-NEXT:    movl %eax, %edx
2712; X86-NOBMI-NEXT:    xorl %eax, %eax
2713; X86-NOBMI-NEXT:  .LBB25_4:
2714; X86-NOBMI-NEXT:    notl %edx
2715; X86-NOBMI-NEXT:    andl %edi, %edx
2716; X86-NOBMI-NEXT:    notl %eax
2717; X86-NOBMI-NEXT:    andl %esi, %eax
2718; X86-NOBMI-NEXT:    popl %esi
2719; X86-NOBMI-NEXT:    popl %edi
2720; X86-NOBMI-NEXT:    retl
2721;
2722; X86-BMI1NOTBM-LABEL: bextr64_b2_load:
2723; X86-BMI1NOTBM:       # %bb.0:
2724; X86-BMI1NOTBM-NEXT:    pushl %ebx
2725; X86-BMI1NOTBM-NEXT:    pushl %edi
2726; X86-BMI1NOTBM-NEXT:    pushl %esi
2727; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2728; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2729; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2730; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2731; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2732; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2733; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2734; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2735; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2736; X86-BMI1NOTBM-NEXT:    je .LBB25_2
2737; X86-BMI1NOTBM-NEXT:  # %bb.1:
2738; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2739; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2740; X86-BMI1NOTBM-NEXT:  .LBB25_2:
2741; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2742; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2743; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2744; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2745; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2746; X86-BMI1NOTBM-NEXT:    testb $32, %al
2747; X86-BMI1NOTBM-NEXT:    je .LBB25_4
2748; X86-BMI1NOTBM-NEXT:  # %bb.3:
2749; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2750; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2751; X86-BMI1NOTBM-NEXT:  .LBB25_4:
2752; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2753; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2754; X86-BMI1NOTBM-NEXT:    popl %esi
2755; X86-BMI1NOTBM-NEXT:    popl %edi
2756; X86-BMI1NOTBM-NEXT:    popl %ebx
2757; X86-BMI1NOTBM-NEXT:    retl
2758;
2759; X86-BMI1BMI2-LABEL: bextr64_b2_load:
2760; X86-BMI1BMI2:       # %bb.0:
2761; X86-BMI1BMI2-NEXT:    pushl %ebx
2762; X86-BMI1BMI2-NEXT:    pushl %edi
2763; X86-BMI1BMI2-NEXT:    pushl %esi
2764; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2765; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2766; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2767; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2768; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2769; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edi, %edx
2770; X86-BMI1BMI2-NEXT:    shrdl %cl, %edi, %esi
2771; X86-BMI1BMI2-NEXT:    testb $32, %cl
2772; X86-BMI1BMI2-NEXT:    je .LBB25_2
2773; X86-BMI1BMI2-NEXT:  # %bb.1:
2774; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2775; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2776; X86-BMI1BMI2-NEXT:  .LBB25_2:
2777; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2778; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2779; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2780; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2781; X86-BMI1BMI2-NEXT:    testb $32, %al
2782; X86-BMI1BMI2-NEXT:    je .LBB25_4
2783; X86-BMI1BMI2-NEXT:  # %bb.3:
2784; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2785; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2786; X86-BMI1BMI2-NEXT:  .LBB25_4:
2787; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2788; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2789; X86-BMI1BMI2-NEXT:    popl %esi
2790; X86-BMI1BMI2-NEXT:    popl %edi
2791; X86-BMI1BMI2-NEXT:    popl %ebx
2792; X86-BMI1BMI2-NEXT:    retl
2793;
2794; X64-NOBMI-LABEL: bextr64_b2_load:
2795; X64-NOBMI:       # %bb.0:
2796; X64-NOBMI-NEXT:    movq %rsi, %rcx
2797; X64-NOBMI-NEXT:    movq (%rdi), %rsi
2798; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2799; X64-NOBMI-NEXT:    shrq %cl, %rsi
2800; X64-NOBMI-NEXT:    movq $-1, %rax
2801; X64-NOBMI-NEXT:    movl %edx, %ecx
2802; X64-NOBMI-NEXT:    shlq %cl, %rax
2803; X64-NOBMI-NEXT:    notq %rax
2804; X64-NOBMI-NEXT:    andq %rsi, %rax
2805; X64-NOBMI-NEXT:    retq
2806;
2807; X64-BMI1NOTBM-LABEL: bextr64_b2_load:
2808; X64-BMI1NOTBM:       # %bb.0:
2809; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2810; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2811; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2812; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
2813; X64-BMI1NOTBM-NEXT:    retq
2814;
2815; X64-BMI1BMI2-LABEL: bextr64_b2_load:
2816; X64-BMI1BMI2:       # %bb.0:
2817; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
2818; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2819; X64-BMI1BMI2-NEXT:    retq
2820  %val = load i64, i64* %w
2821  %shifted = lshr i64 %val, %numskipbits
2822  %notmask = shl i64 -1, %numlowbits
2823  %mask = xor i64 %notmask, -1
2824  %masked = and i64 %mask, %shifted
2825  ret i64 %masked
2826}
2827
2828define i64 @bextr64_b3_load_indexzext(i64* %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2829; X86-NOBMI-LABEL: bextr64_b3_load_indexzext:
2830; X86-NOBMI:       # %bb.0:
2831; X86-NOBMI-NEXT:    pushl %edi
2832; X86-NOBMI-NEXT:    pushl %esi
2833; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2834; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2835; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2836; X86-NOBMI-NEXT:    movl (%eax), %esi
2837; X86-NOBMI-NEXT:    movl 4(%eax), %eax
2838; X86-NOBMI-NEXT:    movl %eax, %edi
2839; X86-NOBMI-NEXT:    shrl %cl, %edi
2840; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2841; X86-NOBMI-NEXT:    testb $32, %cl
2842; X86-NOBMI-NEXT:    je .LBB26_2
2843; X86-NOBMI-NEXT:  # %bb.1:
2844; X86-NOBMI-NEXT:    movl %edi, %esi
2845; X86-NOBMI-NEXT:    xorl %edi, %edi
2846; X86-NOBMI-NEXT:  .LBB26_2:
2847; X86-NOBMI-NEXT:    movl $-1, %edx
2848; X86-NOBMI-NEXT:    movl $-1, %eax
2849; X86-NOBMI-NEXT:    movb %ch, %cl
2850; X86-NOBMI-NEXT:    shll %cl, %eax
2851; X86-NOBMI-NEXT:    shldl %cl, %edx, %edx
2852; X86-NOBMI-NEXT:    testb $32, %ch
2853; X86-NOBMI-NEXT:    je .LBB26_4
2854; X86-NOBMI-NEXT:  # %bb.3:
2855; X86-NOBMI-NEXT:    movl %eax, %edx
2856; X86-NOBMI-NEXT:    xorl %eax, %eax
2857; X86-NOBMI-NEXT:  .LBB26_4:
2858; X86-NOBMI-NEXT:    notl %edx
2859; X86-NOBMI-NEXT:    andl %edi, %edx
2860; X86-NOBMI-NEXT:    notl %eax
2861; X86-NOBMI-NEXT:    andl %esi, %eax
2862; X86-NOBMI-NEXT:    popl %esi
2863; X86-NOBMI-NEXT:    popl %edi
2864; X86-NOBMI-NEXT:    retl
2865;
2866; X86-BMI1NOTBM-LABEL: bextr64_b3_load_indexzext:
2867; X86-BMI1NOTBM:       # %bb.0:
2868; X86-BMI1NOTBM-NEXT:    pushl %ebx
2869; X86-BMI1NOTBM-NEXT:    pushl %edi
2870; X86-BMI1NOTBM-NEXT:    pushl %esi
2871; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
2872; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
2873; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
2874; X86-BMI1NOTBM-NEXT:    movl (%edx), %esi
2875; X86-BMI1NOTBM-NEXT:    movl 4(%edx), %edi
2876; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
2877; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
2878; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
2879; X86-BMI1NOTBM-NEXT:    testb $32, %cl
2880; X86-BMI1NOTBM-NEXT:    je .LBB26_2
2881; X86-BMI1NOTBM-NEXT:  # %bb.1:
2882; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
2883; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
2884; X86-BMI1NOTBM-NEXT:  .LBB26_2:
2885; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
2886; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
2887; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
2888; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
2889; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
2890; X86-BMI1NOTBM-NEXT:    testb $32, %al
2891; X86-BMI1NOTBM-NEXT:    je .LBB26_4
2892; X86-BMI1NOTBM-NEXT:  # %bb.3:
2893; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
2894; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
2895; X86-BMI1NOTBM-NEXT:  .LBB26_4:
2896; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
2897; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
2898; X86-BMI1NOTBM-NEXT:    popl %esi
2899; X86-BMI1NOTBM-NEXT:    popl %edi
2900; X86-BMI1NOTBM-NEXT:    popl %ebx
2901; X86-BMI1NOTBM-NEXT:    retl
2902;
2903; X86-BMI1BMI2-LABEL: bextr64_b3_load_indexzext:
2904; X86-BMI1BMI2:       # %bb.0:
2905; X86-BMI1BMI2-NEXT:    pushl %ebx
2906; X86-BMI1BMI2-NEXT:    pushl %edi
2907; X86-BMI1BMI2-NEXT:    pushl %esi
2908; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
2909; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
2910; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2911; X86-BMI1BMI2-NEXT:    movl (%edx), %esi
2912; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edi
2913; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edi, %edx
2914; X86-BMI1BMI2-NEXT:    shrdl %cl, %edi, %esi
2915; X86-BMI1BMI2-NEXT:    testb $32, %cl
2916; X86-BMI1BMI2-NEXT:    je .LBB26_2
2917; X86-BMI1BMI2-NEXT:  # %bb.1:
2918; X86-BMI1BMI2-NEXT:    movl %edx, %esi
2919; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
2920; X86-BMI1BMI2-NEXT:  .LBB26_2:
2921; X86-BMI1BMI2-NEXT:    movl $-1, %edi
2922; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
2923; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
2924; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
2925; X86-BMI1BMI2-NEXT:    testb $32, %al
2926; X86-BMI1BMI2-NEXT:    je .LBB26_4
2927; X86-BMI1BMI2-NEXT:  # %bb.3:
2928; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
2929; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
2930; X86-BMI1BMI2-NEXT:  .LBB26_4:
2931; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
2932; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
2933; X86-BMI1BMI2-NEXT:    popl %esi
2934; X86-BMI1BMI2-NEXT:    popl %edi
2935; X86-BMI1BMI2-NEXT:    popl %ebx
2936; X86-BMI1BMI2-NEXT:    retl
2937;
2938; X64-NOBMI-LABEL: bextr64_b3_load_indexzext:
2939; X64-NOBMI:       # %bb.0:
2940; X64-NOBMI-NEXT:    movl %esi, %ecx
2941; X64-NOBMI-NEXT:    movq (%rdi), %rsi
2942; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2943; X64-NOBMI-NEXT:    shrq %cl, %rsi
2944; X64-NOBMI-NEXT:    movq $-1, %rax
2945; X64-NOBMI-NEXT:    movl %edx, %ecx
2946; X64-NOBMI-NEXT:    shlq %cl, %rax
2947; X64-NOBMI-NEXT:    notq %rax
2948; X64-NOBMI-NEXT:    andq %rsi, %rax
2949; X64-NOBMI-NEXT:    retq
2950;
2951; X64-BMI1NOTBM-LABEL: bextr64_b3_load_indexzext:
2952; X64-BMI1NOTBM:       # %bb.0:
2953; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
2954; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
2955; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
2956; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
2957; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
2958; X64-BMI1NOTBM-NEXT:    retq
2959;
2960; X64-BMI1BMI2-LABEL: bextr64_b3_load_indexzext:
2961; X64-BMI1BMI2:       # %bb.0:
2962; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
2963; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2964; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
2965; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2966; X64-BMI1BMI2-NEXT:    retq
2967  %val = load i64, i64* %w
2968  %skip = zext i8 %numskipbits to i64
2969  %shifted = lshr i64 %val, %skip
2970  %conv = zext i8 %numlowbits to i64
2971  %notmask = shl i64 -1, %conv
2972  %mask = xor i64 %notmask, -1
2973  %masked = and i64 %mask, %shifted
2974  ret i64 %masked
2975}
2976
2977define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2978; X86-NOBMI-LABEL: bextr64_b4_commutative:
2979; X86-NOBMI:       # %bb.0:
2980; X86-NOBMI-NEXT:    pushl %edi
2981; X86-NOBMI-NEXT:    pushl %esi
2982; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2983; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2984; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2985; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2986; X86-NOBMI-NEXT:    movl %esi, %edx
2987; X86-NOBMI-NEXT:    shrl %cl, %edx
2988; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
2989; X86-NOBMI-NEXT:    testb $32, %cl
2990; X86-NOBMI-NEXT:    je .LBB27_2
2991; X86-NOBMI-NEXT:  # %bb.1:
2992; X86-NOBMI-NEXT:    movl %edx, %eax
2993; X86-NOBMI-NEXT:    xorl %edx, %edx
2994; X86-NOBMI-NEXT:  .LBB27_2:
2995; X86-NOBMI-NEXT:    movl $-1, %edi
2996; X86-NOBMI-NEXT:    movl $-1, %esi
2997; X86-NOBMI-NEXT:    movb %ch, %cl
2998; X86-NOBMI-NEXT:    shll %cl, %esi
2999; X86-NOBMI-NEXT:    shldl %cl, %edi, %edi
3000; X86-NOBMI-NEXT:    testb $32, %ch
3001; X86-NOBMI-NEXT:    je .LBB27_4
3002; X86-NOBMI-NEXT:  # %bb.3:
3003; X86-NOBMI-NEXT:    movl %esi, %edi
3004; X86-NOBMI-NEXT:    xorl %esi, %esi
3005; X86-NOBMI-NEXT:  .LBB27_4:
3006; X86-NOBMI-NEXT:    notl %edi
3007; X86-NOBMI-NEXT:    andl %edi, %edx
3008; X86-NOBMI-NEXT:    notl %esi
3009; X86-NOBMI-NEXT:    andl %esi, %eax
3010; X86-NOBMI-NEXT:    popl %esi
3011; X86-NOBMI-NEXT:    popl %edi
3012; X86-NOBMI-NEXT:    retl
3013;
3014; X86-BMI1NOTBM-LABEL: bextr64_b4_commutative:
3015; X86-BMI1NOTBM:       # %bb.0:
3016; X86-BMI1NOTBM-NEXT:    pushl %ebx
3017; X86-BMI1NOTBM-NEXT:    pushl %edi
3018; X86-BMI1NOTBM-NEXT:    pushl %esi
3019; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
3020; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3021; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
3022; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3023; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
3024; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
3025; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
3026; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3027; X86-BMI1NOTBM-NEXT:    je .LBB27_2
3028; X86-BMI1NOTBM-NEXT:  # %bb.1:
3029; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
3030; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
3031; X86-BMI1NOTBM-NEXT:  .LBB27_2:
3032; X86-BMI1NOTBM-NEXT:    movl $-1, %edi
3033; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
3034; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
3035; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
3036; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %edi
3037; X86-BMI1NOTBM-NEXT:    testb $32, %al
3038; X86-BMI1NOTBM-NEXT:    je .LBB27_4
3039; X86-BMI1NOTBM-NEXT:  # %bb.3:
3040; X86-BMI1NOTBM-NEXT:    movl %ebx, %edi
3041; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
3042; X86-BMI1NOTBM-NEXT:  .LBB27_4:
3043; X86-BMI1NOTBM-NEXT:    andnl %edx, %edi, %edx
3044; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %eax
3045; X86-BMI1NOTBM-NEXT:    popl %esi
3046; X86-BMI1NOTBM-NEXT:    popl %edi
3047; X86-BMI1NOTBM-NEXT:    popl %ebx
3048; X86-BMI1NOTBM-NEXT:    retl
3049;
3050; X86-BMI1BMI2-LABEL: bextr64_b4_commutative:
3051; X86-BMI1BMI2:       # %bb.0:
3052; X86-BMI1BMI2-NEXT:    pushl %ebx
3053; X86-BMI1BMI2-NEXT:    pushl %edi
3054; X86-BMI1BMI2-NEXT:    pushl %esi
3055; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3056; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3057; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3058; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3059; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %esi
3060; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
3061; X86-BMI1BMI2-NEXT:    testb $32, %cl
3062; X86-BMI1BMI2-NEXT:    je .LBB27_2
3063; X86-BMI1BMI2-NEXT:  # %bb.1:
3064; X86-BMI1BMI2-NEXT:    movl %edx, %esi
3065; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
3066; X86-BMI1BMI2-NEXT:  .LBB27_2:
3067; X86-BMI1BMI2-NEXT:    movl $-1, %edi
3068; X86-BMI1BMI2-NEXT:    shlxl %eax, %edi, %ebx
3069; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
3070; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edi
3071; X86-BMI1BMI2-NEXT:    testb $32, %al
3072; X86-BMI1BMI2-NEXT:    je .LBB27_4
3073; X86-BMI1BMI2-NEXT:  # %bb.3:
3074; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
3075; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
3076; X86-BMI1BMI2-NEXT:  .LBB27_4:
3077; X86-BMI1BMI2-NEXT:    andnl %edx, %edi, %edx
3078; X86-BMI1BMI2-NEXT:    andnl %esi, %ebx, %eax
3079; X86-BMI1BMI2-NEXT:    popl %esi
3080; X86-BMI1BMI2-NEXT:    popl %edi
3081; X86-BMI1BMI2-NEXT:    popl %ebx
3082; X86-BMI1BMI2-NEXT:    retl
3083;
3084; X64-NOBMI-LABEL: bextr64_b4_commutative:
3085; X64-NOBMI:       # %bb.0:
3086; X64-NOBMI-NEXT:    movq %rsi, %rcx
3087; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3088; X64-NOBMI-NEXT:    shrq %cl, %rdi
3089; X64-NOBMI-NEXT:    movq $-1, %rax
3090; X64-NOBMI-NEXT:    movl %edx, %ecx
3091; X64-NOBMI-NEXT:    shlq %cl, %rax
3092; X64-NOBMI-NEXT:    notq %rax
3093; X64-NOBMI-NEXT:    andq %rdi, %rax
3094; X64-NOBMI-NEXT:    retq
3095;
3096; X64-BMI1NOTBM-LABEL: bextr64_b4_commutative:
3097; X64-BMI1NOTBM:       # %bb.0:
3098; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
3099; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
3100; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
3101; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
3102; X64-BMI1NOTBM-NEXT:    retq
3103;
3104; X64-BMI1BMI2-LABEL: bextr64_b4_commutative:
3105; X64-BMI1BMI2:       # %bb.0:
3106; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3107; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
3108; X64-BMI1BMI2-NEXT:    retq
3109  %shifted = lshr i64 %val, %numskipbits
3110  %notmask = shl i64 -1, %numlowbits
3111  %mask = xor i64 %notmask, -1
3112  %masked = and i64 %shifted, %mask ; swapped order
3113  ret i64 %masked
3114}
3115
3116define i64 @bextr64_b5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
3117; X86-NOBMI-LABEL: bextr64_b5_skipextrauses:
3118; X86-NOBMI:       # %bb.0:
3119; X86-NOBMI-NEXT:    pushl %ebp
3120; X86-NOBMI-NEXT:    pushl %ebx
3121; X86-NOBMI-NEXT:    pushl %edi
3122; X86-NOBMI-NEXT:    pushl %esi
3123; X86-NOBMI-NEXT:    subl $12, %esp
3124; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
3125; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
3126; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3127; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3128; X86-NOBMI-NEXT:    movl %esi, %ebp
3129; X86-NOBMI-NEXT:    movl %eax, %ecx
3130; X86-NOBMI-NEXT:    shrl %cl, %ebp
3131; X86-NOBMI-NEXT:    shrdl %cl, %esi, %ebx
3132; X86-NOBMI-NEXT:    testb $32, %al
3133; X86-NOBMI-NEXT:    je .LBB28_2
3134; X86-NOBMI-NEXT:  # %bb.1:
3135; X86-NOBMI-NEXT:    movl %ebp, %ebx
3136; X86-NOBMI-NEXT:    xorl %ebp, %ebp
3137; X86-NOBMI-NEXT:  .LBB28_2:
3138; X86-NOBMI-NEXT:    movl $-1, %esi
3139; X86-NOBMI-NEXT:    movl $-1, %edi
3140; X86-NOBMI-NEXT:    movl %edx, %ecx
3141; X86-NOBMI-NEXT:    shll %cl, %edi
3142; X86-NOBMI-NEXT:    shldl %cl, %esi, %esi
3143; X86-NOBMI-NEXT:    testb $32, %dl
3144; X86-NOBMI-NEXT:    je .LBB28_4
3145; X86-NOBMI-NEXT:  # %bb.3:
3146; X86-NOBMI-NEXT:    movl %edi, %esi
3147; X86-NOBMI-NEXT:    xorl %edi, %edi
3148; X86-NOBMI-NEXT:  .LBB28_4:
3149; X86-NOBMI-NEXT:    notl %esi
3150; X86-NOBMI-NEXT:    andl %ebp, %esi
3151; X86-NOBMI-NEXT:    notl %edi
3152; X86-NOBMI-NEXT:    andl %ebx, %edi
3153; X86-NOBMI-NEXT:    subl $8, %esp
3154; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
3155; X86-NOBMI-NEXT:    pushl %eax
3156; X86-NOBMI-NEXT:    calll use64
3157; X86-NOBMI-NEXT:    addl $16, %esp
3158; X86-NOBMI-NEXT:    movl %edi, %eax
3159; X86-NOBMI-NEXT:    movl %esi, %edx
3160; X86-NOBMI-NEXT:    addl $12, %esp
3161; X86-NOBMI-NEXT:    popl %esi
3162; X86-NOBMI-NEXT:    popl %edi
3163; X86-NOBMI-NEXT:    popl %ebx
3164; X86-NOBMI-NEXT:    popl %ebp
3165; X86-NOBMI-NEXT:    retl
3166;
3167; X86-BMI1NOTBM-LABEL: bextr64_b5_skipextrauses:
3168; X86-BMI1NOTBM:       # %bb.0:
3169; X86-BMI1NOTBM-NEXT:    pushl %ebp
3170; X86-BMI1NOTBM-NEXT:    pushl %ebx
3171; X86-BMI1NOTBM-NEXT:    pushl %edi
3172; X86-BMI1NOTBM-NEXT:    pushl %esi
3173; X86-BMI1NOTBM-NEXT:    subl $12, %esp
3174; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %dl
3175; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3176; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
3177; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3178; X86-BMI1NOTBM-NEXT:    movl %ebx, %esi
3179; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
3180; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3181; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %edi
3182; X86-BMI1NOTBM-NEXT:    testb $32, %al
3183; X86-BMI1NOTBM-NEXT:    je .LBB28_2
3184; X86-BMI1NOTBM-NEXT:  # %bb.1:
3185; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
3186; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
3187; X86-BMI1NOTBM-NEXT:  .LBB28_2:
3188; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
3189; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
3190; X86-BMI1NOTBM-NEXT:    movl %edx, %ecx
3191; X86-BMI1NOTBM-NEXT:    shll %cl, %ebp
3192; X86-BMI1NOTBM-NEXT:    shldl %cl, %ebx, %ebx
3193; X86-BMI1NOTBM-NEXT:    testb $32, %dl
3194; X86-BMI1NOTBM-NEXT:    je .LBB28_4
3195; X86-BMI1NOTBM-NEXT:  # %bb.3:
3196; X86-BMI1NOTBM-NEXT:    movl %ebp, %ebx
3197; X86-BMI1NOTBM-NEXT:    xorl %ebp, %ebp
3198; X86-BMI1NOTBM-NEXT:  .LBB28_4:
3199; X86-BMI1NOTBM-NEXT:    andnl %esi, %ebx, %esi
3200; X86-BMI1NOTBM-NEXT:    andnl %edi, %ebp, %edi
3201; X86-BMI1NOTBM-NEXT:    subl $8, %esp
3202; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
3203; X86-BMI1NOTBM-NEXT:    pushl %eax
3204; X86-BMI1NOTBM-NEXT:    calll use64
3205; X86-BMI1NOTBM-NEXT:    addl $16, %esp
3206; X86-BMI1NOTBM-NEXT:    movl %edi, %eax
3207; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
3208; X86-BMI1NOTBM-NEXT:    addl $12, %esp
3209; X86-BMI1NOTBM-NEXT:    popl %esi
3210; X86-BMI1NOTBM-NEXT:    popl %edi
3211; X86-BMI1NOTBM-NEXT:    popl %ebx
3212; X86-BMI1NOTBM-NEXT:    popl %ebp
3213; X86-BMI1NOTBM-NEXT:    retl
3214;
3215; X86-BMI1BMI2-LABEL: bextr64_b5_skipextrauses:
3216; X86-BMI1BMI2:       # %bb.0:
3217; X86-BMI1BMI2-NEXT:    pushl %ebp
3218; X86-BMI1BMI2-NEXT:    pushl %ebx
3219; X86-BMI1BMI2-NEXT:    pushl %edi
3220; X86-BMI1BMI2-NEXT:    pushl %esi
3221; X86-BMI1BMI2-NEXT:    subl $12, %esp
3222; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
3223; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
3224; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3225; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3226; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
3227; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
3228; X86-BMI1BMI2-NEXT:    shrxl %eax, %esi, %esi
3229; X86-BMI1BMI2-NEXT:    testb $32, %al
3230; X86-BMI1BMI2-NEXT:    je .LBB28_2
3231; X86-BMI1BMI2-NEXT:  # %bb.1:
3232; X86-BMI1BMI2-NEXT:    movl %esi, %edi
3233; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
3234; X86-BMI1BMI2-NEXT:  .LBB28_2:
3235; X86-BMI1BMI2-NEXT:    movl $-1, %ebp
3236; X86-BMI1BMI2-NEXT:    shlxl %edx, %ebp, %ebx
3237; X86-BMI1BMI2-NEXT:    movl %edx, %ecx
3238; X86-BMI1BMI2-NEXT:    shldl %cl, %ebp, %ebp
3239; X86-BMI1BMI2-NEXT:    testb $32, %dl
3240; X86-BMI1BMI2-NEXT:    je .LBB28_4
3241; X86-BMI1BMI2-NEXT:  # %bb.3:
3242; X86-BMI1BMI2-NEXT:    movl %ebx, %ebp
3243; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
3244; X86-BMI1BMI2-NEXT:  .LBB28_4:
3245; X86-BMI1BMI2-NEXT:    andnl %esi, %ebp, %esi
3246; X86-BMI1BMI2-NEXT:    andnl %edi, %ebx, %edi
3247; X86-BMI1BMI2-NEXT:    subl $8, %esp
3248; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
3249; X86-BMI1BMI2-NEXT:    pushl %eax
3250; X86-BMI1BMI2-NEXT:    calll use64
3251; X86-BMI1BMI2-NEXT:    addl $16, %esp
3252; X86-BMI1BMI2-NEXT:    movl %edi, %eax
3253; X86-BMI1BMI2-NEXT:    movl %esi, %edx
3254; X86-BMI1BMI2-NEXT:    addl $12, %esp
3255; X86-BMI1BMI2-NEXT:    popl %esi
3256; X86-BMI1BMI2-NEXT:    popl %edi
3257; X86-BMI1BMI2-NEXT:    popl %ebx
3258; X86-BMI1BMI2-NEXT:    popl %ebp
3259; X86-BMI1BMI2-NEXT:    retl
3260;
3261; X64-NOBMI-LABEL: bextr64_b5_skipextrauses:
3262; X64-NOBMI:       # %bb.0:
3263; X64-NOBMI-NEXT:    pushq %rbx
3264; X64-NOBMI-NEXT:    movl %esi, %ecx
3265; X64-NOBMI-NEXT:    shrq %cl, %rdi
3266; X64-NOBMI-NEXT:    movq $-1, %rbx
3267; X64-NOBMI-NEXT:    movl %edx, %ecx
3268; X64-NOBMI-NEXT:    shlq %cl, %rbx
3269; X64-NOBMI-NEXT:    notq %rbx
3270; X64-NOBMI-NEXT:    andq %rdi, %rbx
3271; X64-NOBMI-NEXT:    movq %rsi, %rdi
3272; X64-NOBMI-NEXT:    callq use64
3273; X64-NOBMI-NEXT:    movq %rbx, %rax
3274; X64-NOBMI-NEXT:    popq %rbx
3275; X64-NOBMI-NEXT:    retq
3276;
3277; X64-BMI1NOTBM-LABEL: bextr64_b5_skipextrauses:
3278; X64-BMI1NOTBM:       # %bb.0:
3279; X64-BMI1NOTBM-NEXT:    pushq %rbx
3280; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
3281; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
3282; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
3283; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rbx
3284; X64-BMI1NOTBM-NEXT:    movq %rsi, %rdi
3285; X64-BMI1NOTBM-NEXT:    callq use64
3286; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
3287; X64-BMI1NOTBM-NEXT:    popq %rbx
3288; X64-BMI1NOTBM-NEXT:    retq
3289;
3290; X64-BMI1BMI2-LABEL: bextr64_b5_skipextrauses:
3291; X64-BMI1BMI2:       # %bb.0:
3292; X64-BMI1BMI2-NEXT:    pushq %rbx
3293; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3294; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
3295; X64-BMI1BMI2-NEXT:    movq %rsi, %rdi
3296; X64-BMI1BMI2-NEXT:    callq use64
3297; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
3298; X64-BMI1BMI2-NEXT:    popq %rbx
3299; X64-BMI1BMI2-NEXT:    retq
3300  %shifted = lshr i64 %val, %numskipbits
3301  %notmask = shl i64 -1, %numlowbits
3302  %mask = xor i64 %notmask, -1
3303  %masked = and i64 %mask, %shifted
3304  call void @use64(i64 %numskipbits)
3305  ret i64 %masked
3306}
3307
3308; 64-bit, but with 32-bit output
3309
3310; Everything done in 64-bit, truncation happens last.
3311define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3312; X86-NOBMI-LABEL: bextr64_32_b0:
3313; X86-NOBMI:       # %bb.0:
3314; X86-NOBMI-NEXT:    pushl %edi
3315; X86-NOBMI-NEXT:    pushl %esi
3316; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
3317; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3318; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3319; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3320; X86-NOBMI-NEXT:    movl %edi, %eax
3321; X86-NOBMI-NEXT:    shrl %cl, %eax
3322; X86-NOBMI-NEXT:    shrdl %cl, %edi, %esi
3323; X86-NOBMI-NEXT:    testb $32, %cl
3324; X86-NOBMI-NEXT:    jne .LBB29_2
3325; X86-NOBMI-NEXT:  # %bb.1:
3326; X86-NOBMI-NEXT:    movl %esi, %eax
3327; X86-NOBMI-NEXT:  .LBB29_2:
3328; X86-NOBMI-NEXT:    movl $-1, %esi
3329; X86-NOBMI-NEXT:    movl %edx, %ecx
3330; X86-NOBMI-NEXT:    shll %cl, %esi
3331; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3332; X86-NOBMI-NEXT:    testb $32, %dl
3333; X86-NOBMI-NEXT:    jne .LBB29_4
3334; X86-NOBMI-NEXT:  # %bb.3:
3335; X86-NOBMI-NEXT:    movl %esi, %ecx
3336; X86-NOBMI-NEXT:  .LBB29_4:
3337; X86-NOBMI-NEXT:    notl %ecx
3338; X86-NOBMI-NEXT:    andl %ecx, %eax
3339; X86-NOBMI-NEXT:    popl %esi
3340; X86-NOBMI-NEXT:    popl %edi
3341; X86-NOBMI-NEXT:    retl
3342;
3343; X86-BMI1NOTBM-LABEL: bextr64_32_b0:
3344; X86-BMI1NOTBM:       # %bb.0:
3345; X86-BMI1NOTBM-NEXT:    pushl %edi
3346; X86-BMI1NOTBM-NEXT:    pushl %esi
3347; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
3348; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3349; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
3350; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3351; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
3352; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
3353; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
3354; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3355; X86-BMI1NOTBM-NEXT:    jne .LBB29_2
3356; X86-BMI1NOTBM-NEXT:  # %bb.1:
3357; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
3358; X86-BMI1NOTBM-NEXT:  .LBB29_2:
3359; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3360; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
3361; X86-BMI1NOTBM-NEXT:    shll %cl, %esi
3362; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3363; X86-BMI1NOTBM-NEXT:    testb $32, %al
3364; X86-BMI1NOTBM-NEXT:    jne .LBB29_4
3365; X86-BMI1NOTBM-NEXT:  # %bb.3:
3366; X86-BMI1NOTBM-NEXT:    movl %esi, %ecx
3367; X86-BMI1NOTBM-NEXT:  .LBB29_4:
3368; X86-BMI1NOTBM-NEXT:    andnl %edx, %ecx, %eax
3369; X86-BMI1NOTBM-NEXT:    popl %esi
3370; X86-BMI1NOTBM-NEXT:    popl %edi
3371; X86-BMI1NOTBM-NEXT:    retl
3372;
3373; X86-BMI1BMI2-LABEL: bextr64_32_b0:
3374; X86-BMI1BMI2:       # %bb.0:
3375; X86-BMI1BMI2-NEXT:    pushl %esi
3376; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3377; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3378; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3379; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3380; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
3381; X86-BMI1BMI2-NEXT:    testb $32, %cl
3382; X86-BMI1BMI2-NEXT:    je .LBB29_2
3383; X86-BMI1BMI2-NEXT:  # %bb.1:
3384; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
3385; X86-BMI1BMI2-NEXT:  .LBB29_2:
3386; X86-BMI1BMI2-NEXT:    xorl %ecx, %ecx
3387; X86-BMI1BMI2-NEXT:    testb $32, %al
3388; X86-BMI1BMI2-NEXT:    jne .LBB29_4
3389; X86-BMI1BMI2-NEXT:  # %bb.3:
3390; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3391; X86-BMI1BMI2-NEXT:    shlxl %eax, %ecx, %ecx
3392; X86-BMI1BMI2-NEXT:  .LBB29_4:
3393; X86-BMI1BMI2-NEXT:    andnl %edx, %ecx, %eax
3394; X86-BMI1BMI2-NEXT:    popl %esi
3395; X86-BMI1BMI2-NEXT:    retl
3396;
3397; X64-NOBMI-LABEL: bextr64_32_b0:
3398; X64-NOBMI:       # %bb.0:
3399; X64-NOBMI-NEXT:    movq %rsi, %rcx
3400; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3401; X64-NOBMI-NEXT:    shrq %cl, %rdi
3402; X64-NOBMI-NEXT:    movq $-1, %rax
3403; X64-NOBMI-NEXT:    movl %edx, %ecx
3404; X64-NOBMI-NEXT:    shlq %cl, %rax
3405; X64-NOBMI-NEXT:    notl %eax
3406; X64-NOBMI-NEXT:    andl %edi, %eax
3407; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
3408; X64-NOBMI-NEXT:    retq
3409;
3410; X64-BMI1NOTBM-LABEL: bextr64_32_b0:
3411; X64-BMI1NOTBM:       # %bb.0:
3412; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
3413; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
3414; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
3415; X64-BMI1NOTBM-NEXT:    movq $-1, %rax
3416; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3417; X64-BMI1NOTBM-NEXT:    shlq %cl, %rax
3418; X64-BMI1NOTBM-NEXT:    andnl %edi, %eax, %eax
3419; X64-BMI1NOTBM-NEXT:    retq
3420;
3421; X64-BMI1BMI2-LABEL: bextr64_32_b0:
3422; X64-BMI1BMI2:       # %bb.0:
3423; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
3424; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3425; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
3426; X64-BMI1BMI2-NEXT:    shlxq %rdx, %rcx, %rcx
3427; X64-BMI1BMI2-NEXT:    andnl %eax, %ecx, %eax
3428; X64-BMI1BMI2-NEXT:    retq
3429  %shiftedval = lshr i64 %val, %numskipbits
3430  %widenumlowbits = zext i8 %numlowbits to i64
3431  %notmask = shl nsw i64 -1, %widenumlowbits
3432  %mask = xor i64 %notmask, -1
3433  %wideres = and i64 %shiftedval, %mask
3434  %res = trunc i64 %wideres to i32
3435  ret i32 %res
3436}
3437
3438; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
3439define i32 @bextr64_32_b1(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3440; X86-NOBMI-LABEL: bextr64_32_b1:
3441; X86-NOBMI:       # %bb.0:
3442; X86-NOBMI-NEXT:    pushl %edi
3443; X86-NOBMI-NEXT:    pushl %esi
3444; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
3445; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3446; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3447; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3448; X86-NOBMI-NEXT:    movl %edi, %esi
3449; X86-NOBMI-NEXT:    shrl %cl, %esi
3450; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
3451; X86-NOBMI-NEXT:    testb $32, %cl
3452; X86-NOBMI-NEXT:    jne .LBB30_2
3453; X86-NOBMI-NEXT:  # %bb.1:
3454; X86-NOBMI-NEXT:    movl %eax, %esi
3455; X86-NOBMI-NEXT:  .LBB30_2:
3456; X86-NOBMI-NEXT:    movl $-1, %eax
3457; X86-NOBMI-NEXT:    movl %edx, %ecx
3458; X86-NOBMI-NEXT:    shll %cl, %eax
3459; X86-NOBMI-NEXT:    notl %eax
3460; X86-NOBMI-NEXT:    andl %esi, %eax
3461; X86-NOBMI-NEXT:    popl %esi
3462; X86-NOBMI-NEXT:    popl %edi
3463; X86-NOBMI-NEXT:    retl
3464;
3465; X86-BMI1NOTBM-LABEL: bextr64_32_b1:
3466; X86-BMI1NOTBM:       # %bb.0:
3467; X86-BMI1NOTBM-NEXT:    pushl %edi
3468; X86-BMI1NOTBM-NEXT:    pushl %esi
3469; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
3470; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3471; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
3472; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3473; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
3474; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
3475; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
3476; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3477; X86-BMI1NOTBM-NEXT:    jne .LBB30_2
3478; X86-BMI1NOTBM-NEXT:  # %bb.1:
3479; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
3480; X86-BMI1NOTBM-NEXT:  .LBB30_2:
3481; X86-BMI1NOTBM-NEXT:    shll $8, %eax
3482; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
3483; X86-BMI1NOTBM-NEXT:    popl %esi
3484; X86-BMI1NOTBM-NEXT:    popl %edi
3485; X86-BMI1NOTBM-NEXT:    retl
3486;
3487; X86-BMI1BMI2-LABEL: bextr64_32_b1:
3488; X86-BMI1BMI2:       # %bb.0:
3489; X86-BMI1BMI2-NEXT:    pushl %esi
3490; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3491; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3492; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3493; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3494; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
3495; X86-BMI1BMI2-NEXT:    testb $32, %cl
3496; X86-BMI1BMI2-NEXT:    je .LBB30_2
3497; X86-BMI1BMI2-NEXT:  # %bb.1:
3498; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
3499; X86-BMI1BMI2-NEXT:  .LBB30_2:
3500; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
3501; X86-BMI1BMI2-NEXT:    popl %esi
3502; X86-BMI1BMI2-NEXT:    retl
3503;
3504; X64-NOBMI-LABEL: bextr64_32_b1:
3505; X64-NOBMI:       # %bb.0:
3506; X64-NOBMI-NEXT:    movq %rsi, %rcx
3507; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3508; X64-NOBMI-NEXT:    shrq %cl, %rdi
3509; X64-NOBMI-NEXT:    movl $-1, %eax
3510; X64-NOBMI-NEXT:    movl %edx, %ecx
3511; X64-NOBMI-NEXT:    shll %cl, %eax
3512; X64-NOBMI-NEXT:    notl %eax
3513; X64-NOBMI-NEXT:    andl %edi, %eax
3514; X64-NOBMI-NEXT:    retq
3515;
3516; X64-BMI1NOTBM-LABEL: bextr64_32_b1:
3517; X64-BMI1NOTBM:       # %bb.0:
3518; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
3519; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
3520; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
3521; X64-BMI1NOTBM-NEXT:    shll $8, %edx
3522; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
3523; X64-BMI1NOTBM-NEXT:    retq
3524;
3525; X64-BMI1BMI2-LABEL: bextr64_32_b1:
3526; X64-BMI1BMI2:       # %bb.0:
3527; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3528; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
3529; X64-BMI1BMI2-NEXT:    retq
3530  %shiftedval = lshr i64 %val, %numskipbits
3531  %truncshiftedval = trunc i64 %shiftedval to i32
3532  %widenumlowbits = zext i8 %numlowbits to i32
3533  %notmask = shl nsw i32 -1, %widenumlowbits
3534  %mask = xor i32 %notmask, -1
3535  %res = and i32 %truncshiftedval, %mask
3536  ret i32 %res
3537}
3538
3539; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
3540; Masking is 64-bit. Then truncation.
3541define i32 @bextr64_32_b2(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3542; X86-NOBMI-LABEL: bextr64_32_b2:
3543; X86-NOBMI:       # %bb.0:
3544; X86-NOBMI-NEXT:    pushl %edi
3545; X86-NOBMI-NEXT:    pushl %esi
3546; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
3547; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3548; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3549; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3550; X86-NOBMI-NEXT:    movl %edi, %esi
3551; X86-NOBMI-NEXT:    shrl %cl, %esi
3552; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
3553; X86-NOBMI-NEXT:    testb $32, %cl
3554; X86-NOBMI-NEXT:    jne .LBB31_2
3555; X86-NOBMI-NEXT:  # %bb.1:
3556; X86-NOBMI-NEXT:    movl %eax, %esi
3557; X86-NOBMI-NEXT:  .LBB31_2:
3558; X86-NOBMI-NEXT:    movl $-1, %eax
3559; X86-NOBMI-NEXT:    movl %edx, %ecx
3560; X86-NOBMI-NEXT:    shll %cl, %eax
3561; X86-NOBMI-NEXT:    notl %eax
3562; X86-NOBMI-NEXT:    andl %esi, %eax
3563; X86-NOBMI-NEXT:    popl %esi
3564; X86-NOBMI-NEXT:    popl %edi
3565; X86-NOBMI-NEXT:    retl
3566;
3567; X86-BMI1NOTBM-LABEL: bextr64_32_b2:
3568; X86-BMI1NOTBM:       # %bb.0:
3569; X86-BMI1NOTBM-NEXT:    pushl %edi
3570; X86-BMI1NOTBM-NEXT:    pushl %esi
3571; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
3572; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3573; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
3574; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3575; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
3576; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
3577; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
3578; X86-BMI1NOTBM-NEXT:    testb $32, %cl
3579; X86-BMI1NOTBM-NEXT:    jne .LBB31_2
3580; X86-BMI1NOTBM-NEXT:  # %bb.1:
3581; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
3582; X86-BMI1NOTBM-NEXT:  .LBB31_2:
3583; X86-BMI1NOTBM-NEXT:    shll $8, %eax
3584; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
3585; X86-BMI1NOTBM-NEXT:    popl %esi
3586; X86-BMI1NOTBM-NEXT:    popl %edi
3587; X86-BMI1NOTBM-NEXT:    retl
3588;
3589; X86-BMI1BMI2-LABEL: bextr64_32_b2:
3590; X86-BMI1BMI2:       # %bb.0:
3591; X86-BMI1BMI2-NEXT:    pushl %esi
3592; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3593; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3594; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3595; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3596; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
3597; X86-BMI1BMI2-NEXT:    testb $32, %cl
3598; X86-BMI1BMI2-NEXT:    je .LBB31_2
3599; X86-BMI1BMI2-NEXT:  # %bb.1:
3600; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
3601; X86-BMI1BMI2-NEXT:  .LBB31_2:
3602; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
3603; X86-BMI1BMI2-NEXT:    popl %esi
3604; X86-BMI1BMI2-NEXT:    retl
3605;
3606; X64-NOBMI-LABEL: bextr64_32_b2:
3607; X64-NOBMI:       # %bb.0:
3608; X64-NOBMI-NEXT:    movq %rsi, %rcx
3609; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3610; X64-NOBMI-NEXT:    shrq %cl, %rdi
3611; X64-NOBMI-NEXT:    movl $-1, %eax
3612; X64-NOBMI-NEXT:    movl %edx, %ecx
3613; X64-NOBMI-NEXT:    shll %cl, %eax
3614; X64-NOBMI-NEXT:    notl %eax
3615; X64-NOBMI-NEXT:    andl %edi, %eax
3616; X64-NOBMI-NEXT:    retq
3617;
3618; X64-BMI1NOTBM-LABEL: bextr64_32_b2:
3619; X64-BMI1NOTBM:       # %bb.0:
3620; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
3621; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
3622; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
3623; X64-BMI1NOTBM-NEXT:    shll $8, %edx
3624; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
3625; X64-BMI1NOTBM-NEXT:    retq
3626;
3627; X64-BMI1BMI2-LABEL: bextr64_32_b2:
3628; X64-BMI1BMI2:       # %bb.0:
3629; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3630; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
3631; X64-BMI1BMI2-NEXT:    retq
3632  %shiftedval = lshr i64 %val, %numskipbits
3633  %widenumlowbits = zext i8 %numlowbits to i32
3634  %notmask = shl nsw i32 -1, %widenumlowbits
3635  %mask = xor i32 %notmask, -1
3636  %zextmask = zext i32 %mask to i64
3637  %wideres = and i64 %shiftedval, %zextmask
3638  %res = trunc i64 %wideres to i32
3639  ret i32 %res
3640}
3641
3642; ---------------------------------------------------------------------------- ;
3643; Pattern c. 32-bit
3644; ---------------------------------------------------------------------------- ;
3645
3646define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
3647; X86-NOBMI-LABEL: bextr32_c0:
3648; X86-NOBMI:       # %bb.0:
3649; X86-NOBMI-NEXT:    pushl %edi
3650; X86-NOBMI-NEXT:    pushl %esi
3651; X86-NOBMI-NEXT:    pushl %eax
3652; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3653; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3654; X86-NOBMI-NEXT:    shrl %cl, %edi
3655; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3656; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3657; X86-NOBMI-NEXT:    movl $-1, %esi
3658; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3659; X86-NOBMI-NEXT:    shrl %cl, %esi
3660; X86-NOBMI-NEXT:    movl %esi, (%esp)
3661; X86-NOBMI-NEXT:    calll use32
3662; X86-NOBMI-NEXT:    andl %edi, %esi
3663; X86-NOBMI-NEXT:    movl %esi, %eax
3664; X86-NOBMI-NEXT:    addl $4, %esp
3665; X86-NOBMI-NEXT:    popl %esi
3666; X86-NOBMI-NEXT:    popl %edi
3667; X86-NOBMI-NEXT:    retl
3668;
3669; X86-BMI1NOTBM-LABEL: bextr32_c0:
3670; X86-BMI1NOTBM:       # %bb.0:
3671; X86-BMI1NOTBM-NEXT:    pushl %edi
3672; X86-BMI1NOTBM-NEXT:    pushl %esi
3673; X86-BMI1NOTBM-NEXT:    pushl %eax
3674; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3675; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3676; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3677; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3678; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3679; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3680; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3681; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3682; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3683; X86-BMI1NOTBM-NEXT:    calll use32
3684; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3685; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3686; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3687; X86-BMI1NOTBM-NEXT:    popl %esi
3688; X86-BMI1NOTBM-NEXT:    popl %edi
3689; X86-BMI1NOTBM-NEXT:    retl
3690;
3691; X86-BMI1BMI2-LABEL: bextr32_c0:
3692; X86-BMI1BMI2:       # %bb.0:
3693; X86-BMI1BMI2-NEXT:    pushl %ebx
3694; X86-BMI1BMI2-NEXT:    pushl %esi
3695; X86-BMI1BMI2-NEXT:    pushl %eax
3696; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3697; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3698; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
3699; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3700; X86-BMI1BMI2-NEXT:    negb %al
3701; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3702; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3703; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3704; X86-BMI1BMI2-NEXT:    calll use32
3705; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3706; X86-BMI1BMI2-NEXT:    addl $4, %esp
3707; X86-BMI1BMI2-NEXT:    popl %esi
3708; X86-BMI1BMI2-NEXT:    popl %ebx
3709; X86-BMI1BMI2-NEXT:    retl
3710;
3711; X64-NOBMI-LABEL: bextr32_c0:
3712; X64-NOBMI:       # %bb.0:
3713; X64-NOBMI-NEXT:    pushq %rbp
3714; X64-NOBMI-NEXT:    pushq %rbx
3715; X64-NOBMI-NEXT:    pushq %rax
3716; X64-NOBMI-NEXT:    movl %esi, %ecx
3717; X64-NOBMI-NEXT:    movl %edi, %ebx
3718; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3719; X64-NOBMI-NEXT:    shrl %cl, %ebx
3720; X64-NOBMI-NEXT:    negb %dl
3721; X64-NOBMI-NEXT:    movl $-1, %ebp
3722; X64-NOBMI-NEXT:    movl %edx, %ecx
3723; X64-NOBMI-NEXT:    shrl %cl, %ebp
3724; X64-NOBMI-NEXT:    movl %ebp, %edi
3725; X64-NOBMI-NEXT:    callq use32
3726; X64-NOBMI-NEXT:    andl %ebx, %ebp
3727; X64-NOBMI-NEXT:    movl %ebp, %eax
3728; X64-NOBMI-NEXT:    addq $8, %rsp
3729; X64-NOBMI-NEXT:    popq %rbx
3730; X64-NOBMI-NEXT:    popq %rbp
3731; X64-NOBMI-NEXT:    retq
3732;
3733; X64-BMI1NOTBM-LABEL: bextr32_c0:
3734; X64-BMI1NOTBM:       # %bb.0:
3735; X64-BMI1NOTBM-NEXT:    pushq %rbp
3736; X64-BMI1NOTBM-NEXT:    pushq %rbx
3737; X64-BMI1NOTBM-NEXT:    pushq %rax
3738; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3739; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
3740; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3741; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3742; X64-BMI1NOTBM-NEXT:    negb %dl
3743; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
3744; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3745; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3746; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
3747; X64-BMI1NOTBM-NEXT:    callq use32
3748; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
3749; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
3750; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3751; X64-BMI1NOTBM-NEXT:    popq %rbx
3752; X64-BMI1NOTBM-NEXT:    popq %rbp
3753; X64-BMI1NOTBM-NEXT:    retq
3754;
3755; X64-BMI1BMI2-LABEL: bextr32_c0:
3756; X64-BMI1BMI2:       # %bb.0:
3757; X64-BMI1BMI2-NEXT:    pushq %rbp
3758; X64-BMI1BMI2-NEXT:    pushq %rbx
3759; X64-BMI1BMI2-NEXT:    pushq %rax
3760; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3761; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
3762; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3763; X64-BMI1BMI2-NEXT:    negb %al
3764; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3765; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3766; X64-BMI1BMI2-NEXT:    callq use32
3767; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3768; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3769; X64-BMI1BMI2-NEXT:    popq %rbx
3770; X64-BMI1BMI2-NEXT:    popq %rbp
3771; X64-BMI1BMI2-NEXT:    retq
3772  %shifted = lshr i32 %val, %numskipbits
3773  %numhighbits = sub i32 32, %numlowbits
3774  %mask = lshr i32 -1, %numhighbits
3775  call void @use32(i32 %mask)
3776  %masked = and i32 %mask, %shifted
3777  ret i32 %masked
3778}
3779
3780define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
3781; X86-NOBMI-LABEL: bextr32_c1_indexzext:
3782; X86-NOBMI:       # %bb.0:
3783; X86-NOBMI-NEXT:    pushl %edi
3784; X86-NOBMI-NEXT:    pushl %esi
3785; X86-NOBMI-NEXT:    pushl %eax
3786; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3787; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3788; X86-NOBMI-NEXT:    shrl %cl, %edi
3789; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3790; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3791; X86-NOBMI-NEXT:    movl $-1, %esi
3792; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3793; X86-NOBMI-NEXT:    shrl %cl, %esi
3794; X86-NOBMI-NEXT:    movl %esi, (%esp)
3795; X86-NOBMI-NEXT:    calll use32
3796; X86-NOBMI-NEXT:    andl %edi, %esi
3797; X86-NOBMI-NEXT:    movl %esi, %eax
3798; X86-NOBMI-NEXT:    addl $4, %esp
3799; X86-NOBMI-NEXT:    popl %esi
3800; X86-NOBMI-NEXT:    popl %edi
3801; X86-NOBMI-NEXT:    retl
3802;
3803; X86-BMI1NOTBM-LABEL: bextr32_c1_indexzext:
3804; X86-BMI1NOTBM:       # %bb.0:
3805; X86-BMI1NOTBM-NEXT:    pushl %edi
3806; X86-BMI1NOTBM-NEXT:    pushl %esi
3807; X86-BMI1NOTBM-NEXT:    pushl %eax
3808; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3809; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
3810; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3811; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3812; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3813; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3814; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3815; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3816; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3817; X86-BMI1NOTBM-NEXT:    calll use32
3818; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3819; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3820; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3821; X86-BMI1NOTBM-NEXT:    popl %esi
3822; X86-BMI1NOTBM-NEXT:    popl %edi
3823; X86-BMI1NOTBM-NEXT:    retl
3824;
3825; X86-BMI1BMI2-LABEL: bextr32_c1_indexzext:
3826; X86-BMI1BMI2:       # %bb.0:
3827; X86-BMI1BMI2-NEXT:    pushl %ebx
3828; X86-BMI1BMI2-NEXT:    pushl %esi
3829; X86-BMI1BMI2-NEXT:    pushl %eax
3830; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3831; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
3832; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
3833; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3834; X86-BMI1BMI2-NEXT:    negb %al
3835; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3836; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3837; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3838; X86-BMI1BMI2-NEXT:    calll use32
3839; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3840; X86-BMI1BMI2-NEXT:    addl $4, %esp
3841; X86-BMI1BMI2-NEXT:    popl %esi
3842; X86-BMI1BMI2-NEXT:    popl %ebx
3843; X86-BMI1BMI2-NEXT:    retl
3844;
3845; X64-NOBMI-LABEL: bextr32_c1_indexzext:
3846; X64-NOBMI:       # %bb.0:
3847; X64-NOBMI-NEXT:    pushq %rbp
3848; X64-NOBMI-NEXT:    pushq %rbx
3849; X64-NOBMI-NEXT:    pushq %rax
3850; X64-NOBMI-NEXT:    movl %esi, %ecx
3851; X64-NOBMI-NEXT:    movl %edi, %ebx
3852; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3853; X64-NOBMI-NEXT:    shrl %cl, %ebx
3854; X64-NOBMI-NEXT:    negb %dl
3855; X64-NOBMI-NEXT:    movl $-1, %ebp
3856; X64-NOBMI-NEXT:    movl %edx, %ecx
3857; X64-NOBMI-NEXT:    shrl %cl, %ebp
3858; X64-NOBMI-NEXT:    movl %ebp, %edi
3859; X64-NOBMI-NEXT:    callq use32
3860; X64-NOBMI-NEXT:    andl %ebx, %ebp
3861; X64-NOBMI-NEXT:    movl %ebp, %eax
3862; X64-NOBMI-NEXT:    addq $8, %rsp
3863; X64-NOBMI-NEXT:    popq %rbx
3864; X64-NOBMI-NEXT:    popq %rbp
3865; X64-NOBMI-NEXT:    retq
3866;
3867; X64-BMI1NOTBM-LABEL: bextr32_c1_indexzext:
3868; X64-BMI1NOTBM:       # %bb.0:
3869; X64-BMI1NOTBM-NEXT:    pushq %rbp
3870; X64-BMI1NOTBM-NEXT:    pushq %rbx
3871; X64-BMI1NOTBM-NEXT:    pushq %rax
3872; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
3873; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
3874; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3875; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
3876; X64-BMI1NOTBM-NEXT:    negb %dl
3877; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
3878; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
3879; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
3880; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
3881; X64-BMI1NOTBM-NEXT:    callq use32
3882; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
3883; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
3884; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
3885; X64-BMI1NOTBM-NEXT:    popq %rbx
3886; X64-BMI1NOTBM-NEXT:    popq %rbp
3887; X64-BMI1NOTBM-NEXT:    retq
3888;
3889; X64-BMI1BMI2-LABEL: bextr32_c1_indexzext:
3890; X64-BMI1BMI2:       # %bb.0:
3891; X64-BMI1BMI2-NEXT:    pushq %rbp
3892; X64-BMI1BMI2-NEXT:    pushq %rbx
3893; X64-BMI1BMI2-NEXT:    pushq %rax
3894; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
3895; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
3896; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
3897; X64-BMI1BMI2-NEXT:    negb %al
3898; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
3899; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
3900; X64-BMI1BMI2-NEXT:    callq use32
3901; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
3902; X64-BMI1BMI2-NEXT:    addq $8, %rsp
3903; X64-BMI1BMI2-NEXT:    popq %rbx
3904; X64-BMI1BMI2-NEXT:    popq %rbp
3905; X64-BMI1BMI2-NEXT:    retq
3906  %skip = zext i8 %numskipbits to i32
3907  %shifted = lshr i32 %val, %skip
3908  %numhighbits = sub i8 32, %numlowbits
3909  %sh_prom = zext i8 %numhighbits to i32
3910  %mask = lshr i32 -1, %sh_prom
3911  call void @use32(i32 %mask)
3912  %masked = and i32 %mask, %shifted
3913  ret i32 %masked
3914}
3915
3916define i32 @bextr32_c2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
3917; X86-NOBMI-LABEL: bextr32_c2_load:
3918; X86-NOBMI:       # %bb.0:
3919; X86-NOBMI-NEXT:    pushl %edi
3920; X86-NOBMI-NEXT:    pushl %esi
3921; X86-NOBMI-NEXT:    pushl %eax
3922; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3923; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3924; X86-NOBMI-NEXT:    movl (%eax), %edi
3925; X86-NOBMI-NEXT:    shrl %cl, %edi
3926; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3927; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
3928; X86-NOBMI-NEXT:    movl $-1, %esi
3929; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3930; X86-NOBMI-NEXT:    shrl %cl, %esi
3931; X86-NOBMI-NEXT:    movl %esi, (%esp)
3932; X86-NOBMI-NEXT:    calll use32
3933; X86-NOBMI-NEXT:    andl %edi, %esi
3934; X86-NOBMI-NEXT:    movl %esi, %eax
3935; X86-NOBMI-NEXT:    addl $4, %esp
3936; X86-NOBMI-NEXT:    popl %esi
3937; X86-NOBMI-NEXT:    popl %edi
3938; X86-NOBMI-NEXT:    retl
3939;
3940; X86-BMI1NOTBM-LABEL: bextr32_c2_load:
3941; X86-BMI1NOTBM:       # %bb.0:
3942; X86-BMI1NOTBM-NEXT:    pushl %edi
3943; X86-BMI1NOTBM-NEXT:    pushl %esi
3944; X86-BMI1NOTBM-NEXT:    pushl %eax
3945; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
3946; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
3947; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
3948; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
3949; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
3950; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
3951; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
3952; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
3953; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
3954; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
3955; X86-BMI1NOTBM-NEXT:    calll use32
3956; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
3957; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
3958; X86-BMI1NOTBM-NEXT:    addl $4, %esp
3959; X86-BMI1NOTBM-NEXT:    popl %esi
3960; X86-BMI1NOTBM-NEXT:    popl %edi
3961; X86-BMI1NOTBM-NEXT:    retl
3962;
3963; X86-BMI1BMI2-LABEL: bextr32_c2_load:
3964; X86-BMI1BMI2:       # %bb.0:
3965; X86-BMI1BMI2-NEXT:    pushl %ebx
3966; X86-BMI1BMI2-NEXT:    pushl %esi
3967; X86-BMI1BMI2-NEXT:    pushl %eax
3968; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
3969; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3970; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
3971; X86-BMI1BMI2-NEXT:    shrxl %ecx, (%eax), %esi
3972; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
3973; X86-BMI1BMI2-NEXT:    negb %al
3974; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
3975; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
3976; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
3977; X86-BMI1BMI2-NEXT:    calll use32
3978; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
3979; X86-BMI1BMI2-NEXT:    addl $4, %esp
3980; X86-BMI1BMI2-NEXT:    popl %esi
3981; X86-BMI1BMI2-NEXT:    popl %ebx
3982; X86-BMI1BMI2-NEXT:    retl
3983;
3984; X64-NOBMI-LABEL: bextr32_c2_load:
3985; X64-NOBMI:       # %bb.0:
3986; X64-NOBMI-NEXT:    pushq %rbp
3987; X64-NOBMI-NEXT:    pushq %rbx
3988; X64-NOBMI-NEXT:    pushq %rax
3989; X64-NOBMI-NEXT:    movl %esi, %ecx
3990; X64-NOBMI-NEXT:    movl (%rdi), %ebp
3991; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3992; X64-NOBMI-NEXT:    shrl %cl, %ebp
3993; X64-NOBMI-NEXT:    negb %dl
3994; X64-NOBMI-NEXT:    movl $-1, %ebx
3995; X64-NOBMI-NEXT:    movl %edx, %ecx
3996; X64-NOBMI-NEXT:    shrl %cl, %ebx
3997; X64-NOBMI-NEXT:    movl %ebx, %edi
3998; X64-NOBMI-NEXT:    callq use32
3999; X64-NOBMI-NEXT:    andl %ebp, %ebx
4000; X64-NOBMI-NEXT:    movl %ebx, %eax
4001; X64-NOBMI-NEXT:    addq $8, %rsp
4002; X64-NOBMI-NEXT:    popq %rbx
4003; X64-NOBMI-NEXT:    popq %rbp
4004; X64-NOBMI-NEXT:    retq
4005;
4006; X64-BMI1NOTBM-LABEL: bextr32_c2_load:
4007; X64-BMI1NOTBM:       # %bb.0:
4008; X64-BMI1NOTBM-NEXT:    pushq %rbp
4009; X64-BMI1NOTBM-NEXT:    pushq %rbx
4010; X64-BMI1NOTBM-NEXT:    pushq %rax
4011; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4012; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebp
4013; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4014; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
4015; X64-BMI1NOTBM-NEXT:    negb %dl
4016; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
4017; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4018; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4019; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
4020; X64-BMI1NOTBM-NEXT:    callq use32
4021; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
4022; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
4023; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4024; X64-BMI1NOTBM-NEXT:    popq %rbx
4025; X64-BMI1NOTBM-NEXT:    popq %rbp
4026; X64-BMI1NOTBM-NEXT:    retq
4027;
4028; X64-BMI1BMI2-LABEL: bextr32_c2_load:
4029; X64-BMI1BMI2:       # %bb.0:
4030; X64-BMI1BMI2-NEXT:    pushq %rbp
4031; X64-BMI1BMI2-NEXT:    pushq %rbx
4032; X64-BMI1BMI2-NEXT:    pushq %rax
4033; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4034; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
4035; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4036; X64-BMI1BMI2-NEXT:    negb %al
4037; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
4038; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
4039; X64-BMI1BMI2-NEXT:    callq use32
4040; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4041; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4042; X64-BMI1BMI2-NEXT:    popq %rbx
4043; X64-BMI1BMI2-NEXT:    popq %rbp
4044; X64-BMI1BMI2-NEXT:    retq
4045  %val = load i32, i32* %w
4046  %shifted = lshr i32 %val, %numskipbits
4047  %numhighbits = sub i32 32, %numlowbits
4048  %mask = lshr i32 -1, %numhighbits
4049  call void @use32(i32 %mask)
4050  %masked = and i32 %mask, %shifted
4051  ret i32 %masked
4052}
4053
4054define i32 @bextr32_c3_load_indexzext(i32* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
4055; X86-NOBMI-LABEL: bextr32_c3_load_indexzext:
4056; X86-NOBMI:       # %bb.0:
4057; X86-NOBMI-NEXT:    pushl %edi
4058; X86-NOBMI-NEXT:    pushl %esi
4059; X86-NOBMI-NEXT:    pushl %eax
4060; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4061; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4062; X86-NOBMI-NEXT:    movl (%eax), %edi
4063; X86-NOBMI-NEXT:    shrl %cl, %edi
4064; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4065; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4066; X86-NOBMI-NEXT:    movl $-1, %esi
4067; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4068; X86-NOBMI-NEXT:    shrl %cl, %esi
4069; X86-NOBMI-NEXT:    movl %esi, (%esp)
4070; X86-NOBMI-NEXT:    calll use32
4071; X86-NOBMI-NEXT:    andl %edi, %esi
4072; X86-NOBMI-NEXT:    movl %esi, %eax
4073; X86-NOBMI-NEXT:    addl $4, %esp
4074; X86-NOBMI-NEXT:    popl %esi
4075; X86-NOBMI-NEXT:    popl %edi
4076; X86-NOBMI-NEXT:    retl
4077;
4078; X86-BMI1NOTBM-LABEL: bextr32_c3_load_indexzext:
4079; X86-BMI1NOTBM:       # %bb.0:
4080; X86-BMI1NOTBM-NEXT:    pushl %edi
4081; X86-BMI1NOTBM-NEXT:    pushl %esi
4082; X86-BMI1NOTBM-NEXT:    pushl %eax
4083; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
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:    xorl %ecx, %ecx
4088; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4089; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
4090; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4091; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
4092; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
4093; X86-BMI1NOTBM-NEXT:    calll use32
4094; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
4095; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4096; X86-BMI1NOTBM-NEXT:    addl $4, %esp
4097; X86-BMI1NOTBM-NEXT:    popl %esi
4098; X86-BMI1NOTBM-NEXT:    popl %edi
4099; X86-BMI1NOTBM-NEXT:    retl
4100;
4101; X86-BMI1BMI2-LABEL: bextr32_c3_load_indexzext:
4102; X86-BMI1BMI2:       # %bb.0:
4103; X86-BMI1BMI2-NEXT:    pushl %ebx
4104; X86-BMI1BMI2-NEXT:    pushl %esi
4105; X86-BMI1BMI2-NEXT:    pushl %eax
4106; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
4107; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4108; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4109; X86-BMI1BMI2-NEXT:    shrxl %ecx, (%eax), %esi
4110; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
4111; X86-BMI1BMI2-NEXT:    negb %al
4112; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
4113; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
4114; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
4115; X86-BMI1BMI2-NEXT:    calll use32
4116; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
4117; X86-BMI1BMI2-NEXT:    addl $4, %esp
4118; X86-BMI1BMI2-NEXT:    popl %esi
4119; X86-BMI1BMI2-NEXT:    popl %ebx
4120; X86-BMI1BMI2-NEXT:    retl
4121;
4122; X64-NOBMI-LABEL: bextr32_c3_load_indexzext:
4123; X64-NOBMI:       # %bb.0:
4124; X64-NOBMI-NEXT:    pushq %rbp
4125; X64-NOBMI-NEXT:    pushq %rbx
4126; X64-NOBMI-NEXT:    pushq %rax
4127; X64-NOBMI-NEXT:    movl %esi, %ecx
4128; X64-NOBMI-NEXT:    movl (%rdi), %ebp
4129; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4130; X64-NOBMI-NEXT:    shrl %cl, %ebp
4131; X64-NOBMI-NEXT:    negb %dl
4132; X64-NOBMI-NEXT:    movl $-1, %ebx
4133; X64-NOBMI-NEXT:    movl %edx, %ecx
4134; X64-NOBMI-NEXT:    shrl %cl, %ebx
4135; X64-NOBMI-NEXT:    movl %ebx, %edi
4136; X64-NOBMI-NEXT:    callq use32
4137; X64-NOBMI-NEXT:    andl %ebp, %ebx
4138; X64-NOBMI-NEXT:    movl %ebx, %eax
4139; X64-NOBMI-NEXT:    addq $8, %rsp
4140; X64-NOBMI-NEXT:    popq %rbx
4141; X64-NOBMI-NEXT:    popq %rbp
4142; X64-NOBMI-NEXT:    retq
4143;
4144; X64-BMI1NOTBM-LABEL: bextr32_c3_load_indexzext:
4145; X64-BMI1NOTBM:       # %bb.0:
4146; X64-BMI1NOTBM-NEXT:    pushq %rbp
4147; X64-BMI1NOTBM-NEXT:    pushq %rbx
4148; X64-BMI1NOTBM-NEXT:    pushq %rax
4149; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4150; X64-BMI1NOTBM-NEXT:    movl (%rdi), %ebp
4151; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4152; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
4153; X64-BMI1NOTBM-NEXT:    negb %dl
4154; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
4155; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4156; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4157; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
4158; X64-BMI1NOTBM-NEXT:    callq use32
4159; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
4160; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
4161; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4162; X64-BMI1NOTBM-NEXT:    popq %rbx
4163; X64-BMI1NOTBM-NEXT:    popq %rbp
4164; X64-BMI1NOTBM-NEXT:    retq
4165;
4166; X64-BMI1BMI2-LABEL: bextr32_c3_load_indexzext:
4167; X64-BMI1BMI2:       # %bb.0:
4168; X64-BMI1BMI2-NEXT:    pushq %rbp
4169; X64-BMI1BMI2-NEXT:    pushq %rbx
4170; X64-BMI1BMI2-NEXT:    pushq %rax
4171; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4172; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
4173; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4174; X64-BMI1BMI2-NEXT:    negb %al
4175; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
4176; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
4177; X64-BMI1BMI2-NEXT:    callq use32
4178; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4179; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4180; X64-BMI1BMI2-NEXT:    popq %rbx
4181; X64-BMI1BMI2-NEXT:    popq %rbp
4182; X64-BMI1BMI2-NEXT:    retq
4183  %val = load i32, i32* %w
4184  %skip = zext i8 %numskipbits to i32
4185  %shifted = lshr i32 %val, %skip
4186  %numhighbits = sub i8 32, %numlowbits
4187  %sh_prom = zext i8 %numhighbits to i32
4188  %mask = lshr i32 -1, %sh_prom
4189  call void @use32(i32 %mask)
4190  %masked = and i32 %mask, %shifted
4191  ret i32 %masked
4192}
4193
4194define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
4195; X86-NOBMI-LABEL: bextr32_c4_commutative:
4196; X86-NOBMI:       # %bb.0:
4197; X86-NOBMI-NEXT:    pushl %edi
4198; X86-NOBMI-NEXT:    pushl %esi
4199; X86-NOBMI-NEXT:    pushl %eax
4200; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4201; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4202; X86-NOBMI-NEXT:    shrl %cl, %edi
4203; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4204; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4205; X86-NOBMI-NEXT:    movl $-1, %esi
4206; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4207; X86-NOBMI-NEXT:    shrl %cl, %esi
4208; X86-NOBMI-NEXT:    movl %esi, (%esp)
4209; X86-NOBMI-NEXT:    calll use32
4210; X86-NOBMI-NEXT:    andl %edi, %esi
4211; X86-NOBMI-NEXT:    movl %esi, %eax
4212; X86-NOBMI-NEXT:    addl $4, %esp
4213; X86-NOBMI-NEXT:    popl %esi
4214; X86-NOBMI-NEXT:    popl %edi
4215; X86-NOBMI-NEXT:    retl
4216;
4217; X86-BMI1NOTBM-LABEL: bextr32_c4_commutative:
4218; X86-BMI1NOTBM:       # %bb.0:
4219; X86-BMI1NOTBM-NEXT:    pushl %edi
4220; X86-BMI1NOTBM-NEXT:    pushl %esi
4221; X86-BMI1NOTBM-NEXT:    pushl %eax
4222; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4223; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
4224; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4225; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
4226; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4227; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
4228; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4229; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
4230; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
4231; X86-BMI1NOTBM-NEXT:    calll use32
4232; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
4233; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4234; X86-BMI1NOTBM-NEXT:    addl $4, %esp
4235; X86-BMI1NOTBM-NEXT:    popl %esi
4236; X86-BMI1NOTBM-NEXT:    popl %edi
4237; X86-BMI1NOTBM-NEXT:    retl
4238;
4239; X86-BMI1BMI2-LABEL: bextr32_c4_commutative:
4240; X86-BMI1BMI2:       # %bb.0:
4241; X86-BMI1BMI2-NEXT:    pushl %ebx
4242; X86-BMI1BMI2-NEXT:    pushl %esi
4243; X86-BMI1BMI2-NEXT:    pushl %eax
4244; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
4245; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
4246; X86-BMI1BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
4247; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
4248; X86-BMI1BMI2-NEXT:    negb %al
4249; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
4250; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
4251; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
4252; X86-BMI1BMI2-NEXT:    calll use32
4253; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %eax
4254; X86-BMI1BMI2-NEXT:    addl $4, %esp
4255; X86-BMI1BMI2-NEXT:    popl %esi
4256; X86-BMI1BMI2-NEXT:    popl %ebx
4257; X86-BMI1BMI2-NEXT:    retl
4258;
4259; X64-NOBMI-LABEL: bextr32_c4_commutative:
4260; X64-NOBMI:       # %bb.0:
4261; X64-NOBMI-NEXT:    pushq %rbp
4262; X64-NOBMI-NEXT:    pushq %rbx
4263; X64-NOBMI-NEXT:    pushq %rax
4264; X64-NOBMI-NEXT:    movl %esi, %ecx
4265; X64-NOBMI-NEXT:    movl %edi, %ebx
4266; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4267; X64-NOBMI-NEXT:    shrl %cl, %ebx
4268; X64-NOBMI-NEXT:    negb %dl
4269; X64-NOBMI-NEXT:    movl $-1, %ebp
4270; X64-NOBMI-NEXT:    movl %edx, %ecx
4271; X64-NOBMI-NEXT:    shrl %cl, %ebp
4272; X64-NOBMI-NEXT:    movl %ebp, %edi
4273; X64-NOBMI-NEXT:    callq use32
4274; X64-NOBMI-NEXT:    andl %ebx, %ebp
4275; X64-NOBMI-NEXT:    movl %ebp, %eax
4276; X64-NOBMI-NEXT:    addq $8, %rsp
4277; X64-NOBMI-NEXT:    popq %rbx
4278; X64-NOBMI-NEXT:    popq %rbp
4279; X64-NOBMI-NEXT:    retq
4280;
4281; X64-BMI1NOTBM-LABEL: bextr32_c4_commutative:
4282; X64-BMI1NOTBM:       # %bb.0:
4283; X64-BMI1NOTBM-NEXT:    pushq %rbp
4284; X64-BMI1NOTBM-NEXT:    pushq %rbx
4285; X64-BMI1NOTBM-NEXT:    pushq %rax
4286; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4287; X64-BMI1NOTBM-NEXT:    movl %edi, %ebx
4288; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4289; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4290; X64-BMI1NOTBM-NEXT:    negb %dl
4291; X64-BMI1NOTBM-NEXT:    movl $-1, %ebp
4292; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4293; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
4294; X64-BMI1NOTBM-NEXT:    movl %ebp, %edi
4295; X64-BMI1NOTBM-NEXT:    callq use32
4296; X64-BMI1NOTBM-NEXT:    andl %ebx, %ebp
4297; X64-BMI1NOTBM-NEXT:    movl %ebp, %eax
4298; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4299; X64-BMI1NOTBM-NEXT:    popq %rbx
4300; X64-BMI1NOTBM-NEXT:    popq %rbp
4301; X64-BMI1NOTBM-NEXT:    retq
4302;
4303; X64-BMI1BMI2-LABEL: bextr32_c4_commutative:
4304; X64-BMI1BMI2:       # %bb.0:
4305; X64-BMI1BMI2-NEXT:    pushq %rbp
4306; X64-BMI1BMI2-NEXT:    pushq %rbx
4307; X64-BMI1BMI2-NEXT:    pushq %rax
4308; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4309; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %ebp
4310; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4311; X64-BMI1BMI2-NEXT:    negb %al
4312; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
4313; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
4314; X64-BMI1BMI2-NEXT:    callq use32
4315; X64-BMI1BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4316; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4317; X64-BMI1BMI2-NEXT:    popq %rbx
4318; X64-BMI1BMI2-NEXT:    popq %rbp
4319; X64-BMI1BMI2-NEXT:    retq
4320  %shifted = lshr i32 %val, %numskipbits
4321  %numhighbits = sub i32 32, %numlowbits
4322  %mask = lshr i32 -1, %numhighbits
4323  call void @use32(i32 %mask)
4324  %masked = and i32 %shifted, %mask ; swapped order
4325  ret i32 %masked
4326}
4327
4328define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
4329; X86-NOBMI-LABEL: bextr32_c5_skipextrauses:
4330; X86-NOBMI:       # %bb.0:
4331; X86-NOBMI-NEXT:    pushl %ebx
4332; X86-NOBMI-NEXT:    pushl %edi
4333; X86-NOBMI-NEXT:    pushl %esi
4334; X86-NOBMI-NEXT:    subl $16, %esp
4335; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4336; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
4337; X86-NOBMI-NEXT:    movl %ebx, %ecx
4338; X86-NOBMI-NEXT:    shrl %cl, %edi
4339; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4340; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4341; X86-NOBMI-NEXT:    movl $-1, %esi
4342; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4343; X86-NOBMI-NEXT:    shrl %cl, %esi
4344; X86-NOBMI-NEXT:    movl %esi, (%esp)
4345; X86-NOBMI-NEXT:    calll use32
4346; X86-NOBMI-NEXT:    andl %edi, %esi
4347; X86-NOBMI-NEXT:    movl %ebx, (%esp)
4348; X86-NOBMI-NEXT:    calll use32
4349; X86-NOBMI-NEXT:    movl %esi, %eax
4350; X86-NOBMI-NEXT:    addl $16, %esp
4351; X86-NOBMI-NEXT:    popl %esi
4352; X86-NOBMI-NEXT:    popl %edi
4353; X86-NOBMI-NEXT:    popl %ebx
4354; X86-NOBMI-NEXT:    retl
4355;
4356; X86-BMI1NOTBM-LABEL: bextr32_c5_skipextrauses:
4357; X86-BMI1NOTBM:       # %bb.0:
4358; X86-BMI1NOTBM-NEXT:    pushl %ebx
4359; X86-BMI1NOTBM-NEXT:    pushl %edi
4360; X86-BMI1NOTBM-NEXT:    pushl %esi
4361; X86-BMI1NOTBM-NEXT:    subl $16, %esp
4362; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
4363; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
4364; X86-BMI1NOTBM-NEXT:    movl %ebx, %ecx
4365; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4366; X86-BMI1NOTBM-NEXT:    xorl %ecx, %ecx
4367; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4368; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
4369; X86-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4370; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
4371; X86-BMI1NOTBM-NEXT:    movl %esi, (%esp)
4372; X86-BMI1NOTBM-NEXT:    calll use32
4373; X86-BMI1NOTBM-NEXT:    andl %edi, %esi
4374; X86-BMI1NOTBM-NEXT:    movl %ebx, (%esp)
4375; X86-BMI1NOTBM-NEXT:    calll use32
4376; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4377; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4378; X86-BMI1NOTBM-NEXT:    popl %esi
4379; X86-BMI1NOTBM-NEXT:    popl %edi
4380; X86-BMI1NOTBM-NEXT:    popl %ebx
4381; X86-BMI1NOTBM-NEXT:    retl
4382;
4383; X86-BMI1BMI2-LABEL: bextr32_c5_skipextrauses:
4384; X86-BMI1BMI2:       # %bb.0:
4385; X86-BMI1BMI2-NEXT:    pushl %ebx
4386; X86-BMI1BMI2-NEXT:    pushl %edi
4387; X86-BMI1BMI2-NEXT:    pushl %esi
4388; X86-BMI1BMI2-NEXT:    subl $16, %esp
4389; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %bl
4390; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
4391; X86-BMI1BMI2-NEXT:    shrxl %edi, {{[0-9]+}}(%esp), %esi
4392; X86-BMI1BMI2-NEXT:    movl %ebx, %eax
4393; X86-BMI1BMI2-NEXT:    negb %al
4394; X86-BMI1BMI2-NEXT:    movl $-1, %ecx
4395; X86-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %eax
4396; X86-BMI1BMI2-NEXT:    movl %eax, (%esp)
4397; X86-BMI1BMI2-NEXT:    calll use32
4398; X86-BMI1BMI2-NEXT:    bzhil %ebx, %esi, %esi
4399; X86-BMI1BMI2-NEXT:    movl %edi, (%esp)
4400; X86-BMI1BMI2-NEXT:    calll use32
4401; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4402; X86-BMI1BMI2-NEXT:    addl $16, %esp
4403; X86-BMI1BMI2-NEXT:    popl %esi
4404; X86-BMI1BMI2-NEXT:    popl %edi
4405; X86-BMI1BMI2-NEXT:    popl %ebx
4406; X86-BMI1BMI2-NEXT:    retl
4407;
4408; X64-NOBMI-LABEL: bextr32_c5_skipextrauses:
4409; X64-NOBMI:       # %bb.0:
4410; X64-NOBMI-NEXT:    pushq %rbp
4411; X64-NOBMI-NEXT:    pushq %r14
4412; X64-NOBMI-NEXT:    pushq %rbx
4413; X64-NOBMI-NEXT:    movl %esi, %r14d
4414; X64-NOBMI-NEXT:    movl %edi, %ebp
4415; X64-NOBMI-NEXT:    movl %r14d, %ecx
4416; X64-NOBMI-NEXT:    shrl %cl, %ebp
4417; X64-NOBMI-NEXT:    negb %dl
4418; X64-NOBMI-NEXT:    movl $-1, %ebx
4419; X64-NOBMI-NEXT:    movl %edx, %ecx
4420; X64-NOBMI-NEXT:    shrl %cl, %ebx
4421; X64-NOBMI-NEXT:    movl %ebx, %edi
4422; X64-NOBMI-NEXT:    callq use32
4423; X64-NOBMI-NEXT:    andl %ebp, %ebx
4424; X64-NOBMI-NEXT:    movl %r14d, %edi
4425; X64-NOBMI-NEXT:    callq use32
4426; X64-NOBMI-NEXT:    movl %ebx, %eax
4427; X64-NOBMI-NEXT:    popq %rbx
4428; X64-NOBMI-NEXT:    popq %r14
4429; X64-NOBMI-NEXT:    popq %rbp
4430; X64-NOBMI-NEXT:    retq
4431;
4432; X64-BMI1NOTBM-LABEL: bextr32_c5_skipextrauses:
4433; X64-BMI1NOTBM:       # %bb.0:
4434; X64-BMI1NOTBM-NEXT:    pushq %rbp
4435; X64-BMI1NOTBM-NEXT:    pushq %r14
4436; X64-BMI1NOTBM-NEXT:    pushq %rbx
4437; X64-BMI1NOTBM-NEXT:    movl %esi, %r14d
4438; X64-BMI1NOTBM-NEXT:    movl %edi, %ebp
4439; X64-BMI1NOTBM-NEXT:    movl %r14d, %ecx
4440; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebp
4441; X64-BMI1NOTBM-NEXT:    negb %dl
4442; X64-BMI1NOTBM-NEXT:    movl $-1, %ebx
4443; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4444; X64-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4445; X64-BMI1NOTBM-NEXT:    movl %ebx, %edi
4446; X64-BMI1NOTBM-NEXT:    callq use32
4447; X64-BMI1NOTBM-NEXT:    andl %ebp, %ebx
4448; X64-BMI1NOTBM-NEXT:    movl %r14d, %edi
4449; X64-BMI1NOTBM-NEXT:    callq use32
4450; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
4451; X64-BMI1NOTBM-NEXT:    popq %rbx
4452; X64-BMI1NOTBM-NEXT:    popq %r14
4453; X64-BMI1NOTBM-NEXT:    popq %rbp
4454; X64-BMI1NOTBM-NEXT:    retq
4455;
4456; X64-BMI1BMI2-LABEL: bextr32_c5_skipextrauses:
4457; X64-BMI1BMI2:       # %bb.0:
4458; X64-BMI1BMI2-NEXT:    pushq %rbp
4459; X64-BMI1BMI2-NEXT:    pushq %r14
4460; X64-BMI1BMI2-NEXT:    pushq %rbx
4461; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4462; X64-BMI1BMI2-NEXT:    movl %esi, %ebp
4463; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %r14d
4464; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4465; X64-BMI1BMI2-NEXT:    negb %al
4466; X64-BMI1BMI2-NEXT:    movl $-1, %ecx
4467; X64-BMI1BMI2-NEXT:    shrxl %eax, %ecx, %edi
4468; X64-BMI1BMI2-NEXT:    callq use32
4469; X64-BMI1BMI2-NEXT:    bzhil %ebx, %r14d, %ebx
4470; X64-BMI1BMI2-NEXT:    movl %ebp, %edi
4471; X64-BMI1BMI2-NEXT:    callq use32
4472; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4473; X64-BMI1BMI2-NEXT:    popq %rbx
4474; X64-BMI1BMI2-NEXT:    popq %r14
4475; X64-BMI1BMI2-NEXT:    popq %rbp
4476; X64-BMI1BMI2-NEXT:    retq
4477  %shifted = lshr i32 %val, %numskipbits
4478  %numhighbits = sub i32 32, %numlowbits
4479  %mask = lshr i32 -1, %numhighbits
4480  call void @use32(i32 %mask)
4481  %masked = and i32 %mask, %shifted
4482  call void @use32(i32 %numskipbits)
4483  ret i32 %masked
4484}
4485
4486; 64-bit
4487
4488define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
4489; X86-NOBMI-LABEL: bextr64_c0:
4490; X86-NOBMI:       # %bb.0:
4491; X86-NOBMI-NEXT:    pushl %ebp
4492; X86-NOBMI-NEXT:    pushl %ebx
4493; X86-NOBMI-NEXT:    pushl %edi
4494; X86-NOBMI-NEXT:    pushl %esi
4495; X86-NOBMI-NEXT:    subl $12, %esp
4496; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4497; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4498; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4499; X86-NOBMI-NEXT:    movl %eax, %edi
4500; X86-NOBMI-NEXT:    shrl %cl, %edi
4501; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4502; X86-NOBMI-NEXT:    testb $32, %cl
4503; X86-NOBMI-NEXT:    je .LBB38_2
4504; X86-NOBMI-NEXT:  # %bb.1:
4505; X86-NOBMI-NEXT:    movl %edi, %esi
4506; X86-NOBMI-NEXT:    xorl %edi, %edi
4507; X86-NOBMI-NEXT:  .LBB38_2:
4508; X86-NOBMI-NEXT:    movb $64, %cl
4509; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4510; X86-NOBMI-NEXT:    movl $-1, %ebp
4511; X86-NOBMI-NEXT:    movl $-1, %ebx
4512; X86-NOBMI-NEXT:    shrl %cl, %ebx
4513; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4514; X86-NOBMI-NEXT:    testb $32, %cl
4515; X86-NOBMI-NEXT:    je .LBB38_4
4516; X86-NOBMI-NEXT:  # %bb.3:
4517; X86-NOBMI-NEXT:    movl %ebx, %ebp
4518; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4519; X86-NOBMI-NEXT:  .LBB38_4:
4520; X86-NOBMI-NEXT:    subl $8, %esp
4521; X86-NOBMI-NEXT:    pushl %ebx
4522; X86-NOBMI-NEXT:    pushl %ebp
4523; X86-NOBMI-NEXT:    calll use64
4524; X86-NOBMI-NEXT:    addl $16, %esp
4525; X86-NOBMI-NEXT:    andl %ebp, %esi
4526; X86-NOBMI-NEXT:    andl %ebx, %edi
4527; X86-NOBMI-NEXT:    movl %esi, %eax
4528; X86-NOBMI-NEXT:    movl %edi, %edx
4529; X86-NOBMI-NEXT:    addl $12, %esp
4530; X86-NOBMI-NEXT:    popl %esi
4531; X86-NOBMI-NEXT:    popl %edi
4532; X86-NOBMI-NEXT:    popl %ebx
4533; X86-NOBMI-NEXT:    popl %ebp
4534; X86-NOBMI-NEXT:    retl
4535;
4536; X86-BMI1NOTBM-LABEL: bextr64_c0:
4537; X86-BMI1NOTBM:       # %bb.0:
4538; X86-BMI1NOTBM-NEXT:    pushl %ebp
4539; X86-BMI1NOTBM-NEXT:    pushl %ebx
4540; X86-BMI1NOTBM-NEXT:    pushl %edi
4541; X86-BMI1NOTBM-NEXT:    pushl %esi
4542; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4543; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4544; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
4545; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4546; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4547; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4548; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4549; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4550; X86-BMI1NOTBM-NEXT:    je .LBB38_2
4551; X86-BMI1NOTBM-NEXT:  # %bb.1:
4552; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4553; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4554; X86-BMI1NOTBM-NEXT:  .LBB38_2:
4555; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4556; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4557; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4558; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4559; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4560; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4561; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4562; X86-BMI1NOTBM-NEXT:    je .LBB38_4
4563; X86-BMI1NOTBM-NEXT:  # %bb.3:
4564; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4565; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4566; X86-BMI1NOTBM-NEXT:  .LBB38_4:
4567; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4568; X86-BMI1NOTBM-NEXT:    pushl %ebx
4569; X86-BMI1NOTBM-NEXT:    pushl %ebp
4570; X86-BMI1NOTBM-NEXT:    calll use64
4571; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4572; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4573; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4574; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4575; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4576; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4577; X86-BMI1NOTBM-NEXT:    popl %esi
4578; X86-BMI1NOTBM-NEXT:    popl %edi
4579; X86-BMI1NOTBM-NEXT:    popl %ebx
4580; X86-BMI1NOTBM-NEXT:    popl %ebp
4581; X86-BMI1NOTBM-NEXT:    retl
4582;
4583; X86-BMI1BMI2-LABEL: bextr64_c0:
4584; X86-BMI1BMI2:       # %bb.0:
4585; X86-BMI1BMI2-NEXT:    pushl %ebp
4586; X86-BMI1BMI2-NEXT:    pushl %ebx
4587; X86-BMI1BMI2-NEXT:    pushl %edi
4588; X86-BMI1BMI2-NEXT:    pushl %esi
4589; X86-BMI1BMI2-NEXT:    subl $12, %esp
4590; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4591; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4592; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4593; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4594; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4595; X86-BMI1BMI2-NEXT:    testb $32, %cl
4596; X86-BMI1BMI2-NEXT:    je .LBB38_2
4597; X86-BMI1BMI2-NEXT:  # %bb.1:
4598; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4599; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4600; X86-BMI1BMI2-NEXT:  .LBB38_2:
4601; X86-BMI1BMI2-NEXT:    movb $64, %cl
4602; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4603; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4604; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4605; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4606; X86-BMI1BMI2-NEXT:    testb $32, %cl
4607; X86-BMI1BMI2-NEXT:    je .LBB38_4
4608; X86-BMI1BMI2-NEXT:  # %bb.3:
4609; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4610; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4611; X86-BMI1BMI2-NEXT:  .LBB38_4:
4612; X86-BMI1BMI2-NEXT:    subl $8, %esp
4613; X86-BMI1BMI2-NEXT:    pushl %ebp
4614; X86-BMI1BMI2-NEXT:    pushl %ebx
4615; X86-BMI1BMI2-NEXT:    calll use64
4616; X86-BMI1BMI2-NEXT:    addl $16, %esp
4617; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4618; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4619; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4620; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4621; X86-BMI1BMI2-NEXT:    addl $12, %esp
4622; X86-BMI1BMI2-NEXT:    popl %esi
4623; X86-BMI1BMI2-NEXT:    popl %edi
4624; X86-BMI1BMI2-NEXT:    popl %ebx
4625; X86-BMI1BMI2-NEXT:    popl %ebp
4626; X86-BMI1BMI2-NEXT:    retl
4627;
4628; X64-NOBMI-LABEL: bextr64_c0:
4629; X64-NOBMI:       # %bb.0:
4630; X64-NOBMI-NEXT:    pushq %r14
4631; X64-NOBMI-NEXT:    pushq %rbx
4632; X64-NOBMI-NEXT:    pushq %rax
4633; X64-NOBMI-NEXT:    movq %rsi, %rcx
4634; X64-NOBMI-NEXT:    movq %rdi, %r14
4635; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
4636; X64-NOBMI-NEXT:    shrq %cl, %r14
4637; X64-NOBMI-NEXT:    negb %dl
4638; X64-NOBMI-NEXT:    movq $-1, %rbx
4639; X64-NOBMI-NEXT:    movl %edx, %ecx
4640; X64-NOBMI-NEXT:    shrq %cl, %rbx
4641; X64-NOBMI-NEXT:    movq %rbx, %rdi
4642; X64-NOBMI-NEXT:    callq use64
4643; X64-NOBMI-NEXT:    andq %r14, %rbx
4644; X64-NOBMI-NEXT:    movq %rbx, %rax
4645; X64-NOBMI-NEXT:    addq $8, %rsp
4646; X64-NOBMI-NEXT:    popq %rbx
4647; X64-NOBMI-NEXT:    popq %r14
4648; X64-NOBMI-NEXT:    retq
4649;
4650; X64-BMI1NOTBM-LABEL: bextr64_c0:
4651; X64-BMI1NOTBM:       # %bb.0:
4652; X64-BMI1NOTBM-NEXT:    pushq %r14
4653; X64-BMI1NOTBM-NEXT:    pushq %rbx
4654; X64-BMI1NOTBM-NEXT:    pushq %rax
4655; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
4656; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
4657; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
4658; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4659; X64-BMI1NOTBM-NEXT:    negb %dl
4660; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4661; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4662; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4663; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4664; X64-BMI1NOTBM-NEXT:    callq use64
4665; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4666; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4667; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4668; X64-BMI1NOTBM-NEXT:    popq %rbx
4669; X64-BMI1NOTBM-NEXT:    popq %r14
4670; X64-BMI1NOTBM-NEXT:    retq
4671;
4672; X64-BMI1BMI2-LABEL: bextr64_c0:
4673; X64-BMI1BMI2:       # %bb.0:
4674; X64-BMI1BMI2-NEXT:    pushq %r14
4675; X64-BMI1BMI2-NEXT:    pushq %rbx
4676; X64-BMI1BMI2-NEXT:    pushq %rax
4677; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
4678; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
4679; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4680; X64-BMI1BMI2-NEXT:    negb %al
4681; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4682; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4683; X64-BMI1BMI2-NEXT:    callq use64
4684; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4685; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4686; X64-BMI1BMI2-NEXT:    popq %rbx
4687; X64-BMI1BMI2-NEXT:    popq %r14
4688; X64-BMI1BMI2-NEXT:    retq
4689  %shifted = lshr i64 %val, %numskipbits
4690  %numhighbits = sub i64 64, %numlowbits
4691  %mask = lshr i64 -1, %numhighbits
4692  call void @use64(i64 %mask)
4693  %masked = and i64 %mask, %shifted
4694  ret i64 %masked
4695}
4696
4697define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
4698; X86-NOBMI-LABEL: bextr64_c1_indexzext:
4699; X86-NOBMI:       # %bb.0:
4700; X86-NOBMI-NEXT:    pushl %ebp
4701; X86-NOBMI-NEXT:    pushl %ebx
4702; X86-NOBMI-NEXT:    pushl %edi
4703; X86-NOBMI-NEXT:    pushl %esi
4704; X86-NOBMI-NEXT:    subl $12, %esp
4705; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4706; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4707; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4708; X86-NOBMI-NEXT:    movl %eax, %edi
4709; X86-NOBMI-NEXT:    shrl %cl, %edi
4710; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4711; X86-NOBMI-NEXT:    testb $32, %cl
4712; X86-NOBMI-NEXT:    je .LBB39_2
4713; X86-NOBMI-NEXT:  # %bb.1:
4714; X86-NOBMI-NEXT:    movl %edi, %esi
4715; X86-NOBMI-NEXT:    xorl %edi, %edi
4716; X86-NOBMI-NEXT:  .LBB39_2:
4717; X86-NOBMI-NEXT:    movb $64, %cl
4718; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4719; X86-NOBMI-NEXT:    movl $-1, %ebp
4720; X86-NOBMI-NEXT:    movl $-1, %ebx
4721; X86-NOBMI-NEXT:    shrl %cl, %ebx
4722; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4723; X86-NOBMI-NEXT:    testb $32, %cl
4724; X86-NOBMI-NEXT:    je .LBB39_4
4725; X86-NOBMI-NEXT:  # %bb.3:
4726; X86-NOBMI-NEXT:    movl %ebx, %ebp
4727; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4728; X86-NOBMI-NEXT:  .LBB39_4:
4729; X86-NOBMI-NEXT:    subl $8, %esp
4730; X86-NOBMI-NEXT:    pushl %ebx
4731; X86-NOBMI-NEXT:    pushl %ebp
4732; X86-NOBMI-NEXT:    calll use64
4733; X86-NOBMI-NEXT:    addl $16, %esp
4734; X86-NOBMI-NEXT:    andl %ebp, %esi
4735; X86-NOBMI-NEXT:    andl %ebx, %edi
4736; X86-NOBMI-NEXT:    movl %esi, %eax
4737; X86-NOBMI-NEXT:    movl %edi, %edx
4738; X86-NOBMI-NEXT:    addl $12, %esp
4739; X86-NOBMI-NEXT:    popl %esi
4740; X86-NOBMI-NEXT:    popl %edi
4741; X86-NOBMI-NEXT:    popl %ebx
4742; X86-NOBMI-NEXT:    popl %ebp
4743; X86-NOBMI-NEXT:    retl
4744;
4745; X86-BMI1NOTBM-LABEL: bextr64_c1_indexzext:
4746; X86-BMI1NOTBM:       # %bb.0:
4747; X86-BMI1NOTBM-NEXT:    pushl %ebp
4748; X86-BMI1NOTBM-NEXT:    pushl %ebx
4749; X86-BMI1NOTBM-NEXT:    pushl %edi
4750; X86-BMI1NOTBM-NEXT:    pushl %esi
4751; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4752; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4753; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
4754; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4755; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4756; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4757; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4758; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4759; X86-BMI1NOTBM-NEXT:    je .LBB39_2
4760; X86-BMI1NOTBM-NEXT:  # %bb.1:
4761; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4762; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4763; X86-BMI1NOTBM-NEXT:  .LBB39_2:
4764; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4765; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4766; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4767; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4768; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4769; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4770; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4771; X86-BMI1NOTBM-NEXT:    je .LBB39_4
4772; X86-BMI1NOTBM-NEXT:  # %bb.3:
4773; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4774; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4775; X86-BMI1NOTBM-NEXT:  .LBB39_4:
4776; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4777; X86-BMI1NOTBM-NEXT:    pushl %ebx
4778; X86-BMI1NOTBM-NEXT:    pushl %ebp
4779; X86-BMI1NOTBM-NEXT:    calll use64
4780; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4781; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4782; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4783; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4784; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4785; X86-BMI1NOTBM-NEXT:    addl $12, %esp
4786; X86-BMI1NOTBM-NEXT:    popl %esi
4787; X86-BMI1NOTBM-NEXT:    popl %edi
4788; X86-BMI1NOTBM-NEXT:    popl %ebx
4789; X86-BMI1NOTBM-NEXT:    popl %ebp
4790; X86-BMI1NOTBM-NEXT:    retl
4791;
4792; X86-BMI1BMI2-LABEL: bextr64_c1_indexzext:
4793; X86-BMI1BMI2:       # %bb.0:
4794; X86-BMI1BMI2-NEXT:    pushl %ebp
4795; X86-BMI1BMI2-NEXT:    pushl %ebx
4796; X86-BMI1BMI2-NEXT:    pushl %edi
4797; X86-BMI1BMI2-NEXT:    pushl %esi
4798; X86-BMI1BMI2-NEXT:    subl $12, %esp
4799; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
4800; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4801; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4802; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
4803; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
4804; X86-BMI1BMI2-NEXT:    testb $32, %cl
4805; X86-BMI1BMI2-NEXT:    je .LBB39_2
4806; X86-BMI1BMI2-NEXT:  # %bb.1:
4807; X86-BMI1BMI2-NEXT:    movl %edi, %esi
4808; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
4809; X86-BMI1BMI2-NEXT:  .LBB39_2:
4810; X86-BMI1BMI2-NEXT:    movb $64, %cl
4811; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
4812; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
4813; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
4814; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
4815; X86-BMI1BMI2-NEXT:    testb $32, %cl
4816; X86-BMI1BMI2-NEXT:    je .LBB39_4
4817; X86-BMI1BMI2-NEXT:  # %bb.3:
4818; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
4819; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
4820; X86-BMI1BMI2-NEXT:  .LBB39_4:
4821; X86-BMI1BMI2-NEXT:    subl $8, %esp
4822; X86-BMI1BMI2-NEXT:    pushl %ebp
4823; X86-BMI1BMI2-NEXT:    pushl %ebx
4824; X86-BMI1BMI2-NEXT:    calll use64
4825; X86-BMI1BMI2-NEXT:    addl $16, %esp
4826; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
4827; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
4828; X86-BMI1BMI2-NEXT:    movl %esi, %eax
4829; X86-BMI1BMI2-NEXT:    movl %edi, %edx
4830; X86-BMI1BMI2-NEXT:    addl $12, %esp
4831; X86-BMI1BMI2-NEXT:    popl %esi
4832; X86-BMI1BMI2-NEXT:    popl %edi
4833; X86-BMI1BMI2-NEXT:    popl %ebx
4834; X86-BMI1BMI2-NEXT:    popl %ebp
4835; X86-BMI1BMI2-NEXT:    retl
4836;
4837; X64-NOBMI-LABEL: bextr64_c1_indexzext:
4838; X64-NOBMI:       # %bb.0:
4839; X64-NOBMI-NEXT:    pushq %r14
4840; X64-NOBMI-NEXT:    pushq %rbx
4841; X64-NOBMI-NEXT:    pushq %rax
4842; X64-NOBMI-NEXT:    movl %esi, %ecx
4843; X64-NOBMI-NEXT:    movq %rdi, %r14
4844; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4845; X64-NOBMI-NEXT:    shrq %cl, %r14
4846; X64-NOBMI-NEXT:    negb %dl
4847; X64-NOBMI-NEXT:    movq $-1, %rbx
4848; X64-NOBMI-NEXT:    movl %edx, %ecx
4849; X64-NOBMI-NEXT:    shrq %cl, %rbx
4850; X64-NOBMI-NEXT:    movq %rbx, %rdi
4851; X64-NOBMI-NEXT:    callq use64
4852; X64-NOBMI-NEXT:    andq %r14, %rbx
4853; X64-NOBMI-NEXT:    movq %rbx, %rax
4854; X64-NOBMI-NEXT:    addq $8, %rsp
4855; X64-NOBMI-NEXT:    popq %rbx
4856; X64-NOBMI-NEXT:    popq %r14
4857; X64-NOBMI-NEXT:    retq
4858;
4859; X64-BMI1NOTBM-LABEL: bextr64_c1_indexzext:
4860; X64-BMI1NOTBM:       # %bb.0:
4861; X64-BMI1NOTBM-NEXT:    pushq %r14
4862; X64-BMI1NOTBM-NEXT:    pushq %rbx
4863; X64-BMI1NOTBM-NEXT:    pushq %rax
4864; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
4865; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
4866; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
4867; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
4868; X64-BMI1NOTBM-NEXT:    negb %dl
4869; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
4870; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
4871; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
4872; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
4873; X64-BMI1NOTBM-NEXT:    callq use64
4874; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
4875; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
4876; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
4877; X64-BMI1NOTBM-NEXT:    popq %rbx
4878; X64-BMI1NOTBM-NEXT:    popq %r14
4879; X64-BMI1NOTBM-NEXT:    retq
4880;
4881; X64-BMI1BMI2-LABEL: bextr64_c1_indexzext:
4882; X64-BMI1BMI2:       # %bb.0:
4883; X64-BMI1BMI2-NEXT:    pushq %r14
4884; X64-BMI1BMI2-NEXT:    pushq %rbx
4885; X64-BMI1BMI2-NEXT:    pushq %rax
4886; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
4887; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
4888; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
4889; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
4890; X64-BMI1BMI2-NEXT:    negb %al
4891; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
4892; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
4893; X64-BMI1BMI2-NEXT:    callq use64
4894; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
4895; X64-BMI1BMI2-NEXT:    addq $8, %rsp
4896; X64-BMI1BMI2-NEXT:    popq %rbx
4897; X64-BMI1BMI2-NEXT:    popq %r14
4898; X64-BMI1BMI2-NEXT:    retq
4899  %skip = zext i8 %numskipbits to i64
4900  %shifted = lshr i64 %val, %skip
4901  %numhighbits = sub i8 64, %numlowbits
4902  %sh_prom = zext i8 %numhighbits to i64
4903  %mask = lshr i64 -1, %sh_prom
4904  call void @use64(i64 %mask)
4905  %masked = and i64 %mask, %shifted
4906  ret i64 %masked
4907}
4908
4909define i64 @bextr64_c2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
4910; X86-NOBMI-LABEL: bextr64_c2_load:
4911; X86-NOBMI:       # %bb.0:
4912; X86-NOBMI-NEXT:    pushl %ebp
4913; X86-NOBMI-NEXT:    pushl %ebx
4914; X86-NOBMI-NEXT:    pushl %edi
4915; X86-NOBMI-NEXT:    pushl %esi
4916; X86-NOBMI-NEXT:    subl $12, %esp
4917; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
4918; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4919; X86-NOBMI-NEXT:    movl (%eax), %esi
4920; X86-NOBMI-NEXT:    movl 4(%eax), %eax
4921; X86-NOBMI-NEXT:    movl %eax, %edi
4922; X86-NOBMI-NEXT:    shrl %cl, %edi
4923; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4924; X86-NOBMI-NEXT:    testb $32, %cl
4925; X86-NOBMI-NEXT:    je .LBB40_2
4926; X86-NOBMI-NEXT:  # %bb.1:
4927; X86-NOBMI-NEXT:    movl %edi, %esi
4928; X86-NOBMI-NEXT:    xorl %edi, %edi
4929; X86-NOBMI-NEXT:  .LBB40_2:
4930; X86-NOBMI-NEXT:    movb $64, %cl
4931; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4932; X86-NOBMI-NEXT:    movl $-1, %ebp
4933; X86-NOBMI-NEXT:    movl $-1, %ebx
4934; X86-NOBMI-NEXT:    shrl %cl, %ebx
4935; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
4936; X86-NOBMI-NEXT:    testb $32, %cl
4937; X86-NOBMI-NEXT:    je .LBB40_4
4938; X86-NOBMI-NEXT:  # %bb.3:
4939; X86-NOBMI-NEXT:    movl %ebx, %ebp
4940; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4941; X86-NOBMI-NEXT:  .LBB40_4:
4942; X86-NOBMI-NEXT:    subl $8, %esp
4943; X86-NOBMI-NEXT:    pushl %ebx
4944; X86-NOBMI-NEXT:    pushl %ebp
4945; X86-NOBMI-NEXT:    calll use64
4946; X86-NOBMI-NEXT:    addl $16, %esp
4947; X86-NOBMI-NEXT:    andl %ebp, %esi
4948; X86-NOBMI-NEXT:    andl %ebx, %edi
4949; X86-NOBMI-NEXT:    movl %esi, %eax
4950; X86-NOBMI-NEXT:    movl %edi, %edx
4951; X86-NOBMI-NEXT:    addl $12, %esp
4952; X86-NOBMI-NEXT:    popl %esi
4953; X86-NOBMI-NEXT:    popl %edi
4954; X86-NOBMI-NEXT:    popl %ebx
4955; X86-NOBMI-NEXT:    popl %ebp
4956; X86-NOBMI-NEXT:    retl
4957;
4958; X86-BMI1NOTBM-LABEL: bextr64_c2_load:
4959; X86-BMI1NOTBM:       # %bb.0:
4960; X86-BMI1NOTBM-NEXT:    pushl %ebp
4961; X86-BMI1NOTBM-NEXT:    pushl %ebx
4962; X86-BMI1NOTBM-NEXT:    pushl %edi
4963; X86-BMI1NOTBM-NEXT:    pushl %esi
4964; X86-BMI1NOTBM-NEXT:    subl $12, %esp
4965; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
4966; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
4967; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
4968; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
4969; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
4970; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
4971; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
4972; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4973; X86-BMI1NOTBM-NEXT:    je .LBB40_2
4974; X86-BMI1NOTBM-NEXT:  # %bb.1:
4975; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
4976; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
4977; X86-BMI1NOTBM-NEXT:  .LBB40_2:
4978; X86-BMI1NOTBM-NEXT:    movb $64, %cl
4979; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
4980; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
4981; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
4982; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
4983; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
4984; X86-BMI1NOTBM-NEXT:    testb $32, %cl
4985; X86-BMI1NOTBM-NEXT:    je .LBB40_4
4986; X86-BMI1NOTBM-NEXT:  # %bb.3:
4987; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
4988; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
4989; X86-BMI1NOTBM-NEXT:  .LBB40_4:
4990; X86-BMI1NOTBM-NEXT:    subl $8, %esp
4991; X86-BMI1NOTBM-NEXT:    pushl %ebx
4992; X86-BMI1NOTBM-NEXT:    pushl %ebp
4993; X86-BMI1NOTBM-NEXT:    calll use64
4994; X86-BMI1NOTBM-NEXT:    addl $16, %esp
4995; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
4996; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
4997; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
4998; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
4999; X86-BMI1NOTBM-NEXT:    addl $12, %esp
5000; X86-BMI1NOTBM-NEXT:    popl %esi
5001; X86-BMI1NOTBM-NEXT:    popl %edi
5002; X86-BMI1NOTBM-NEXT:    popl %ebx
5003; X86-BMI1NOTBM-NEXT:    popl %ebp
5004; X86-BMI1NOTBM-NEXT:    retl
5005;
5006; X86-BMI1BMI2-LABEL: bextr64_c2_load:
5007; X86-BMI1BMI2:       # %bb.0:
5008; X86-BMI1BMI2-NEXT:    pushl %ebp
5009; X86-BMI1BMI2-NEXT:    pushl %ebx
5010; X86-BMI1BMI2-NEXT:    pushl %edi
5011; X86-BMI1BMI2-NEXT:    pushl %esi
5012; X86-BMI1BMI2-NEXT:    subl $12, %esp
5013; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5014; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5015; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
5016; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
5017; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
5018; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
5019; X86-BMI1BMI2-NEXT:    testb $32, %cl
5020; X86-BMI1BMI2-NEXT:    je .LBB40_2
5021; X86-BMI1BMI2-NEXT:  # %bb.1:
5022; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5023; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
5024; X86-BMI1BMI2-NEXT:  .LBB40_2:
5025; X86-BMI1BMI2-NEXT:    movb $64, %cl
5026; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5027; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
5028; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
5029; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
5030; X86-BMI1BMI2-NEXT:    testb $32, %cl
5031; X86-BMI1BMI2-NEXT:    je .LBB40_4
5032; X86-BMI1BMI2-NEXT:  # %bb.3:
5033; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
5034; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
5035; X86-BMI1BMI2-NEXT:  .LBB40_4:
5036; X86-BMI1BMI2-NEXT:    subl $8, %esp
5037; X86-BMI1BMI2-NEXT:    pushl %ebp
5038; X86-BMI1BMI2-NEXT:    pushl %ebx
5039; X86-BMI1BMI2-NEXT:    calll use64
5040; X86-BMI1BMI2-NEXT:    addl $16, %esp
5041; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
5042; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
5043; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5044; X86-BMI1BMI2-NEXT:    movl %edi, %edx
5045; X86-BMI1BMI2-NEXT:    addl $12, %esp
5046; X86-BMI1BMI2-NEXT:    popl %esi
5047; X86-BMI1BMI2-NEXT:    popl %edi
5048; X86-BMI1BMI2-NEXT:    popl %ebx
5049; X86-BMI1BMI2-NEXT:    popl %ebp
5050; X86-BMI1BMI2-NEXT:    retl
5051;
5052; X64-NOBMI-LABEL: bextr64_c2_load:
5053; X64-NOBMI:       # %bb.0:
5054; X64-NOBMI-NEXT:    pushq %r14
5055; X64-NOBMI-NEXT:    pushq %rbx
5056; X64-NOBMI-NEXT:    pushq %rax
5057; X64-NOBMI-NEXT:    movq %rsi, %rcx
5058; X64-NOBMI-NEXT:    movq (%rdi), %r14
5059; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5060; X64-NOBMI-NEXT:    shrq %cl, %r14
5061; X64-NOBMI-NEXT:    negb %dl
5062; X64-NOBMI-NEXT:    movq $-1, %rbx
5063; X64-NOBMI-NEXT:    movl %edx, %ecx
5064; X64-NOBMI-NEXT:    shrq %cl, %rbx
5065; X64-NOBMI-NEXT:    movq %rbx, %rdi
5066; X64-NOBMI-NEXT:    callq use64
5067; X64-NOBMI-NEXT:    andq %r14, %rbx
5068; X64-NOBMI-NEXT:    movq %rbx, %rax
5069; X64-NOBMI-NEXT:    addq $8, %rsp
5070; X64-NOBMI-NEXT:    popq %rbx
5071; X64-NOBMI-NEXT:    popq %r14
5072; X64-NOBMI-NEXT:    retq
5073;
5074; X64-BMI1NOTBM-LABEL: bextr64_c2_load:
5075; X64-BMI1NOTBM:       # %bb.0:
5076; X64-BMI1NOTBM-NEXT:    pushq %r14
5077; X64-BMI1NOTBM-NEXT:    pushq %rbx
5078; X64-BMI1NOTBM-NEXT:    pushq %rax
5079; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
5080; X64-BMI1NOTBM-NEXT:    movq (%rdi), %r14
5081; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
5082; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
5083; X64-BMI1NOTBM-NEXT:    negb %dl
5084; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
5085; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5086; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
5087; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
5088; X64-BMI1NOTBM-NEXT:    callq use64
5089; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
5090; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
5091; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
5092; X64-BMI1NOTBM-NEXT:    popq %rbx
5093; X64-BMI1NOTBM-NEXT:    popq %r14
5094; X64-BMI1NOTBM-NEXT:    retq
5095;
5096; X64-BMI1BMI2-LABEL: bextr64_c2_load:
5097; X64-BMI1BMI2:       # %bb.0:
5098; X64-BMI1BMI2-NEXT:    pushq %r14
5099; X64-BMI1BMI2-NEXT:    pushq %rbx
5100; X64-BMI1BMI2-NEXT:    pushq %rax
5101; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
5102; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
5103; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5104; X64-BMI1BMI2-NEXT:    negb %al
5105; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
5106; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
5107; X64-BMI1BMI2-NEXT:    callq use64
5108; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5109; X64-BMI1BMI2-NEXT:    addq $8, %rsp
5110; X64-BMI1BMI2-NEXT:    popq %rbx
5111; X64-BMI1BMI2-NEXT:    popq %r14
5112; X64-BMI1BMI2-NEXT:    retq
5113  %val = load i64, i64* %w
5114  %shifted = lshr i64 %val, %numskipbits
5115  %numhighbits = sub i64 64, %numlowbits
5116  %mask = lshr i64 -1, %numhighbits
5117  call void @use64(i64 %mask)
5118  %masked = and i64 %mask, %shifted
5119  ret i64 %masked
5120}
5121
5122define i64 @bextr64_c3_load_indexzext(i64* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
5123; X86-NOBMI-LABEL: bextr64_c3_load_indexzext:
5124; X86-NOBMI:       # %bb.0:
5125; X86-NOBMI-NEXT:    pushl %ebp
5126; X86-NOBMI-NEXT:    pushl %ebx
5127; X86-NOBMI-NEXT:    pushl %edi
5128; X86-NOBMI-NEXT:    pushl %esi
5129; X86-NOBMI-NEXT:    subl $12, %esp
5130; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5131; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5132; X86-NOBMI-NEXT:    movl (%eax), %esi
5133; X86-NOBMI-NEXT:    movl 4(%eax), %eax
5134; X86-NOBMI-NEXT:    movl %eax, %edi
5135; X86-NOBMI-NEXT:    shrl %cl, %edi
5136; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5137; X86-NOBMI-NEXT:    testb $32, %cl
5138; X86-NOBMI-NEXT:    je .LBB41_2
5139; X86-NOBMI-NEXT:  # %bb.1:
5140; X86-NOBMI-NEXT:    movl %edi, %esi
5141; X86-NOBMI-NEXT:    xorl %edi, %edi
5142; X86-NOBMI-NEXT:  .LBB41_2:
5143; X86-NOBMI-NEXT:    movb $64, %cl
5144; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5145; X86-NOBMI-NEXT:    movl $-1, %ebp
5146; X86-NOBMI-NEXT:    movl $-1, %ebx
5147; X86-NOBMI-NEXT:    shrl %cl, %ebx
5148; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
5149; X86-NOBMI-NEXT:    testb $32, %cl
5150; X86-NOBMI-NEXT:    je .LBB41_4
5151; X86-NOBMI-NEXT:  # %bb.3:
5152; X86-NOBMI-NEXT:    movl %ebx, %ebp
5153; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5154; X86-NOBMI-NEXT:  .LBB41_4:
5155; X86-NOBMI-NEXT:    subl $8, %esp
5156; X86-NOBMI-NEXT:    pushl %ebx
5157; X86-NOBMI-NEXT:    pushl %ebp
5158; X86-NOBMI-NEXT:    calll use64
5159; X86-NOBMI-NEXT:    addl $16, %esp
5160; X86-NOBMI-NEXT:    andl %ebp, %esi
5161; X86-NOBMI-NEXT:    andl %ebx, %edi
5162; X86-NOBMI-NEXT:    movl %esi, %eax
5163; X86-NOBMI-NEXT:    movl %edi, %edx
5164; X86-NOBMI-NEXT:    addl $12, %esp
5165; X86-NOBMI-NEXT:    popl %esi
5166; X86-NOBMI-NEXT:    popl %edi
5167; X86-NOBMI-NEXT:    popl %ebx
5168; X86-NOBMI-NEXT:    popl %ebp
5169; X86-NOBMI-NEXT:    retl
5170;
5171; X86-BMI1NOTBM-LABEL: bextr64_c3_load_indexzext:
5172; X86-BMI1NOTBM:       # %bb.0:
5173; X86-BMI1NOTBM-NEXT:    pushl %ebp
5174; X86-BMI1NOTBM-NEXT:    pushl %ebx
5175; X86-BMI1NOTBM-NEXT:    pushl %edi
5176; X86-BMI1NOTBM-NEXT:    pushl %esi
5177; X86-BMI1NOTBM-NEXT:    subl $12, %esp
5178; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5179; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5180; X86-BMI1NOTBM-NEXT:    movl (%eax), %esi
5181; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %eax
5182; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5183; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
5184; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
5185; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5186; X86-BMI1NOTBM-NEXT:    je .LBB41_2
5187; X86-BMI1NOTBM-NEXT:  # %bb.1:
5188; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5189; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
5190; X86-BMI1NOTBM-NEXT:  .LBB41_2:
5191; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5192; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5193; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
5194; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
5195; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
5196; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
5197; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5198; X86-BMI1NOTBM-NEXT:    je .LBB41_4
5199; X86-BMI1NOTBM-NEXT:  # %bb.3:
5200; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
5201; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
5202; X86-BMI1NOTBM-NEXT:  .LBB41_4:
5203; X86-BMI1NOTBM-NEXT:    subl $8, %esp
5204; X86-BMI1NOTBM-NEXT:    pushl %ebx
5205; X86-BMI1NOTBM-NEXT:    pushl %ebp
5206; X86-BMI1NOTBM-NEXT:    calll use64
5207; X86-BMI1NOTBM-NEXT:    addl $16, %esp
5208; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
5209; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
5210; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5211; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
5212; X86-BMI1NOTBM-NEXT:    addl $12, %esp
5213; X86-BMI1NOTBM-NEXT:    popl %esi
5214; X86-BMI1NOTBM-NEXT:    popl %edi
5215; X86-BMI1NOTBM-NEXT:    popl %ebx
5216; X86-BMI1NOTBM-NEXT:    popl %ebp
5217; X86-BMI1NOTBM-NEXT:    retl
5218;
5219; X86-BMI1BMI2-LABEL: bextr64_c3_load_indexzext:
5220; X86-BMI1BMI2:       # %bb.0:
5221; X86-BMI1BMI2-NEXT:    pushl %ebp
5222; X86-BMI1BMI2-NEXT:    pushl %ebx
5223; X86-BMI1BMI2-NEXT:    pushl %edi
5224; X86-BMI1BMI2-NEXT:    pushl %esi
5225; X86-BMI1BMI2-NEXT:    subl $12, %esp
5226; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5227; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5228; X86-BMI1BMI2-NEXT:    movl (%eax), %esi
5229; X86-BMI1BMI2-NEXT:    movl 4(%eax), %eax
5230; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
5231; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
5232; X86-BMI1BMI2-NEXT:    testb $32, %cl
5233; X86-BMI1BMI2-NEXT:    je .LBB41_2
5234; X86-BMI1BMI2-NEXT:  # %bb.1:
5235; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5236; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
5237; X86-BMI1BMI2-NEXT:  .LBB41_2:
5238; X86-BMI1BMI2-NEXT:    movb $64, %cl
5239; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5240; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
5241; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
5242; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
5243; X86-BMI1BMI2-NEXT:    testb $32, %cl
5244; X86-BMI1BMI2-NEXT:    je .LBB41_4
5245; X86-BMI1BMI2-NEXT:  # %bb.3:
5246; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
5247; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
5248; X86-BMI1BMI2-NEXT:  .LBB41_4:
5249; X86-BMI1BMI2-NEXT:    subl $8, %esp
5250; X86-BMI1BMI2-NEXT:    pushl %ebp
5251; X86-BMI1BMI2-NEXT:    pushl %ebx
5252; X86-BMI1BMI2-NEXT:    calll use64
5253; X86-BMI1BMI2-NEXT:    addl $16, %esp
5254; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
5255; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
5256; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5257; X86-BMI1BMI2-NEXT:    movl %edi, %edx
5258; X86-BMI1BMI2-NEXT:    addl $12, %esp
5259; X86-BMI1BMI2-NEXT:    popl %esi
5260; X86-BMI1BMI2-NEXT:    popl %edi
5261; X86-BMI1BMI2-NEXT:    popl %ebx
5262; X86-BMI1BMI2-NEXT:    popl %ebp
5263; X86-BMI1BMI2-NEXT:    retl
5264;
5265; X64-NOBMI-LABEL: bextr64_c3_load_indexzext:
5266; X64-NOBMI:       # %bb.0:
5267; X64-NOBMI-NEXT:    pushq %r14
5268; X64-NOBMI-NEXT:    pushq %rbx
5269; X64-NOBMI-NEXT:    pushq %rax
5270; X64-NOBMI-NEXT:    movl %esi, %ecx
5271; X64-NOBMI-NEXT:    movq (%rdi), %r14
5272; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5273; X64-NOBMI-NEXT:    shrq %cl, %r14
5274; X64-NOBMI-NEXT:    negb %dl
5275; X64-NOBMI-NEXT:    movq $-1, %rbx
5276; X64-NOBMI-NEXT:    movl %edx, %ecx
5277; X64-NOBMI-NEXT:    shrq %cl, %rbx
5278; X64-NOBMI-NEXT:    movq %rbx, %rdi
5279; X64-NOBMI-NEXT:    callq use64
5280; X64-NOBMI-NEXT:    andq %r14, %rbx
5281; X64-NOBMI-NEXT:    movq %rbx, %rax
5282; X64-NOBMI-NEXT:    addq $8, %rsp
5283; X64-NOBMI-NEXT:    popq %rbx
5284; X64-NOBMI-NEXT:    popq %r14
5285; X64-NOBMI-NEXT:    retq
5286;
5287; X64-BMI1NOTBM-LABEL: bextr64_c3_load_indexzext:
5288; X64-BMI1NOTBM:       # %bb.0:
5289; X64-BMI1NOTBM-NEXT:    pushq %r14
5290; X64-BMI1NOTBM-NEXT:    pushq %rbx
5291; X64-BMI1NOTBM-NEXT:    pushq %rax
5292; X64-BMI1NOTBM-NEXT:    movl %esi, %ecx
5293; X64-BMI1NOTBM-NEXT:    movq (%rdi), %r14
5294; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $ecx
5295; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
5296; X64-BMI1NOTBM-NEXT:    negb %dl
5297; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
5298; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5299; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
5300; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
5301; X64-BMI1NOTBM-NEXT:    callq use64
5302; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
5303; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
5304; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
5305; X64-BMI1NOTBM-NEXT:    popq %rbx
5306; X64-BMI1NOTBM-NEXT:    popq %r14
5307; X64-BMI1NOTBM-NEXT:    retq
5308;
5309; X64-BMI1BMI2-LABEL: bextr64_c3_load_indexzext:
5310; X64-BMI1BMI2:       # %bb.0:
5311; X64-BMI1BMI2-NEXT:    pushq %r14
5312; X64-BMI1BMI2-NEXT:    pushq %rbx
5313; X64-BMI1BMI2-NEXT:    pushq %rax
5314; X64-BMI1BMI2-NEXT:    movl %edx, %ebx
5315; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
5316; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
5317; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5318; X64-BMI1BMI2-NEXT:    negb %al
5319; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
5320; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
5321; X64-BMI1BMI2-NEXT:    callq use64
5322; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5323; X64-BMI1BMI2-NEXT:    addq $8, %rsp
5324; X64-BMI1BMI2-NEXT:    popq %rbx
5325; X64-BMI1BMI2-NEXT:    popq %r14
5326; X64-BMI1BMI2-NEXT:    retq
5327  %val = load i64, i64* %w
5328  %skip = zext i8 %numskipbits to i64
5329  %shifted = lshr i64 %val, %skip
5330  %numhighbits = sub i8 64, %numlowbits
5331  %sh_prom = zext i8 %numhighbits to i64
5332  %mask = lshr i64 -1, %sh_prom
5333  call void @use64(i64 %mask)
5334  %masked = and i64 %mask, %shifted
5335  ret i64 %masked
5336}
5337
5338define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5339; X86-NOBMI-LABEL: bextr64_c4_commutative:
5340; X86-NOBMI:       # %bb.0:
5341; X86-NOBMI-NEXT:    pushl %ebp
5342; X86-NOBMI-NEXT:    pushl %ebx
5343; X86-NOBMI-NEXT:    pushl %edi
5344; X86-NOBMI-NEXT:    pushl %esi
5345; X86-NOBMI-NEXT:    subl $12, %esp
5346; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5347; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5348; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5349; X86-NOBMI-NEXT:    movl %eax, %edi
5350; X86-NOBMI-NEXT:    shrl %cl, %edi
5351; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5352; X86-NOBMI-NEXT:    testb $32, %cl
5353; X86-NOBMI-NEXT:    je .LBB42_2
5354; X86-NOBMI-NEXT:  # %bb.1:
5355; X86-NOBMI-NEXT:    movl %edi, %esi
5356; X86-NOBMI-NEXT:    xorl %edi, %edi
5357; X86-NOBMI-NEXT:  .LBB42_2:
5358; X86-NOBMI-NEXT:    movb $64, %cl
5359; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5360; X86-NOBMI-NEXT:    movl $-1, %ebp
5361; X86-NOBMI-NEXT:    movl $-1, %ebx
5362; X86-NOBMI-NEXT:    shrl %cl, %ebx
5363; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %ebp
5364; X86-NOBMI-NEXT:    testb $32, %cl
5365; X86-NOBMI-NEXT:    je .LBB42_4
5366; X86-NOBMI-NEXT:  # %bb.3:
5367; X86-NOBMI-NEXT:    movl %ebx, %ebp
5368; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5369; X86-NOBMI-NEXT:  .LBB42_4:
5370; X86-NOBMI-NEXT:    subl $8, %esp
5371; X86-NOBMI-NEXT:    pushl %ebx
5372; X86-NOBMI-NEXT:    pushl %ebp
5373; X86-NOBMI-NEXT:    calll use64
5374; X86-NOBMI-NEXT:    addl $16, %esp
5375; X86-NOBMI-NEXT:    andl %ebp, %esi
5376; X86-NOBMI-NEXT:    andl %ebx, %edi
5377; X86-NOBMI-NEXT:    movl %esi, %eax
5378; X86-NOBMI-NEXT:    movl %edi, %edx
5379; X86-NOBMI-NEXT:    addl $12, %esp
5380; X86-NOBMI-NEXT:    popl %esi
5381; X86-NOBMI-NEXT:    popl %edi
5382; X86-NOBMI-NEXT:    popl %ebx
5383; X86-NOBMI-NEXT:    popl %ebp
5384; X86-NOBMI-NEXT:    retl
5385;
5386; X86-BMI1NOTBM-LABEL: bextr64_c4_commutative:
5387; X86-BMI1NOTBM:       # %bb.0:
5388; X86-BMI1NOTBM-NEXT:    pushl %ebp
5389; X86-BMI1NOTBM-NEXT:    pushl %ebx
5390; X86-BMI1NOTBM-NEXT:    pushl %edi
5391; X86-BMI1NOTBM-NEXT:    pushl %esi
5392; X86-BMI1NOTBM-NEXT:    subl $12, %esp
5393; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5394; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
5395; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5396; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5397; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
5398; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
5399; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5400; X86-BMI1NOTBM-NEXT:    je .LBB42_2
5401; X86-BMI1NOTBM-NEXT:  # %bb.1:
5402; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5403; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
5404; X86-BMI1NOTBM-NEXT:  .LBB42_2:
5405; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5406; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5407; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
5408; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
5409; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebx
5410; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %ebp
5411; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5412; X86-BMI1NOTBM-NEXT:    je .LBB42_4
5413; X86-BMI1NOTBM-NEXT:  # %bb.3:
5414; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
5415; X86-BMI1NOTBM-NEXT:    xorl %ebx, %ebx
5416; X86-BMI1NOTBM-NEXT:  .LBB42_4:
5417; X86-BMI1NOTBM-NEXT:    subl $8, %esp
5418; X86-BMI1NOTBM-NEXT:    pushl %ebx
5419; X86-BMI1NOTBM-NEXT:    pushl %ebp
5420; X86-BMI1NOTBM-NEXT:    calll use64
5421; X86-BMI1NOTBM-NEXT:    addl $16, %esp
5422; X86-BMI1NOTBM-NEXT:    andl %ebp, %esi
5423; X86-BMI1NOTBM-NEXT:    andl %ebx, %edi
5424; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5425; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
5426; X86-BMI1NOTBM-NEXT:    addl $12, %esp
5427; X86-BMI1NOTBM-NEXT:    popl %esi
5428; X86-BMI1NOTBM-NEXT:    popl %edi
5429; X86-BMI1NOTBM-NEXT:    popl %ebx
5430; X86-BMI1NOTBM-NEXT:    popl %ebp
5431; X86-BMI1NOTBM-NEXT:    retl
5432;
5433; X86-BMI1BMI2-LABEL: bextr64_c4_commutative:
5434; X86-BMI1BMI2:       # %bb.0:
5435; X86-BMI1BMI2-NEXT:    pushl %ebp
5436; X86-BMI1BMI2-NEXT:    pushl %ebx
5437; X86-BMI1BMI2-NEXT:    pushl %edi
5438; X86-BMI1BMI2-NEXT:    pushl %esi
5439; X86-BMI1BMI2-NEXT:    subl $12, %esp
5440; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5441; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5442; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5443; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
5444; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
5445; X86-BMI1BMI2-NEXT:    testb $32, %cl
5446; X86-BMI1BMI2-NEXT:    je .LBB42_2
5447; X86-BMI1BMI2-NEXT:  # %bb.1:
5448; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5449; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
5450; X86-BMI1BMI2-NEXT:  .LBB42_2:
5451; X86-BMI1BMI2-NEXT:    movb $64, %cl
5452; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5453; X86-BMI1BMI2-NEXT:    movl $-1, %ebx
5454; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebx, %ebp
5455; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebx, %ebx
5456; X86-BMI1BMI2-NEXT:    testb $32, %cl
5457; X86-BMI1BMI2-NEXT:    je .LBB42_4
5458; X86-BMI1BMI2-NEXT:  # %bb.3:
5459; X86-BMI1BMI2-NEXT:    movl %ebp, %ebx
5460; X86-BMI1BMI2-NEXT:    xorl %ebp, %ebp
5461; X86-BMI1BMI2-NEXT:  .LBB42_4:
5462; X86-BMI1BMI2-NEXT:    subl $8, %esp
5463; X86-BMI1BMI2-NEXT:    pushl %ebp
5464; X86-BMI1BMI2-NEXT:    pushl %ebx
5465; X86-BMI1BMI2-NEXT:    calll use64
5466; X86-BMI1BMI2-NEXT:    addl $16, %esp
5467; X86-BMI1BMI2-NEXT:    andl %ebx, %esi
5468; X86-BMI1BMI2-NEXT:    andl %ebp, %edi
5469; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5470; X86-BMI1BMI2-NEXT:    movl %edi, %edx
5471; X86-BMI1BMI2-NEXT:    addl $12, %esp
5472; X86-BMI1BMI2-NEXT:    popl %esi
5473; X86-BMI1BMI2-NEXT:    popl %edi
5474; X86-BMI1BMI2-NEXT:    popl %ebx
5475; X86-BMI1BMI2-NEXT:    popl %ebp
5476; X86-BMI1BMI2-NEXT:    retl
5477;
5478; X64-NOBMI-LABEL: bextr64_c4_commutative:
5479; X64-NOBMI:       # %bb.0:
5480; X64-NOBMI-NEXT:    pushq %r14
5481; X64-NOBMI-NEXT:    pushq %rbx
5482; X64-NOBMI-NEXT:    pushq %rax
5483; X64-NOBMI-NEXT:    movq %rsi, %rcx
5484; X64-NOBMI-NEXT:    movq %rdi, %r14
5485; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5486; X64-NOBMI-NEXT:    shrq %cl, %r14
5487; X64-NOBMI-NEXT:    negb %dl
5488; X64-NOBMI-NEXT:    movq $-1, %rbx
5489; X64-NOBMI-NEXT:    movl %edx, %ecx
5490; X64-NOBMI-NEXT:    shrq %cl, %rbx
5491; X64-NOBMI-NEXT:    movq %rbx, %rdi
5492; X64-NOBMI-NEXT:    callq use64
5493; X64-NOBMI-NEXT:    andq %r14, %rbx
5494; X64-NOBMI-NEXT:    movq %rbx, %rax
5495; X64-NOBMI-NEXT:    addq $8, %rsp
5496; X64-NOBMI-NEXT:    popq %rbx
5497; X64-NOBMI-NEXT:    popq %r14
5498; X64-NOBMI-NEXT:    retq
5499;
5500; X64-BMI1NOTBM-LABEL: bextr64_c4_commutative:
5501; X64-BMI1NOTBM:       # %bb.0:
5502; X64-BMI1NOTBM-NEXT:    pushq %r14
5503; X64-BMI1NOTBM-NEXT:    pushq %rbx
5504; X64-BMI1NOTBM-NEXT:    pushq %rax
5505; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
5506; X64-BMI1NOTBM-NEXT:    movq %rdi, %r14
5507; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
5508; X64-BMI1NOTBM-NEXT:    shrq %cl, %r14
5509; X64-BMI1NOTBM-NEXT:    negb %dl
5510; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
5511; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5512; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
5513; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
5514; X64-BMI1NOTBM-NEXT:    callq use64
5515; X64-BMI1NOTBM-NEXT:    andq %r14, %rbx
5516; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
5517; X64-BMI1NOTBM-NEXT:    addq $8, %rsp
5518; X64-BMI1NOTBM-NEXT:    popq %rbx
5519; X64-BMI1NOTBM-NEXT:    popq %r14
5520; X64-BMI1NOTBM-NEXT:    retq
5521;
5522; X64-BMI1BMI2-LABEL: bextr64_c4_commutative:
5523; X64-BMI1BMI2:       # %bb.0:
5524; X64-BMI1BMI2-NEXT:    pushq %r14
5525; X64-BMI1BMI2-NEXT:    pushq %rbx
5526; X64-BMI1BMI2-NEXT:    pushq %rax
5527; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
5528; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r14
5529; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5530; X64-BMI1BMI2-NEXT:    negb %al
5531; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
5532; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
5533; X64-BMI1BMI2-NEXT:    callq use64
5534; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5535; X64-BMI1BMI2-NEXT:    addq $8, %rsp
5536; X64-BMI1BMI2-NEXT:    popq %rbx
5537; X64-BMI1BMI2-NEXT:    popq %r14
5538; X64-BMI1BMI2-NEXT:    retq
5539  %shifted = lshr i64 %val, %numskipbits
5540  %numhighbits = sub i64 64, %numlowbits
5541  %mask = lshr i64 -1, %numhighbits
5542  call void @use64(i64 %mask)
5543  %masked = and i64 %shifted, %mask ; swapped order
5544  ret i64 %masked
5545}
5546
5547define i64 @bextr64_c5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5548; X86-NOBMI-LABEL: bextr64_c5_skipextrauses:
5549; X86-NOBMI:       # %bb.0:
5550; X86-NOBMI-NEXT:    pushl %ebp
5551; X86-NOBMI-NEXT:    pushl %ebx
5552; X86-NOBMI-NEXT:    pushl %edi
5553; X86-NOBMI-NEXT:    pushl %esi
5554; X86-NOBMI-NEXT:    subl $12, %esp
5555; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5556; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5557; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5558; X86-NOBMI-NEXT:    movl %eax, %edi
5559; X86-NOBMI-NEXT:    shrl %cl, %edi
5560; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5561; X86-NOBMI-NEXT:    testb $32, %cl
5562; X86-NOBMI-NEXT:    je .LBB43_2
5563; X86-NOBMI-NEXT:  # %bb.1:
5564; X86-NOBMI-NEXT:    movl %edi, %esi
5565; X86-NOBMI-NEXT:    xorl %edi, %edi
5566; X86-NOBMI-NEXT:  .LBB43_2:
5567; X86-NOBMI-NEXT:    movb $64, %cl
5568; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5569; X86-NOBMI-NEXT:    movl $-1, %ebx
5570; X86-NOBMI-NEXT:    movl $-1, %ebp
5571; X86-NOBMI-NEXT:    shrl %cl, %ebp
5572; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %ebx
5573; X86-NOBMI-NEXT:    testb $32, %cl
5574; X86-NOBMI-NEXT:    je .LBB43_4
5575; X86-NOBMI-NEXT:  # %bb.3:
5576; X86-NOBMI-NEXT:    movl %ebp, %ebx
5577; X86-NOBMI-NEXT:    xorl %ebp, %ebp
5578; X86-NOBMI-NEXT:  .LBB43_4:
5579; X86-NOBMI-NEXT:    subl $8, %esp
5580; X86-NOBMI-NEXT:    pushl %ebp
5581; X86-NOBMI-NEXT:    pushl %ebx
5582; X86-NOBMI-NEXT:    calll use64
5583; X86-NOBMI-NEXT:    addl $16, %esp
5584; X86-NOBMI-NEXT:    andl %ebx, %esi
5585; X86-NOBMI-NEXT:    andl %ebp, %edi
5586; X86-NOBMI-NEXT:    subl $8, %esp
5587; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
5588; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
5589; X86-NOBMI-NEXT:    calll use64
5590; X86-NOBMI-NEXT:    addl $16, %esp
5591; X86-NOBMI-NEXT:    movl %esi, %eax
5592; X86-NOBMI-NEXT:    movl %edi, %edx
5593; X86-NOBMI-NEXT:    addl $12, %esp
5594; X86-NOBMI-NEXT:    popl %esi
5595; X86-NOBMI-NEXT:    popl %edi
5596; X86-NOBMI-NEXT:    popl %ebx
5597; X86-NOBMI-NEXT:    popl %ebp
5598; X86-NOBMI-NEXT:    retl
5599;
5600; X86-BMI1NOTBM-LABEL: bextr64_c5_skipextrauses:
5601; X86-BMI1NOTBM:       # %bb.0:
5602; X86-BMI1NOTBM-NEXT:    pushl %ebp
5603; X86-BMI1NOTBM-NEXT:    pushl %ebx
5604; X86-BMI1NOTBM-NEXT:    pushl %edi
5605; X86-BMI1NOTBM-NEXT:    pushl %esi
5606; X86-BMI1NOTBM-NEXT:    subl $12, %esp
5607; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
5608; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5609; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5610; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
5611; X86-BMI1NOTBM-NEXT:    shrl %cl, %edi
5612; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %esi
5613; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5614; X86-BMI1NOTBM-NEXT:    je .LBB43_2
5615; X86-BMI1NOTBM-NEXT:  # %bb.1:
5616; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
5617; X86-BMI1NOTBM-NEXT:    xorl %edi, %edi
5618; X86-BMI1NOTBM-NEXT:  .LBB43_2:
5619; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5620; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5621; X86-BMI1NOTBM-NEXT:    movl $-1, %ebx
5622; X86-BMI1NOTBM-NEXT:    movl $-1, %ebp
5623; X86-BMI1NOTBM-NEXT:    shrl %cl, %ebp
5624; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %ebx
5625; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5626; X86-BMI1NOTBM-NEXT:    je .LBB43_4
5627; X86-BMI1NOTBM-NEXT:  # %bb.3:
5628; X86-BMI1NOTBM-NEXT:    movl %ebp, %ebx
5629; X86-BMI1NOTBM-NEXT:    xorl %ebp, %ebp
5630; X86-BMI1NOTBM-NEXT:  .LBB43_4:
5631; X86-BMI1NOTBM-NEXT:    subl $8, %esp
5632; X86-BMI1NOTBM-NEXT:    pushl %ebp
5633; X86-BMI1NOTBM-NEXT:    pushl %ebx
5634; X86-BMI1NOTBM-NEXT:    calll use64
5635; X86-BMI1NOTBM-NEXT:    addl $16, %esp
5636; X86-BMI1NOTBM-NEXT:    andl %ebx, %esi
5637; X86-BMI1NOTBM-NEXT:    andl %ebp, %edi
5638; X86-BMI1NOTBM-NEXT:    subl $8, %esp
5639; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
5640; X86-BMI1NOTBM-NEXT:    pushl {{[0-9]+}}(%esp)
5641; X86-BMI1NOTBM-NEXT:    calll use64
5642; X86-BMI1NOTBM-NEXT:    addl $16, %esp
5643; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5644; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
5645; X86-BMI1NOTBM-NEXT:    addl $12, %esp
5646; X86-BMI1NOTBM-NEXT:    popl %esi
5647; X86-BMI1NOTBM-NEXT:    popl %edi
5648; X86-BMI1NOTBM-NEXT:    popl %ebx
5649; X86-BMI1NOTBM-NEXT:    popl %ebp
5650; X86-BMI1NOTBM-NEXT:    retl
5651;
5652; X86-BMI1BMI2-LABEL: bextr64_c5_skipextrauses:
5653; X86-BMI1BMI2:       # %bb.0:
5654; X86-BMI1BMI2-NEXT:    pushl %ebp
5655; X86-BMI1BMI2-NEXT:    pushl %ebx
5656; X86-BMI1BMI2-NEXT:    pushl %edi
5657; X86-BMI1BMI2-NEXT:    pushl %esi
5658; X86-BMI1BMI2-NEXT:    subl $12, %esp
5659; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5660; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5661; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5662; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %esi
5663; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edi
5664; X86-BMI1BMI2-NEXT:    testb $32, %cl
5665; X86-BMI1BMI2-NEXT:    je .LBB43_2
5666; X86-BMI1BMI2-NEXT:  # %bb.1:
5667; X86-BMI1BMI2-NEXT:    movl %edi, %esi
5668; X86-BMI1BMI2-NEXT:    xorl %edi, %edi
5669; X86-BMI1BMI2-NEXT:  .LBB43_2:
5670; X86-BMI1BMI2-NEXT:    movb $64, %cl
5671; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5672; X86-BMI1BMI2-NEXT:    movl $-1, %ebp
5673; X86-BMI1BMI2-NEXT:    shrxl %ecx, %ebp, %ebx
5674; X86-BMI1BMI2-NEXT:    shrdl %cl, %ebp, %ebp
5675; X86-BMI1BMI2-NEXT:    testb $32, %cl
5676; X86-BMI1BMI2-NEXT:    je .LBB43_4
5677; X86-BMI1BMI2-NEXT:  # %bb.3:
5678; X86-BMI1BMI2-NEXT:    movl %ebx, %ebp
5679; X86-BMI1BMI2-NEXT:    xorl %ebx, %ebx
5680; X86-BMI1BMI2-NEXT:  .LBB43_4:
5681; X86-BMI1BMI2-NEXT:    subl $8, %esp
5682; X86-BMI1BMI2-NEXT:    pushl %ebx
5683; X86-BMI1BMI2-NEXT:    pushl %ebp
5684; X86-BMI1BMI2-NEXT:    calll use64
5685; X86-BMI1BMI2-NEXT:    addl $16, %esp
5686; X86-BMI1BMI2-NEXT:    andl %ebp, %esi
5687; X86-BMI1BMI2-NEXT:    andl %ebx, %edi
5688; X86-BMI1BMI2-NEXT:    subl $8, %esp
5689; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
5690; X86-BMI1BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
5691; X86-BMI1BMI2-NEXT:    calll use64
5692; X86-BMI1BMI2-NEXT:    addl $16, %esp
5693; X86-BMI1BMI2-NEXT:    movl %esi, %eax
5694; X86-BMI1BMI2-NEXT:    movl %edi, %edx
5695; X86-BMI1BMI2-NEXT:    addl $12, %esp
5696; X86-BMI1BMI2-NEXT:    popl %esi
5697; X86-BMI1BMI2-NEXT:    popl %edi
5698; X86-BMI1BMI2-NEXT:    popl %ebx
5699; X86-BMI1BMI2-NEXT:    popl %ebp
5700; X86-BMI1BMI2-NEXT:    retl
5701;
5702; X64-NOBMI-LABEL: bextr64_c5_skipextrauses:
5703; X64-NOBMI:       # %bb.0:
5704; X64-NOBMI-NEXT:    pushq %r15
5705; X64-NOBMI-NEXT:    pushq %r14
5706; X64-NOBMI-NEXT:    pushq %rbx
5707; X64-NOBMI-NEXT:    movq %rsi, %r14
5708; X64-NOBMI-NEXT:    movq %rdi, %r15
5709; X64-NOBMI-NEXT:    movl %r14d, %ecx
5710; X64-NOBMI-NEXT:    shrq %cl, %r15
5711; X64-NOBMI-NEXT:    negb %dl
5712; X64-NOBMI-NEXT:    movq $-1, %rbx
5713; X64-NOBMI-NEXT:    movl %edx, %ecx
5714; X64-NOBMI-NEXT:    shrq %cl, %rbx
5715; X64-NOBMI-NEXT:    movq %rbx, %rdi
5716; X64-NOBMI-NEXT:    callq use64
5717; X64-NOBMI-NEXT:    andq %r15, %rbx
5718; X64-NOBMI-NEXT:    movq %r14, %rdi
5719; X64-NOBMI-NEXT:    callq use64
5720; X64-NOBMI-NEXT:    movq %rbx, %rax
5721; X64-NOBMI-NEXT:    popq %rbx
5722; X64-NOBMI-NEXT:    popq %r14
5723; X64-NOBMI-NEXT:    popq %r15
5724; X64-NOBMI-NEXT:    retq
5725;
5726; X64-BMI1NOTBM-LABEL: bextr64_c5_skipextrauses:
5727; X64-BMI1NOTBM:       # %bb.0:
5728; X64-BMI1NOTBM-NEXT:    pushq %r15
5729; X64-BMI1NOTBM-NEXT:    pushq %r14
5730; X64-BMI1NOTBM-NEXT:    pushq %rbx
5731; X64-BMI1NOTBM-NEXT:    movq %rsi, %r14
5732; X64-BMI1NOTBM-NEXT:    movq %rdi, %r15
5733; X64-BMI1NOTBM-NEXT:    movl %r14d, %ecx
5734; X64-BMI1NOTBM-NEXT:    shrq %cl, %r15
5735; X64-BMI1NOTBM-NEXT:    negb %dl
5736; X64-BMI1NOTBM-NEXT:    movq $-1, %rbx
5737; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5738; X64-BMI1NOTBM-NEXT:    shrq %cl, %rbx
5739; X64-BMI1NOTBM-NEXT:    movq %rbx, %rdi
5740; X64-BMI1NOTBM-NEXT:    callq use64
5741; X64-BMI1NOTBM-NEXT:    andq %r15, %rbx
5742; X64-BMI1NOTBM-NEXT:    movq %r14, %rdi
5743; X64-BMI1NOTBM-NEXT:    callq use64
5744; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
5745; X64-BMI1NOTBM-NEXT:    popq %rbx
5746; X64-BMI1NOTBM-NEXT:    popq %r14
5747; X64-BMI1NOTBM-NEXT:    popq %r15
5748; X64-BMI1NOTBM-NEXT:    retq
5749;
5750; X64-BMI1BMI2-LABEL: bextr64_c5_skipextrauses:
5751; X64-BMI1BMI2:       # %bb.0:
5752; X64-BMI1BMI2-NEXT:    pushq %r15
5753; X64-BMI1BMI2-NEXT:    pushq %r14
5754; X64-BMI1BMI2-NEXT:    pushq %rbx
5755; X64-BMI1BMI2-NEXT:    movq %rdx, %rbx
5756; X64-BMI1BMI2-NEXT:    movq %rsi, %r14
5757; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %r15
5758; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
5759; X64-BMI1BMI2-NEXT:    negb %al
5760; X64-BMI1BMI2-NEXT:    movq $-1, %rcx
5761; X64-BMI1BMI2-NEXT:    shrxq %rax, %rcx, %rdi
5762; X64-BMI1BMI2-NEXT:    callq use64
5763; X64-BMI1BMI2-NEXT:    bzhiq %rbx, %r15, %rbx
5764; X64-BMI1BMI2-NEXT:    movq %r14, %rdi
5765; X64-BMI1BMI2-NEXT:    callq use64
5766; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
5767; X64-BMI1BMI2-NEXT:    popq %rbx
5768; X64-BMI1BMI2-NEXT:    popq %r14
5769; X64-BMI1BMI2-NEXT:    popq %r15
5770; X64-BMI1BMI2-NEXT:    retq
5771  %shifted = lshr i64 %val, %numskipbits
5772  %numhighbits = sub i64 64, %numlowbits
5773  %mask = lshr i64 -1, %numhighbits
5774  call void @use64(i64 %mask)
5775  %masked = and i64 %mask, %shifted
5776  call void @use64(i64 %numskipbits)
5777  ret i64 %masked
5778}
5779
5780; 64-bit, but with 32-bit output
5781
5782; Everything done in 64-bit, truncation happens last.
5783define i32 @bextr64_32_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5784; X86-NOBMI-LABEL: bextr64_32_c0:
5785; X86-NOBMI:       # %bb.0:
5786; X86-NOBMI-NEXT:    pushl %esi
5787; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5788; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5789; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5790; X86-NOBMI-NEXT:    movl %esi, %edx
5791; X86-NOBMI-NEXT:    shrl %cl, %edx
5792; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
5793; X86-NOBMI-NEXT:    testb $32, %cl
5794; X86-NOBMI-NEXT:    jne .LBB44_2
5795; X86-NOBMI-NEXT:  # %bb.1:
5796; X86-NOBMI-NEXT:    movl %eax, %edx
5797; X86-NOBMI-NEXT:  .LBB44_2:
5798; X86-NOBMI-NEXT:    movb $64, %cl
5799; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5800; X86-NOBMI-NEXT:    movl $-1, %esi
5801; X86-NOBMI-NEXT:    movl $-1, %eax
5802; X86-NOBMI-NEXT:    shrl %cl, %eax
5803; X86-NOBMI-NEXT:    shrdl %cl, %esi, %esi
5804; X86-NOBMI-NEXT:    testb $32, %cl
5805; X86-NOBMI-NEXT:    jne .LBB44_4
5806; X86-NOBMI-NEXT:  # %bb.3:
5807; X86-NOBMI-NEXT:    movl %esi, %eax
5808; X86-NOBMI-NEXT:  .LBB44_4:
5809; X86-NOBMI-NEXT:    andl %edx, %eax
5810; X86-NOBMI-NEXT:    popl %esi
5811; X86-NOBMI-NEXT:    retl
5812;
5813; X86-BMI1NOTBM-LABEL: bextr64_32_c0:
5814; X86-BMI1NOTBM:       # %bb.0:
5815; X86-BMI1NOTBM-NEXT:    pushl %esi
5816; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5817; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
5818; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
5819; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
5820; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
5821; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %eax
5822; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5823; X86-BMI1NOTBM-NEXT:    jne .LBB44_2
5824; X86-BMI1NOTBM-NEXT:  # %bb.1:
5825; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
5826; X86-BMI1NOTBM-NEXT:  .LBB44_2:
5827; X86-BMI1NOTBM-NEXT:    movb $64, %cl
5828; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
5829; X86-BMI1NOTBM-NEXT:    movl $-1, %esi
5830; X86-BMI1NOTBM-NEXT:    movl $-1, %eax
5831; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
5832; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %esi
5833; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5834; X86-BMI1NOTBM-NEXT:    jne .LBB44_4
5835; X86-BMI1NOTBM-NEXT:  # %bb.3:
5836; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
5837; X86-BMI1NOTBM-NEXT:  .LBB44_4:
5838; X86-BMI1NOTBM-NEXT:    andl %edx, %eax
5839; X86-BMI1NOTBM-NEXT:    popl %esi
5840; X86-BMI1NOTBM-NEXT:    retl
5841;
5842; X86-BMI1BMI2-LABEL: bextr64_32_c0:
5843; X86-BMI1BMI2:       # %bb.0:
5844; X86-BMI1BMI2-NEXT:    pushl %esi
5845; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5846; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
5847; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5848; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %edx
5849; X86-BMI1BMI2-NEXT:    testb $32, %cl
5850; X86-BMI1BMI2-NEXT:    je .LBB44_2
5851; X86-BMI1BMI2-NEXT:  # %bb.1:
5852; X86-BMI1BMI2-NEXT:    shrxl %ecx, %eax, %edx
5853; X86-BMI1BMI2-NEXT:  .LBB44_2:
5854; X86-BMI1BMI2-NEXT:    movb $64, %cl
5855; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
5856; X86-BMI1BMI2-NEXT:    movl $-1, %esi
5857; X86-BMI1BMI2-NEXT:    movl $-1, %eax
5858; X86-BMI1BMI2-NEXT:    shrdl %cl, %eax, %eax
5859; X86-BMI1BMI2-NEXT:    testb $32, %cl
5860; X86-BMI1BMI2-NEXT:    je .LBB44_4
5861; X86-BMI1BMI2-NEXT:  # %bb.3:
5862; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
5863; X86-BMI1BMI2-NEXT:  .LBB44_4:
5864; X86-BMI1BMI2-NEXT:    andl %edx, %eax
5865; X86-BMI1BMI2-NEXT:    popl %esi
5866; X86-BMI1BMI2-NEXT:    retl
5867;
5868; X64-NOBMI-LABEL: bextr64_32_c0:
5869; X64-NOBMI:       # %bb.0:
5870; X64-NOBMI-NEXT:    movq %rsi, %rcx
5871; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5872; X64-NOBMI-NEXT:    shrq %cl, %rdi
5873; X64-NOBMI-NEXT:    negb %dl
5874; X64-NOBMI-NEXT:    movq $-1, %rax
5875; X64-NOBMI-NEXT:    movl %edx, %ecx
5876; X64-NOBMI-NEXT:    shrq %cl, %rax
5877; X64-NOBMI-NEXT:    andl %edi, %eax
5878; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
5879; X64-NOBMI-NEXT:    retq
5880;
5881; X64-BMI1NOTBM-LABEL: bextr64_32_c0:
5882; X64-BMI1NOTBM:       # %bb.0:
5883; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
5884; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
5885; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
5886; X64-BMI1NOTBM-NEXT:    negb %dl
5887; X64-BMI1NOTBM-NEXT:    movq $-1, %rax
5888; X64-BMI1NOTBM-NEXT:    movl %edx, %ecx
5889; X64-BMI1NOTBM-NEXT:    shrq %cl, %rax
5890; X64-BMI1NOTBM-NEXT:    andl %edi, %eax
5891; X64-BMI1NOTBM-NEXT:    # kill: def $eax killed $eax killed $rax
5892; X64-BMI1NOTBM-NEXT:    retq
5893;
5894; X64-BMI1BMI2-LABEL: bextr64_32_c0:
5895; X64-BMI1BMI2:       # %bb.0:
5896; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rcx
5897; X64-BMI1BMI2-NEXT:    negb %dl
5898; X64-BMI1BMI2-NEXT:    movq $-1, %rax
5899; X64-BMI1BMI2-NEXT:    shrxq %rdx, %rax, %rax
5900; X64-BMI1BMI2-NEXT:    andl %ecx, %eax
5901; X64-BMI1BMI2-NEXT:    # kill: def $eax killed $eax killed $rax
5902; X64-BMI1BMI2-NEXT:    retq
5903  %shifted = lshr i64 %val, %numskipbits
5904  %numhighbits = sub i64 64, %numlowbits
5905  %mask = lshr i64 -1, %numhighbits
5906  %masked = and i64 %mask, %shifted
5907  %res = trunc i64 %masked to i32
5908  ret i32 %res
5909}
5910
5911; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
5912define i32 @bextr64_32_c1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
5913; X86-NOBMI-LABEL: bextr64_32_c1:
5914; X86-NOBMI:       # %bb.0:
5915; X86-NOBMI-NEXT:    pushl %esi
5916; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
5917; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
5918; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5919; X86-NOBMI-NEXT:    movl %esi, %eax
5920; X86-NOBMI-NEXT:    shrl %cl, %eax
5921; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
5922; X86-NOBMI-NEXT:    testb $32, %cl
5923; X86-NOBMI-NEXT:    jne .LBB45_2
5924; X86-NOBMI-NEXT:  # %bb.1:
5925; X86-NOBMI-NEXT:    movl %edx, %eax
5926; X86-NOBMI-NEXT:  .LBB45_2:
5927; X86-NOBMI-NEXT:    xorl %ecx, %ecx
5928; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5929; X86-NOBMI-NEXT:    shll %cl, %eax
5930; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5931; X86-NOBMI-NEXT:    shrl %cl, %eax
5932; X86-NOBMI-NEXT:    popl %esi
5933; X86-NOBMI-NEXT:    retl
5934;
5935; X86-BMI1NOTBM-LABEL: bextr64_32_c1:
5936; X86-BMI1NOTBM:       # %bb.0:
5937; X86-BMI1NOTBM-NEXT:    pushl %edi
5938; X86-BMI1NOTBM-NEXT:    pushl %esi
5939; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
5940; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
5941; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
5942; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
5943; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
5944; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
5945; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
5946; X86-BMI1NOTBM-NEXT:    testb $32, %cl
5947; X86-BMI1NOTBM-NEXT:    jne .LBB45_2
5948; X86-BMI1NOTBM-NEXT:  # %bb.1:
5949; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
5950; X86-BMI1NOTBM-NEXT:  .LBB45_2:
5951; X86-BMI1NOTBM-NEXT:    shll $8, %eax
5952; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
5953; X86-BMI1NOTBM-NEXT:    popl %esi
5954; X86-BMI1NOTBM-NEXT:    popl %edi
5955; X86-BMI1NOTBM-NEXT:    retl
5956;
5957; X86-BMI1BMI2-LABEL: bextr64_32_c1:
5958; X86-BMI1BMI2:       # %bb.0:
5959; X86-BMI1BMI2-NEXT:    pushl %esi
5960; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
5961; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
5962; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
5963; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5964; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
5965; X86-BMI1BMI2-NEXT:    testb $32, %cl
5966; X86-BMI1BMI2-NEXT:    je .LBB45_2
5967; X86-BMI1BMI2-NEXT:  # %bb.1:
5968; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
5969; X86-BMI1BMI2-NEXT:  .LBB45_2:
5970; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
5971; X86-BMI1BMI2-NEXT:    popl %esi
5972; X86-BMI1BMI2-NEXT:    retl
5973;
5974; X64-NOBMI-LABEL: bextr64_32_c1:
5975; X64-NOBMI:       # %bb.0:
5976; X64-NOBMI-NEXT:    movq %rsi, %rcx
5977; X64-NOBMI-NEXT:    movq %rdi, %rax
5978; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5979; X64-NOBMI-NEXT:    shrq %cl, %rax
5980; X64-NOBMI-NEXT:    negb %dl
5981; X64-NOBMI-NEXT:    movl %edx, %ecx
5982; X64-NOBMI-NEXT:    shll %cl, %eax
5983; X64-NOBMI-NEXT:    shrl %cl, %eax
5984; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
5985; X64-NOBMI-NEXT:    retq
5986;
5987; X64-BMI1NOTBM-LABEL: bextr64_32_c1:
5988; X64-BMI1NOTBM:       # %bb.0:
5989; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
5990; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
5991; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
5992; X64-BMI1NOTBM-NEXT:    shll $8, %edx
5993; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
5994; X64-BMI1NOTBM-NEXT:    retq
5995;
5996; X64-BMI1BMI2-LABEL: bextr64_32_c1:
5997; X64-BMI1BMI2:       # %bb.0:
5998; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
5999; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6000; X64-BMI1BMI2-NEXT:    retq
6001  %shifted = lshr i64 %val, %numskipbits
6002  %truncshifted = trunc i64 %shifted to i32
6003  %numhighbits = sub i32 32, %numlowbits
6004  %mask = lshr i32 -1, %numhighbits
6005  %masked = and i32 %mask, %truncshifted
6006  ret i32 %masked
6007}
6008
6009; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
6010; Masking is 64-bit. Then truncation.
6011define i32 @bextr64_32_c2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
6012; X86-NOBMI-LABEL: bextr64_32_c2:
6013; X86-NOBMI:       # %bb.0:
6014; X86-NOBMI-NEXT:    pushl %esi
6015; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6016; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6017; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6018; X86-NOBMI-NEXT:    movl %esi, %eax
6019; X86-NOBMI-NEXT:    shrl %cl, %eax
6020; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
6021; X86-NOBMI-NEXT:    testb $32, %cl
6022; X86-NOBMI-NEXT:    jne .LBB46_2
6023; X86-NOBMI-NEXT:  # %bb.1:
6024; X86-NOBMI-NEXT:    movl %edx, %eax
6025; X86-NOBMI-NEXT:  .LBB46_2:
6026; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6027; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6028; X86-NOBMI-NEXT:    shll %cl, %eax
6029; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6030; X86-NOBMI-NEXT:    shrl %cl, %eax
6031; X86-NOBMI-NEXT:    popl %esi
6032; X86-NOBMI-NEXT:    retl
6033;
6034; X86-BMI1NOTBM-LABEL: bextr64_32_c2:
6035; X86-BMI1NOTBM:       # %bb.0:
6036; X86-BMI1NOTBM-NEXT:    pushl %edi
6037; X86-BMI1NOTBM-NEXT:    pushl %esi
6038; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
6039; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6040; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
6041; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
6042; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
6043; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
6044; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
6045; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6046; X86-BMI1NOTBM-NEXT:    jne .LBB46_2
6047; X86-BMI1NOTBM-NEXT:  # %bb.1:
6048; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
6049; X86-BMI1NOTBM-NEXT:  .LBB46_2:
6050; X86-BMI1NOTBM-NEXT:    shll $8, %eax
6051; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
6052; X86-BMI1NOTBM-NEXT:    popl %esi
6053; X86-BMI1NOTBM-NEXT:    popl %edi
6054; X86-BMI1NOTBM-NEXT:    retl
6055;
6056; X86-BMI1BMI2-LABEL: bextr64_32_c2:
6057; X86-BMI1BMI2:       # %bb.0:
6058; X86-BMI1BMI2-NEXT:    pushl %esi
6059; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6060; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6061; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6062; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
6063; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
6064; X86-BMI1BMI2-NEXT:    testb $32, %cl
6065; X86-BMI1BMI2-NEXT:    je .LBB46_2
6066; X86-BMI1BMI2-NEXT:  # %bb.1:
6067; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
6068; X86-BMI1BMI2-NEXT:  .LBB46_2:
6069; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
6070; X86-BMI1BMI2-NEXT:    popl %esi
6071; X86-BMI1BMI2-NEXT:    retl
6072;
6073; X64-NOBMI-LABEL: bextr64_32_c2:
6074; X64-NOBMI:       # %bb.0:
6075; X64-NOBMI-NEXT:    movq %rsi, %rcx
6076; X64-NOBMI-NEXT:    movq %rdi, %rax
6077; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6078; X64-NOBMI-NEXT:    shrq %cl, %rax
6079; X64-NOBMI-NEXT:    negb %dl
6080; X64-NOBMI-NEXT:    movl %edx, %ecx
6081; X64-NOBMI-NEXT:    shll %cl, %eax
6082; X64-NOBMI-NEXT:    shrl %cl, %eax
6083; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
6084; X64-NOBMI-NEXT:    retq
6085;
6086; X64-BMI1NOTBM-LABEL: bextr64_32_c2:
6087; X64-BMI1NOTBM:       # %bb.0:
6088; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
6089; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
6090; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
6091; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6092; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
6093; X64-BMI1NOTBM-NEXT:    retq
6094;
6095; X64-BMI1BMI2-LABEL: bextr64_32_c2:
6096; X64-BMI1BMI2:       # %bb.0:
6097; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6098; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6099; X64-BMI1BMI2-NEXT:    retq
6100  %shifted = lshr i64 %val, %numskipbits
6101  %numhighbits = sub i32 32, %numlowbits
6102  %mask = lshr i32 -1, %numhighbits
6103  %zextmask = zext i32 %mask to i64
6104  %masked = and i64 %zextmask, %shifted
6105  %truncmasked = trunc i64 %masked to i32
6106  ret i32 %truncmasked
6107}
6108
6109; ---------------------------------------------------------------------------- ;
6110; Pattern d. 32-bit.
6111; ---------------------------------------------------------------------------- ;
6112
6113define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
6114; X86-NOBMI-LABEL: bextr32_d0:
6115; X86-NOBMI:       # %bb.0:
6116; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6117; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6118; X86-NOBMI-NEXT:    shrl %cl, %eax
6119; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6120; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6121; X86-NOBMI-NEXT:    shll %cl, %eax
6122; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6123; X86-NOBMI-NEXT:    shrl %cl, %eax
6124; X86-NOBMI-NEXT:    retl
6125;
6126; X86-BMI1NOTBM-LABEL: bextr32_d0:
6127; X86-BMI1NOTBM:       # %bb.0:
6128; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
6129; X86-BMI1NOTBM-NEXT:    shll $8, %eax
6130; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6131; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
6132; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
6133; X86-BMI1NOTBM-NEXT:    retl
6134;
6135; X86-BMI1BMI2-LABEL: bextr32_d0:
6136; X86-BMI1BMI2:       # %bb.0:
6137; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6138; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6139; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
6140; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
6141; X86-BMI1BMI2-NEXT:    retl
6142;
6143; X64-NOBMI-LABEL: bextr32_d0:
6144; X64-NOBMI:       # %bb.0:
6145; X64-NOBMI-NEXT:    movl %esi, %ecx
6146; X64-NOBMI-NEXT:    movl %edi, %eax
6147; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6148; X64-NOBMI-NEXT:    shrl %cl, %eax
6149; X64-NOBMI-NEXT:    negb %dl
6150; X64-NOBMI-NEXT:    movl %edx, %ecx
6151; X64-NOBMI-NEXT:    shll %cl, %eax
6152; X64-NOBMI-NEXT:    shrl %cl, %eax
6153; X64-NOBMI-NEXT:    retq
6154;
6155; X64-BMI1NOTBM-LABEL: bextr32_d0:
6156; X64-BMI1NOTBM:       # %bb.0:
6157; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6158; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6159; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
6160; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
6161; X64-BMI1NOTBM-NEXT:    retq
6162;
6163; X64-BMI1BMI2-LABEL: bextr32_d0:
6164; X64-BMI1BMI2:       # %bb.0:
6165; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
6166; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6167; X64-BMI1BMI2-NEXT:    retq
6168  %shifted = lshr i32 %val, %numskipbits
6169  %numhighbits = sub i32 32, %numlowbits
6170  %highbitscleared = shl i32 %shifted, %numhighbits
6171  %masked = lshr i32 %highbitscleared, %numhighbits
6172  ret i32 %masked
6173}
6174
6175define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
6176; X86-NOBMI-LABEL: bextr32_d1_indexzext:
6177; X86-NOBMI:       # %bb.0:
6178; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6179; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6180; X86-NOBMI-NEXT:    shrl %cl, %eax
6181; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6182; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6183; X86-NOBMI-NEXT:    shll %cl, %eax
6184; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6185; X86-NOBMI-NEXT:    shrl %cl, %eax
6186; X86-NOBMI-NEXT:    retl
6187;
6188; X86-BMI1NOTBM-LABEL: bextr32_d1_indexzext:
6189; X86-BMI1NOTBM:       # %bb.0:
6190; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
6191; X86-BMI1NOTBM-NEXT:    shll $8, %eax
6192; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6193; X86-BMI1NOTBM-NEXT:    orl %eax, %ecx
6194; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
6195; X86-BMI1NOTBM-NEXT:    retl
6196;
6197; X86-BMI1BMI2-LABEL: bextr32_d1_indexzext:
6198; X86-BMI1BMI2:       # %bb.0:
6199; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6200; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6201; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
6202; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
6203; X86-BMI1BMI2-NEXT:    retl
6204;
6205; X64-NOBMI-LABEL: bextr32_d1_indexzext:
6206; X64-NOBMI:       # %bb.0:
6207; X64-NOBMI-NEXT:    movl %esi, %ecx
6208; X64-NOBMI-NEXT:    movl %edi, %eax
6209; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6210; X64-NOBMI-NEXT:    shrl %cl, %eax
6211; X64-NOBMI-NEXT:    negb %dl
6212; X64-NOBMI-NEXT:    movl %edx, %ecx
6213; X64-NOBMI-NEXT:    shll %cl, %eax
6214; X64-NOBMI-NEXT:    shrl %cl, %eax
6215; X64-NOBMI-NEXT:    retq
6216;
6217; X64-BMI1NOTBM-LABEL: bextr32_d1_indexzext:
6218; X64-BMI1NOTBM:       # %bb.0:
6219; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6220; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6221; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
6222; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
6223; X64-BMI1NOTBM-NEXT:    retq
6224;
6225; X64-BMI1BMI2-LABEL: bextr32_d1_indexzext:
6226; X64-BMI1BMI2:       # %bb.0:
6227; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
6228; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6229; X64-BMI1BMI2-NEXT:    retq
6230  %skip = zext i8 %numskipbits to i32
6231  %shifted = lshr i32 %val, %skip
6232  %numhighbits = sub i8 32, %numlowbits
6233  %sh_prom = zext i8 %numhighbits to i32
6234  %highbitscleared = shl i32 %shifted, %sh_prom
6235  %masked = lshr i32 %highbitscleared, %sh_prom
6236  ret i32 %masked
6237}
6238
6239define i32 @bextr32_d2_load(i32* %w, i32 %numskipbits, i32 %numlowbits) nounwind {
6240; X86-NOBMI-LABEL: bextr32_d2_load:
6241; X86-NOBMI:       # %bb.0:
6242; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6243; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6244; X86-NOBMI-NEXT:    movl (%eax), %eax
6245; X86-NOBMI-NEXT:    shrl %cl, %eax
6246; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6247; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6248; X86-NOBMI-NEXT:    shll %cl, %eax
6249; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6250; X86-NOBMI-NEXT:    shrl %cl, %eax
6251; X86-NOBMI-NEXT:    retl
6252;
6253; X86-BMI1NOTBM-LABEL: bextr32_d2_load:
6254; X86-BMI1NOTBM:       # %bb.0:
6255; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6256; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6257; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
6258; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6259; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
6260; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
6261; X86-BMI1NOTBM-NEXT:    retl
6262;
6263; X86-BMI1BMI2-LABEL: bextr32_d2_load:
6264; X86-BMI1BMI2:       # %bb.0:
6265; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6266; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6267; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
6268; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
6269; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
6270; X86-BMI1BMI2-NEXT:    retl
6271;
6272; X64-NOBMI-LABEL: bextr32_d2_load:
6273; X64-NOBMI:       # %bb.0:
6274; X64-NOBMI-NEXT:    movl %esi, %ecx
6275; X64-NOBMI-NEXT:    movl (%rdi), %eax
6276; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6277; X64-NOBMI-NEXT:    shrl %cl, %eax
6278; X64-NOBMI-NEXT:    negb %dl
6279; X64-NOBMI-NEXT:    movl %edx, %ecx
6280; X64-NOBMI-NEXT:    shll %cl, %eax
6281; X64-NOBMI-NEXT:    shrl %cl, %eax
6282; X64-NOBMI-NEXT:    retq
6283;
6284; X64-BMI1NOTBM-LABEL: bextr32_d2_load:
6285; X64-BMI1NOTBM:       # %bb.0:
6286; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6287; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6288; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
6289; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
6290; X64-BMI1NOTBM-NEXT:    retq
6291;
6292; X64-BMI1BMI2-LABEL: bextr32_d2_load:
6293; X64-BMI1BMI2:       # %bb.0:
6294; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
6295; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6296; X64-BMI1BMI2-NEXT:    retq
6297  %val = load i32, i32* %w
6298  %shifted = lshr i32 %val, %numskipbits
6299  %numhighbits = sub i32 32, %numlowbits
6300  %highbitscleared = shl i32 %shifted, %numhighbits
6301  %masked = lshr i32 %highbitscleared, %numhighbits
6302  ret i32 %masked
6303}
6304
6305define i32 @bextr32_d3_load_indexzext(i32* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
6306; X86-NOBMI-LABEL: bextr32_d3_load_indexzext:
6307; X86-NOBMI:       # %bb.0:
6308; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6309; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6310; X86-NOBMI-NEXT:    movl (%eax), %eax
6311; X86-NOBMI-NEXT:    shrl %cl, %eax
6312; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6313; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6314; X86-NOBMI-NEXT:    shll %cl, %eax
6315; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6316; X86-NOBMI-NEXT:    shrl %cl, %eax
6317; X86-NOBMI-NEXT:    retl
6318;
6319; X86-BMI1NOTBM-LABEL: bextr32_d3_load_indexzext:
6320; X86-BMI1NOTBM:       # %bb.0:
6321; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6322; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6323; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
6324; X86-BMI1NOTBM-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6325; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
6326; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%eax), %eax
6327; X86-BMI1NOTBM-NEXT:    retl
6328;
6329; X86-BMI1BMI2-LABEL: bextr32_d3_load_indexzext:
6330; X86-BMI1BMI2:       # %bb.0:
6331; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6332; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6333; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %dl
6334; X86-BMI1BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
6335; X86-BMI1BMI2-NEXT:    bzhil %eax, %ecx, %eax
6336; X86-BMI1BMI2-NEXT:    retl
6337;
6338; X64-NOBMI-LABEL: bextr32_d3_load_indexzext:
6339; X64-NOBMI:       # %bb.0:
6340; X64-NOBMI-NEXT:    movl %esi, %ecx
6341; X64-NOBMI-NEXT:    movl (%rdi), %eax
6342; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6343; X64-NOBMI-NEXT:    shrl %cl, %eax
6344; X64-NOBMI-NEXT:    negb %dl
6345; X64-NOBMI-NEXT:    movl %edx, %ecx
6346; X64-NOBMI-NEXT:    shll %cl, %eax
6347; X64-NOBMI-NEXT:    shrl %cl, %eax
6348; X64-NOBMI-NEXT:    retq
6349;
6350; X64-BMI1NOTBM-LABEL: bextr32_d3_load_indexzext:
6351; X64-BMI1NOTBM:       # %bb.0:
6352; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6353; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6354; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
6355; X64-BMI1NOTBM-NEXT:    bextrl %eax, (%rdi), %eax
6356; X64-BMI1NOTBM-NEXT:    retq
6357;
6358; X64-BMI1BMI2-LABEL: bextr32_d3_load_indexzext:
6359; X64-BMI1BMI2:       # %bb.0:
6360; X64-BMI1BMI2-NEXT:    shrxl %esi, (%rdi), %eax
6361; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
6362; X64-BMI1BMI2-NEXT:    retq
6363  %val = load i32, i32* %w
6364  %skip = zext i8 %numskipbits to i32
6365  %shifted = lshr i32 %val, %skip
6366  %numhighbits = sub i8 32, %numlowbits
6367  %sh_prom = zext i8 %numhighbits to i32
6368  %highbitscleared = shl i32 %shifted, %sh_prom
6369  %masked = lshr i32 %highbitscleared, %sh_prom
6370  ret i32 %masked
6371}
6372
6373define i32 @bextr32_d5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
6374; X86-NOBMI-LABEL: bextr32_d5_skipextrauses:
6375; X86-NOBMI:       # %bb.0:
6376; X86-NOBMI-NEXT:    pushl %esi
6377; X86-NOBMI-NEXT:    subl $8, %esp
6378; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6379; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6380; X86-NOBMI-NEXT:    movl %eax, %ecx
6381; X86-NOBMI-NEXT:    shrl %cl, %esi
6382; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6383; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6384; X86-NOBMI-NEXT:    shll %cl, %esi
6385; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6386; X86-NOBMI-NEXT:    shrl %cl, %esi
6387; X86-NOBMI-NEXT:    movl %eax, (%esp)
6388; X86-NOBMI-NEXT:    calll use32
6389; X86-NOBMI-NEXT:    movl %esi, %eax
6390; X86-NOBMI-NEXT:    addl $8, %esp
6391; X86-NOBMI-NEXT:    popl %esi
6392; X86-NOBMI-NEXT:    retl
6393;
6394; X86-BMI1NOTBM-LABEL: bextr32_d5_skipextrauses:
6395; X86-BMI1NOTBM:       # %bb.0:
6396; X86-BMI1NOTBM-NEXT:    pushl %esi
6397; X86-BMI1NOTBM-NEXT:    subl $8, %esp
6398; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6399; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6400; X86-BMI1NOTBM-NEXT:    shll $8, %ecx
6401; X86-BMI1NOTBM-NEXT:    movzbl %al, %edx
6402; X86-BMI1NOTBM-NEXT:    orl %ecx, %edx
6403; X86-BMI1NOTBM-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
6404; X86-BMI1NOTBM-NEXT:    movl %eax, (%esp)
6405; X86-BMI1NOTBM-NEXT:    calll use32
6406; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6407; X86-BMI1NOTBM-NEXT:    addl $8, %esp
6408; X86-BMI1NOTBM-NEXT:    popl %esi
6409; X86-BMI1NOTBM-NEXT:    retl
6410;
6411; X86-BMI1BMI2-LABEL: bextr32_d5_skipextrauses:
6412; X86-BMI1BMI2:       # %bb.0:
6413; X86-BMI1BMI2-NEXT:    pushl %esi
6414; X86-BMI1BMI2-NEXT:    subl $8, %esp
6415; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
6416; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6417; X86-BMI1BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
6418; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %esi
6419; X86-BMI1BMI2-NEXT:    movl %ecx, (%esp)
6420; X86-BMI1BMI2-NEXT:    calll use32
6421; X86-BMI1BMI2-NEXT:    movl %esi, %eax
6422; X86-BMI1BMI2-NEXT:    addl $8, %esp
6423; X86-BMI1BMI2-NEXT:    popl %esi
6424; X86-BMI1BMI2-NEXT:    retl
6425;
6426; X64-NOBMI-LABEL: bextr32_d5_skipextrauses:
6427; X64-NOBMI:       # %bb.0:
6428; X64-NOBMI-NEXT:    pushq %rbx
6429; X64-NOBMI-NEXT:    movl %edi, %ebx
6430; X64-NOBMI-NEXT:    movl %esi, %ecx
6431; X64-NOBMI-NEXT:    shrl %cl, %ebx
6432; X64-NOBMI-NEXT:    negb %dl
6433; X64-NOBMI-NEXT:    movl %edx, %ecx
6434; X64-NOBMI-NEXT:    shll %cl, %ebx
6435; X64-NOBMI-NEXT:    shrl %cl, %ebx
6436; X64-NOBMI-NEXT:    movl %esi, %edi
6437; X64-NOBMI-NEXT:    callq use32
6438; X64-NOBMI-NEXT:    movl %ebx, %eax
6439; X64-NOBMI-NEXT:    popq %rbx
6440; X64-NOBMI-NEXT:    retq
6441;
6442; X64-BMI1NOTBM-LABEL: bextr32_d5_skipextrauses:
6443; X64-BMI1NOTBM:       # %bb.0:
6444; X64-BMI1NOTBM-NEXT:    pushq %rbx
6445; X64-BMI1NOTBM-NEXT:    shll $8, %edx
6446; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6447; X64-BMI1NOTBM-NEXT:    orl %edx, %eax
6448; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %ebx
6449; X64-BMI1NOTBM-NEXT:    movl %esi, %edi
6450; X64-BMI1NOTBM-NEXT:    callq use32
6451; X64-BMI1NOTBM-NEXT:    movl %ebx, %eax
6452; X64-BMI1NOTBM-NEXT:    popq %rbx
6453; X64-BMI1NOTBM-NEXT:    retq
6454;
6455; X64-BMI1BMI2-LABEL: bextr32_d5_skipextrauses:
6456; X64-BMI1BMI2:       # %bb.0:
6457; X64-BMI1BMI2-NEXT:    pushq %rbx
6458; X64-BMI1BMI2-NEXT:    shrxl %esi, %edi, %eax
6459; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %ebx
6460; X64-BMI1BMI2-NEXT:    movl %esi, %edi
6461; X64-BMI1BMI2-NEXT:    callq use32
6462; X64-BMI1BMI2-NEXT:    movl %ebx, %eax
6463; X64-BMI1BMI2-NEXT:    popq %rbx
6464; X64-BMI1BMI2-NEXT:    retq
6465  %shifted = lshr i32 %val, %numskipbits
6466  %numhighbits = sub i32 32, %numlowbits
6467  %highbitscleared = shl i32 %shifted, %numhighbits
6468  %masked = lshr i32 %highbitscleared, %numhighbits
6469  call void @use32(i32 %numskipbits)
6470  ret i32 %masked
6471}
6472
6473; 64-bit.
6474
6475define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
6476; X86-NOBMI-LABEL: bextr64_d0:
6477; X86-NOBMI:       # %bb.0:
6478; X86-NOBMI-NEXT:    pushl %ebx
6479; X86-NOBMI-NEXT:    pushl %edi
6480; X86-NOBMI-NEXT:    pushl %esi
6481; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6482; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
6483; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6484; X86-NOBMI-NEXT:    movl %edx, %eax
6485; X86-NOBMI-NEXT:    shrl %cl, %eax
6486; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
6487; X86-NOBMI-NEXT:    xorl %esi, %esi
6488; X86-NOBMI-NEXT:    testb $32, %cl
6489; X86-NOBMI-NEXT:    je .LBB52_2
6490; X86-NOBMI-NEXT:  # %bb.1:
6491; X86-NOBMI-NEXT:    movl %eax, %edi
6492; X86-NOBMI-NEXT:    xorl %eax, %eax
6493; X86-NOBMI-NEXT:  .LBB52_2:
6494; X86-NOBMI-NEXT:    movb $64, %cl
6495; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6496; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
6497; X86-NOBMI-NEXT:    shll %cl, %edi
6498; X86-NOBMI-NEXT:    testb $32, %cl
6499; X86-NOBMI-NEXT:    movl %edi, %ebx
6500; X86-NOBMI-NEXT:    jne .LBB52_4
6501; X86-NOBMI-NEXT:  # %bb.3:
6502; X86-NOBMI-NEXT:    movl %eax, %ebx
6503; X86-NOBMI-NEXT:  .LBB52_4:
6504; X86-NOBMI-NEXT:    movl %ebx, %eax
6505; X86-NOBMI-NEXT:    shrl %cl, %eax
6506; X86-NOBMI-NEXT:    testb $32, %cl
6507; X86-NOBMI-NEXT:    movl $0, %edx
6508; X86-NOBMI-NEXT:    jne .LBB52_6
6509; X86-NOBMI-NEXT:  # %bb.5:
6510; X86-NOBMI-NEXT:    movl %edi, %esi
6511; X86-NOBMI-NEXT:    movl %eax, %edx
6512; X86-NOBMI-NEXT:  .LBB52_6:
6513; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
6514; X86-NOBMI-NEXT:    testb $32, %cl
6515; X86-NOBMI-NEXT:    jne .LBB52_8
6516; X86-NOBMI-NEXT:  # %bb.7:
6517; X86-NOBMI-NEXT:    movl %esi, %eax
6518; X86-NOBMI-NEXT:  .LBB52_8:
6519; X86-NOBMI-NEXT:    popl %esi
6520; X86-NOBMI-NEXT:    popl %edi
6521; X86-NOBMI-NEXT:    popl %ebx
6522; X86-NOBMI-NEXT:    retl
6523;
6524; X86-BMI1NOTBM-LABEL: bextr64_d0:
6525; X86-BMI1NOTBM:       # %bb.0:
6526; X86-BMI1NOTBM-NEXT:    pushl %ebx
6527; X86-BMI1NOTBM-NEXT:    pushl %edi
6528; X86-BMI1NOTBM-NEXT:    pushl %esi
6529; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6530; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
6531; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
6532; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
6533; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6534; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
6535; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
6536; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6537; X86-BMI1NOTBM-NEXT:    je .LBB52_2
6538; X86-BMI1NOTBM-NEXT:  # %bb.1:
6539; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
6540; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
6541; X86-BMI1NOTBM-NEXT:  .LBB52_2:
6542; X86-BMI1NOTBM-NEXT:    movb $64, %cl
6543; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
6544; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
6545; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
6546; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6547; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
6548; X86-BMI1NOTBM-NEXT:    jne .LBB52_4
6549; X86-BMI1NOTBM-NEXT:  # %bb.3:
6550; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
6551; X86-BMI1NOTBM-NEXT:  .LBB52_4:
6552; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
6553; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6554; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6555; X86-BMI1NOTBM-NEXT:    movl $0, %edx
6556; X86-BMI1NOTBM-NEXT:    jne .LBB52_6
6557; X86-BMI1NOTBM-NEXT:  # %bb.5:
6558; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
6559; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
6560; X86-BMI1NOTBM-NEXT:  .LBB52_6:
6561; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
6562; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6563; X86-BMI1NOTBM-NEXT:    jne .LBB52_8
6564; X86-BMI1NOTBM-NEXT:  # %bb.7:
6565; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6566; X86-BMI1NOTBM-NEXT:  .LBB52_8:
6567; X86-BMI1NOTBM-NEXT:    popl %esi
6568; X86-BMI1NOTBM-NEXT:    popl %edi
6569; X86-BMI1NOTBM-NEXT:    popl %ebx
6570; X86-BMI1NOTBM-NEXT:    retl
6571;
6572; X86-BMI1BMI2-LABEL: bextr64_d0:
6573; X86-BMI1BMI2:       # %bb.0:
6574; X86-BMI1BMI2-NEXT:    pushl %edi
6575; X86-BMI1BMI2-NEXT:    pushl %esi
6576; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6577; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6578; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6579; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
6580; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
6581; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
6582; X86-BMI1BMI2-NEXT:    testb $32, %cl
6583; X86-BMI1BMI2-NEXT:    je .LBB52_2
6584; X86-BMI1BMI2-NEXT:  # %bb.1:
6585; X86-BMI1BMI2-NEXT:    movl %esi, %eax
6586; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
6587; X86-BMI1BMI2-NEXT:  .LBB52_2:
6588; X86-BMI1BMI2-NEXT:    movb $64, %cl
6589; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6590; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
6591; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
6592; X86-BMI1BMI2-NEXT:    testb $32, %cl
6593; X86-BMI1BMI2-NEXT:    je .LBB52_4
6594; X86-BMI1BMI2-NEXT:  # %bb.3:
6595; X86-BMI1BMI2-NEXT:    movl %edi, %esi
6596; X86-BMI1BMI2-NEXT:    movl $0, %edi
6597; X86-BMI1BMI2-NEXT:  .LBB52_4:
6598; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
6599; X86-BMI1BMI2-NEXT:    jne .LBB52_6
6600; X86-BMI1BMI2-NEXT:  # %bb.5:
6601; X86-BMI1BMI2-NEXT:    movl %eax, %edx
6602; X86-BMI1BMI2-NEXT:  .LBB52_6:
6603; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
6604; X86-BMI1BMI2-NEXT:    testb $32, %cl
6605; X86-BMI1BMI2-NEXT:    jne .LBB52_8
6606; X86-BMI1BMI2-NEXT:  # %bb.7:
6607; X86-BMI1BMI2-NEXT:    movl %edi, %eax
6608; X86-BMI1BMI2-NEXT:  .LBB52_8:
6609; X86-BMI1BMI2-NEXT:    popl %esi
6610; X86-BMI1BMI2-NEXT:    popl %edi
6611; X86-BMI1BMI2-NEXT:    retl
6612;
6613; X64-NOBMI-LABEL: bextr64_d0:
6614; X64-NOBMI:       # %bb.0:
6615; X64-NOBMI-NEXT:    movq %rsi, %rcx
6616; X64-NOBMI-NEXT:    movq %rdi, %rax
6617; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6618; X64-NOBMI-NEXT:    shrq %cl, %rax
6619; X64-NOBMI-NEXT:    negb %dl
6620; X64-NOBMI-NEXT:    movl %edx, %ecx
6621; X64-NOBMI-NEXT:    shlq %cl, %rax
6622; X64-NOBMI-NEXT:    shrq %cl, %rax
6623; X64-NOBMI-NEXT:    retq
6624;
6625; X64-BMI1NOTBM-LABEL: bextr64_d0:
6626; X64-BMI1NOTBM:       # %bb.0:
6627; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
6628; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6629; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
6630; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
6631; X64-BMI1NOTBM-NEXT:    retq
6632;
6633; X64-BMI1BMI2-LABEL: bextr64_d0:
6634; X64-BMI1BMI2:       # %bb.0:
6635; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6636; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
6637; X64-BMI1BMI2-NEXT:    retq
6638  %shifted = lshr i64 %val, %numskipbits
6639  %numhighbits = sub i64 64, %numlowbits
6640  %highbitscleared = shl i64 %shifted, %numhighbits
6641  %masked = lshr i64 %highbitscleared, %numhighbits
6642  ret i64 %masked
6643}
6644
6645define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
6646; X86-NOBMI-LABEL: bextr64_d1_indexzext:
6647; X86-NOBMI:       # %bb.0:
6648; X86-NOBMI-NEXT:    pushl %ebx
6649; X86-NOBMI-NEXT:    pushl %edi
6650; X86-NOBMI-NEXT:    pushl %esi
6651; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6652; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
6653; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6654; X86-NOBMI-NEXT:    movl %edx, %eax
6655; X86-NOBMI-NEXT:    shrl %cl, %eax
6656; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
6657; X86-NOBMI-NEXT:    xorl %esi, %esi
6658; X86-NOBMI-NEXT:    testb $32, %cl
6659; X86-NOBMI-NEXT:    je .LBB53_2
6660; X86-NOBMI-NEXT:  # %bb.1:
6661; X86-NOBMI-NEXT:    movl %eax, %edi
6662; X86-NOBMI-NEXT:    xorl %eax, %eax
6663; X86-NOBMI-NEXT:  .LBB53_2:
6664; X86-NOBMI-NEXT:    movb $64, %cl
6665; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6666; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
6667; X86-NOBMI-NEXT:    shll %cl, %edi
6668; X86-NOBMI-NEXT:    testb $32, %cl
6669; X86-NOBMI-NEXT:    movl %edi, %ebx
6670; X86-NOBMI-NEXT:    jne .LBB53_4
6671; X86-NOBMI-NEXT:  # %bb.3:
6672; X86-NOBMI-NEXT:    movl %eax, %ebx
6673; X86-NOBMI-NEXT:  .LBB53_4:
6674; X86-NOBMI-NEXT:    movl %ebx, %eax
6675; X86-NOBMI-NEXT:    shrl %cl, %eax
6676; X86-NOBMI-NEXT:    testb $32, %cl
6677; X86-NOBMI-NEXT:    movl $0, %edx
6678; X86-NOBMI-NEXT:    jne .LBB53_6
6679; X86-NOBMI-NEXT:  # %bb.5:
6680; X86-NOBMI-NEXT:    movl %edi, %esi
6681; X86-NOBMI-NEXT:    movl %eax, %edx
6682; X86-NOBMI-NEXT:  .LBB53_6:
6683; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
6684; X86-NOBMI-NEXT:    testb $32, %cl
6685; X86-NOBMI-NEXT:    jne .LBB53_8
6686; X86-NOBMI-NEXT:  # %bb.7:
6687; X86-NOBMI-NEXT:    movl %esi, %eax
6688; X86-NOBMI-NEXT:  .LBB53_8:
6689; X86-NOBMI-NEXT:    popl %esi
6690; X86-NOBMI-NEXT:    popl %edi
6691; X86-NOBMI-NEXT:    popl %ebx
6692; X86-NOBMI-NEXT:    retl
6693;
6694; X86-BMI1NOTBM-LABEL: bextr64_d1_indexzext:
6695; X86-BMI1NOTBM:       # %bb.0:
6696; X86-BMI1NOTBM-NEXT:    pushl %ebx
6697; X86-BMI1NOTBM-NEXT:    pushl %edi
6698; X86-BMI1NOTBM-NEXT:    pushl %esi
6699; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6700; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
6701; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
6702; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
6703; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6704; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
6705; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
6706; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6707; X86-BMI1NOTBM-NEXT:    je .LBB53_2
6708; X86-BMI1NOTBM-NEXT:  # %bb.1:
6709; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
6710; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
6711; X86-BMI1NOTBM-NEXT:  .LBB53_2:
6712; X86-BMI1NOTBM-NEXT:    movb $64, %cl
6713; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
6714; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
6715; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
6716; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6717; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
6718; X86-BMI1NOTBM-NEXT:    jne .LBB53_4
6719; X86-BMI1NOTBM-NEXT:  # %bb.3:
6720; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
6721; X86-BMI1NOTBM-NEXT:  .LBB53_4:
6722; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
6723; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6724; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6725; X86-BMI1NOTBM-NEXT:    movl $0, %edx
6726; X86-BMI1NOTBM-NEXT:    jne .LBB53_6
6727; X86-BMI1NOTBM-NEXT:  # %bb.5:
6728; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
6729; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
6730; X86-BMI1NOTBM-NEXT:  .LBB53_6:
6731; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
6732; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6733; X86-BMI1NOTBM-NEXT:    jne .LBB53_8
6734; X86-BMI1NOTBM-NEXT:  # %bb.7:
6735; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6736; X86-BMI1NOTBM-NEXT:  .LBB53_8:
6737; X86-BMI1NOTBM-NEXT:    popl %esi
6738; X86-BMI1NOTBM-NEXT:    popl %edi
6739; X86-BMI1NOTBM-NEXT:    popl %ebx
6740; X86-BMI1NOTBM-NEXT:    retl
6741;
6742; X86-BMI1BMI2-LABEL: bextr64_d1_indexzext:
6743; X86-BMI1BMI2:       # %bb.0:
6744; X86-BMI1BMI2-NEXT:    pushl %edi
6745; X86-BMI1BMI2-NEXT:    pushl %esi
6746; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6747; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6748; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6749; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
6750; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
6751; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
6752; X86-BMI1BMI2-NEXT:    testb $32, %cl
6753; X86-BMI1BMI2-NEXT:    je .LBB53_2
6754; X86-BMI1BMI2-NEXT:  # %bb.1:
6755; X86-BMI1BMI2-NEXT:    movl %esi, %eax
6756; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
6757; X86-BMI1BMI2-NEXT:  .LBB53_2:
6758; X86-BMI1BMI2-NEXT:    movb $64, %cl
6759; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6760; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
6761; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
6762; X86-BMI1BMI2-NEXT:    testb $32, %cl
6763; X86-BMI1BMI2-NEXT:    je .LBB53_4
6764; X86-BMI1BMI2-NEXT:  # %bb.3:
6765; X86-BMI1BMI2-NEXT:    movl %edi, %esi
6766; X86-BMI1BMI2-NEXT:    movl $0, %edi
6767; X86-BMI1BMI2-NEXT:  .LBB53_4:
6768; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
6769; X86-BMI1BMI2-NEXT:    jne .LBB53_6
6770; X86-BMI1BMI2-NEXT:  # %bb.5:
6771; X86-BMI1BMI2-NEXT:    movl %eax, %edx
6772; X86-BMI1BMI2-NEXT:  .LBB53_6:
6773; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
6774; X86-BMI1BMI2-NEXT:    testb $32, %cl
6775; X86-BMI1BMI2-NEXT:    jne .LBB53_8
6776; X86-BMI1BMI2-NEXT:  # %bb.7:
6777; X86-BMI1BMI2-NEXT:    movl %edi, %eax
6778; X86-BMI1BMI2-NEXT:  .LBB53_8:
6779; X86-BMI1BMI2-NEXT:    popl %esi
6780; X86-BMI1BMI2-NEXT:    popl %edi
6781; X86-BMI1BMI2-NEXT:    retl
6782;
6783; X64-NOBMI-LABEL: bextr64_d1_indexzext:
6784; X64-NOBMI:       # %bb.0:
6785; X64-NOBMI-NEXT:    movl %esi, %ecx
6786; X64-NOBMI-NEXT:    movq %rdi, %rax
6787; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6788; X64-NOBMI-NEXT:    shrq %cl, %rax
6789; X64-NOBMI-NEXT:    negb %dl
6790; X64-NOBMI-NEXT:    movl %edx, %ecx
6791; X64-NOBMI-NEXT:    shlq %cl, %rax
6792; X64-NOBMI-NEXT:    shrq %cl, %rax
6793; X64-NOBMI-NEXT:    retq
6794;
6795; X64-BMI1NOTBM-LABEL: bextr64_d1_indexzext:
6796; X64-BMI1NOTBM:       # %bb.0:
6797; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
6798; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
6799; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6800; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
6801; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
6802; X64-BMI1NOTBM-NEXT:    retq
6803;
6804; X64-BMI1BMI2-LABEL: bextr64_d1_indexzext:
6805; X64-BMI1BMI2:       # %bb.0:
6806; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
6807; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
6808; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6809; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
6810; X64-BMI1BMI2-NEXT:    retq
6811  %skip = zext i8 %numskipbits to i64
6812  %shifted = lshr i64 %val, %skip
6813  %numhighbits = sub i8 64, %numlowbits
6814  %sh_prom = zext i8 %numhighbits to i64
6815  %highbitscleared = shl i64 %shifted, %sh_prom
6816  %masked = lshr i64 %highbitscleared, %sh_prom
6817  ret i64 %masked
6818}
6819
6820define i64 @bextr64_d2_load(i64* %w, i64 %numskipbits, i64 %numlowbits) nounwind {
6821; X86-NOBMI-LABEL: bextr64_d2_load:
6822; X86-NOBMI:       # %bb.0:
6823; X86-NOBMI-NEXT:    pushl %ebx
6824; X86-NOBMI-NEXT:    pushl %edi
6825; X86-NOBMI-NEXT:    pushl %esi
6826; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
6827; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6828; X86-NOBMI-NEXT:    movl (%eax), %edi
6829; X86-NOBMI-NEXT:    movl 4(%eax), %edx
6830; X86-NOBMI-NEXT:    movl %edx, %eax
6831; X86-NOBMI-NEXT:    shrl %cl, %eax
6832; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
6833; X86-NOBMI-NEXT:    xorl %esi, %esi
6834; X86-NOBMI-NEXT:    testb $32, %cl
6835; X86-NOBMI-NEXT:    je .LBB54_2
6836; X86-NOBMI-NEXT:  # %bb.1:
6837; X86-NOBMI-NEXT:    movl %eax, %edi
6838; X86-NOBMI-NEXT:    xorl %eax, %eax
6839; X86-NOBMI-NEXT:  .LBB54_2:
6840; X86-NOBMI-NEXT:    movb $64, %cl
6841; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6842; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
6843; X86-NOBMI-NEXT:    shll %cl, %edi
6844; X86-NOBMI-NEXT:    testb $32, %cl
6845; X86-NOBMI-NEXT:    movl %edi, %ebx
6846; X86-NOBMI-NEXT:    jne .LBB54_4
6847; X86-NOBMI-NEXT:  # %bb.3:
6848; X86-NOBMI-NEXT:    movl %eax, %ebx
6849; X86-NOBMI-NEXT:  .LBB54_4:
6850; X86-NOBMI-NEXT:    movl %ebx, %eax
6851; X86-NOBMI-NEXT:    shrl %cl, %eax
6852; X86-NOBMI-NEXT:    testb $32, %cl
6853; X86-NOBMI-NEXT:    movl $0, %edx
6854; X86-NOBMI-NEXT:    jne .LBB54_6
6855; X86-NOBMI-NEXT:  # %bb.5:
6856; X86-NOBMI-NEXT:    movl %edi, %esi
6857; X86-NOBMI-NEXT:    movl %eax, %edx
6858; X86-NOBMI-NEXT:  .LBB54_6:
6859; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
6860; X86-NOBMI-NEXT:    testb $32, %cl
6861; X86-NOBMI-NEXT:    jne .LBB54_8
6862; X86-NOBMI-NEXT:  # %bb.7:
6863; X86-NOBMI-NEXT:    movl %esi, %eax
6864; X86-NOBMI-NEXT:  .LBB54_8:
6865; X86-NOBMI-NEXT:    popl %esi
6866; X86-NOBMI-NEXT:    popl %edi
6867; X86-NOBMI-NEXT:    popl %ebx
6868; X86-NOBMI-NEXT:    retl
6869;
6870; X86-BMI1NOTBM-LABEL: bextr64_d2_load:
6871; X86-BMI1NOTBM:       # %bb.0:
6872; X86-BMI1NOTBM-NEXT:    pushl %ebx
6873; X86-BMI1NOTBM-NEXT:    pushl %edi
6874; X86-BMI1NOTBM-NEXT:    pushl %esi
6875; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
6876; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
6877; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
6878; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %edx
6879; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
6880; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6881; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
6882; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
6883; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6884; X86-BMI1NOTBM-NEXT:    je .LBB54_2
6885; X86-BMI1NOTBM-NEXT:  # %bb.1:
6886; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
6887; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
6888; X86-BMI1NOTBM-NEXT:  .LBB54_2:
6889; X86-BMI1NOTBM-NEXT:    movb $64, %cl
6890; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
6891; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
6892; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
6893; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6894; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
6895; X86-BMI1NOTBM-NEXT:    jne .LBB54_4
6896; X86-BMI1NOTBM-NEXT:  # %bb.3:
6897; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
6898; X86-BMI1NOTBM-NEXT:  .LBB54_4:
6899; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
6900; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
6901; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6902; X86-BMI1NOTBM-NEXT:    movl $0, %edx
6903; X86-BMI1NOTBM-NEXT:    jne .LBB54_6
6904; X86-BMI1NOTBM-NEXT:  # %bb.5:
6905; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
6906; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
6907; X86-BMI1NOTBM-NEXT:  .LBB54_6:
6908; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
6909; X86-BMI1NOTBM-NEXT:    testb $32, %cl
6910; X86-BMI1NOTBM-NEXT:    jne .LBB54_8
6911; X86-BMI1NOTBM-NEXT:  # %bb.7:
6912; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
6913; X86-BMI1NOTBM-NEXT:  .LBB54_8:
6914; X86-BMI1NOTBM-NEXT:    popl %esi
6915; X86-BMI1NOTBM-NEXT:    popl %edi
6916; X86-BMI1NOTBM-NEXT:    popl %ebx
6917; X86-BMI1NOTBM-NEXT:    retl
6918;
6919; X86-BMI1BMI2-LABEL: bextr64_d2_load:
6920; X86-BMI1BMI2:       # %bb.0:
6921; X86-BMI1BMI2-NEXT:    pushl %edi
6922; X86-BMI1BMI2-NEXT:    pushl %esi
6923; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
6924; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6925; X86-BMI1BMI2-NEXT:    movl (%edx), %eax
6926; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edx
6927; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
6928; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
6929; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
6930; X86-BMI1BMI2-NEXT:    testb $32, %cl
6931; X86-BMI1BMI2-NEXT:    je .LBB54_2
6932; X86-BMI1BMI2-NEXT:  # %bb.1:
6933; X86-BMI1BMI2-NEXT:    movl %esi, %eax
6934; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
6935; X86-BMI1BMI2-NEXT:  .LBB54_2:
6936; X86-BMI1BMI2-NEXT:    movb $64, %cl
6937; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6938; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
6939; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
6940; X86-BMI1BMI2-NEXT:    testb $32, %cl
6941; X86-BMI1BMI2-NEXT:    je .LBB54_4
6942; X86-BMI1BMI2-NEXT:  # %bb.3:
6943; X86-BMI1BMI2-NEXT:    movl %edi, %esi
6944; X86-BMI1BMI2-NEXT:    movl $0, %edi
6945; X86-BMI1BMI2-NEXT:  .LBB54_4:
6946; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
6947; X86-BMI1BMI2-NEXT:    jne .LBB54_6
6948; X86-BMI1BMI2-NEXT:  # %bb.5:
6949; X86-BMI1BMI2-NEXT:    movl %eax, %edx
6950; X86-BMI1BMI2-NEXT:  .LBB54_6:
6951; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
6952; X86-BMI1BMI2-NEXT:    testb $32, %cl
6953; X86-BMI1BMI2-NEXT:    jne .LBB54_8
6954; X86-BMI1BMI2-NEXT:  # %bb.7:
6955; X86-BMI1BMI2-NEXT:    movl %edi, %eax
6956; X86-BMI1BMI2-NEXT:  .LBB54_8:
6957; X86-BMI1BMI2-NEXT:    popl %esi
6958; X86-BMI1BMI2-NEXT:    popl %edi
6959; X86-BMI1BMI2-NEXT:    retl
6960;
6961; X64-NOBMI-LABEL: bextr64_d2_load:
6962; X64-NOBMI:       # %bb.0:
6963; X64-NOBMI-NEXT:    movq %rsi, %rcx
6964; X64-NOBMI-NEXT:    movq (%rdi), %rax
6965; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6966; X64-NOBMI-NEXT:    shrq %cl, %rax
6967; X64-NOBMI-NEXT:    negb %dl
6968; X64-NOBMI-NEXT:    movl %edx, %ecx
6969; X64-NOBMI-NEXT:    shlq %cl, %rax
6970; X64-NOBMI-NEXT:    shrq %cl, %rax
6971; X64-NOBMI-NEXT:    retq
6972;
6973; X64-BMI1NOTBM-LABEL: bextr64_d2_load:
6974; X64-BMI1NOTBM:       # %bb.0:
6975; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
6976; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
6977; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
6978; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
6979; X64-BMI1NOTBM-NEXT:    retq
6980;
6981; X64-BMI1BMI2-LABEL: bextr64_d2_load:
6982; X64-BMI1BMI2:       # %bb.0:
6983; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
6984; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
6985; X64-BMI1BMI2-NEXT:    retq
6986  %val = load i64, i64* %w
6987  %shifted = lshr i64 %val, %numskipbits
6988  %numhighbits = sub i64 64, %numlowbits
6989  %highbitscleared = shl i64 %shifted, %numhighbits
6990  %masked = lshr i64 %highbitscleared, %numhighbits
6991  ret i64 %masked
6992}
6993
6994define i64 @bextr64_d3_load_indexzext(i64* %w, i8 %numskipbits, i8 %numlowbits) nounwind {
6995; X86-NOBMI-LABEL: bextr64_d3_load_indexzext:
6996; X86-NOBMI:       # %bb.0:
6997; X86-NOBMI-NEXT:    pushl %ebx
6998; X86-NOBMI-NEXT:    pushl %edi
6999; X86-NOBMI-NEXT:    pushl %esi
7000; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
7001; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7002; X86-NOBMI-NEXT:    movl (%eax), %edi
7003; X86-NOBMI-NEXT:    movl 4(%eax), %edx
7004; X86-NOBMI-NEXT:    movl %edx, %eax
7005; X86-NOBMI-NEXT:    shrl %cl, %eax
7006; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
7007; X86-NOBMI-NEXT:    xorl %esi, %esi
7008; X86-NOBMI-NEXT:    testb $32, %cl
7009; X86-NOBMI-NEXT:    je .LBB55_2
7010; X86-NOBMI-NEXT:  # %bb.1:
7011; X86-NOBMI-NEXT:    movl %eax, %edi
7012; X86-NOBMI-NEXT:    xorl %eax, %eax
7013; X86-NOBMI-NEXT:  .LBB55_2:
7014; X86-NOBMI-NEXT:    movb $64, %cl
7015; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7016; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
7017; X86-NOBMI-NEXT:    shll %cl, %edi
7018; X86-NOBMI-NEXT:    testb $32, %cl
7019; X86-NOBMI-NEXT:    movl %edi, %ebx
7020; X86-NOBMI-NEXT:    jne .LBB55_4
7021; X86-NOBMI-NEXT:  # %bb.3:
7022; X86-NOBMI-NEXT:    movl %eax, %ebx
7023; X86-NOBMI-NEXT:  .LBB55_4:
7024; X86-NOBMI-NEXT:    movl %ebx, %eax
7025; X86-NOBMI-NEXT:    shrl %cl, %eax
7026; X86-NOBMI-NEXT:    testb $32, %cl
7027; X86-NOBMI-NEXT:    movl $0, %edx
7028; X86-NOBMI-NEXT:    jne .LBB55_6
7029; X86-NOBMI-NEXT:  # %bb.5:
7030; X86-NOBMI-NEXT:    movl %edi, %esi
7031; X86-NOBMI-NEXT:    movl %eax, %edx
7032; X86-NOBMI-NEXT:  .LBB55_6:
7033; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
7034; X86-NOBMI-NEXT:    testb $32, %cl
7035; X86-NOBMI-NEXT:    jne .LBB55_8
7036; X86-NOBMI-NEXT:  # %bb.7:
7037; X86-NOBMI-NEXT:    movl %esi, %eax
7038; X86-NOBMI-NEXT:  .LBB55_8:
7039; X86-NOBMI-NEXT:    popl %esi
7040; X86-NOBMI-NEXT:    popl %edi
7041; X86-NOBMI-NEXT:    popl %ebx
7042; X86-NOBMI-NEXT:    retl
7043;
7044; X86-BMI1NOTBM-LABEL: bextr64_d3_load_indexzext:
7045; X86-BMI1NOTBM:       # %bb.0:
7046; X86-BMI1NOTBM-NEXT:    pushl %ebx
7047; X86-BMI1NOTBM-NEXT:    pushl %edi
7048; X86-BMI1NOTBM-NEXT:    pushl %esi
7049; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
7050; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7051; X86-BMI1NOTBM-NEXT:    movl (%eax), %edi
7052; X86-BMI1NOTBM-NEXT:    movl 4(%eax), %edx
7053; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
7054; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
7055; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %edi
7056; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
7057; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7058; X86-BMI1NOTBM-NEXT:    je .LBB55_2
7059; X86-BMI1NOTBM-NEXT:  # %bb.1:
7060; X86-BMI1NOTBM-NEXT:    movl %eax, %edi
7061; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
7062; X86-BMI1NOTBM-NEXT:  .LBB55_2:
7063; X86-BMI1NOTBM-NEXT:    movb $64, %cl
7064; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
7065; X86-BMI1NOTBM-NEXT:    shldl %cl, %edi, %eax
7066; X86-BMI1NOTBM-NEXT:    shll %cl, %edi
7067; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7068; X86-BMI1NOTBM-NEXT:    movl %edi, %ebx
7069; X86-BMI1NOTBM-NEXT:    jne .LBB55_4
7070; X86-BMI1NOTBM-NEXT:  # %bb.3:
7071; X86-BMI1NOTBM-NEXT:    movl %eax, %ebx
7072; X86-BMI1NOTBM-NEXT:  .LBB55_4:
7073; X86-BMI1NOTBM-NEXT:    movl %ebx, %eax
7074; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
7075; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7076; X86-BMI1NOTBM-NEXT:    movl $0, %edx
7077; X86-BMI1NOTBM-NEXT:    jne .LBB55_6
7078; X86-BMI1NOTBM-NEXT:  # %bb.5:
7079; X86-BMI1NOTBM-NEXT:    movl %edi, %esi
7080; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
7081; X86-BMI1NOTBM-NEXT:  .LBB55_6:
7082; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebx, %esi
7083; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7084; X86-BMI1NOTBM-NEXT:    jne .LBB55_8
7085; X86-BMI1NOTBM-NEXT:  # %bb.7:
7086; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
7087; X86-BMI1NOTBM-NEXT:  .LBB55_8:
7088; X86-BMI1NOTBM-NEXT:    popl %esi
7089; X86-BMI1NOTBM-NEXT:    popl %edi
7090; X86-BMI1NOTBM-NEXT:    popl %ebx
7091; X86-BMI1NOTBM-NEXT:    retl
7092;
7093; X86-BMI1BMI2-LABEL: bextr64_d3_load_indexzext:
7094; X86-BMI1BMI2:       # %bb.0:
7095; X86-BMI1BMI2-NEXT:    pushl %edi
7096; X86-BMI1BMI2-NEXT:    pushl %esi
7097; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
7098; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7099; X86-BMI1BMI2-NEXT:    movl (%edx), %eax
7100; X86-BMI1BMI2-NEXT:    movl 4(%edx), %edx
7101; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %esi
7102; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
7103; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
7104; X86-BMI1BMI2-NEXT:    testb $32, %cl
7105; X86-BMI1BMI2-NEXT:    je .LBB55_2
7106; X86-BMI1BMI2-NEXT:  # %bb.1:
7107; X86-BMI1BMI2-NEXT:    movl %esi, %eax
7108; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
7109; X86-BMI1BMI2-NEXT:  .LBB55_2:
7110; X86-BMI1BMI2-NEXT:    movb $64, %cl
7111; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7112; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %esi
7113; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %edi
7114; X86-BMI1BMI2-NEXT:    testb $32, %cl
7115; X86-BMI1BMI2-NEXT:    je .LBB55_4
7116; X86-BMI1BMI2-NEXT:  # %bb.3:
7117; X86-BMI1BMI2-NEXT:    movl %edi, %esi
7118; X86-BMI1BMI2-NEXT:    movl $0, %edi
7119; X86-BMI1BMI2-NEXT:  .LBB55_4:
7120; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %eax
7121; X86-BMI1BMI2-NEXT:    jne .LBB55_6
7122; X86-BMI1BMI2-NEXT:  # %bb.5:
7123; X86-BMI1BMI2-NEXT:    movl %eax, %edx
7124; X86-BMI1BMI2-NEXT:  .LBB55_6:
7125; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edi
7126; X86-BMI1BMI2-NEXT:    testb $32, %cl
7127; X86-BMI1BMI2-NEXT:    jne .LBB55_8
7128; X86-BMI1BMI2-NEXT:  # %bb.7:
7129; X86-BMI1BMI2-NEXT:    movl %edi, %eax
7130; X86-BMI1BMI2-NEXT:  .LBB55_8:
7131; X86-BMI1BMI2-NEXT:    popl %esi
7132; X86-BMI1BMI2-NEXT:    popl %edi
7133; X86-BMI1BMI2-NEXT:    retl
7134;
7135; X64-NOBMI-LABEL: bextr64_d3_load_indexzext:
7136; X64-NOBMI:       # %bb.0:
7137; X64-NOBMI-NEXT:    movl %esi, %ecx
7138; X64-NOBMI-NEXT:    movq (%rdi), %rax
7139; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
7140; X64-NOBMI-NEXT:    shrq %cl, %rax
7141; X64-NOBMI-NEXT:    negb %dl
7142; X64-NOBMI-NEXT:    movl %edx, %ecx
7143; X64-NOBMI-NEXT:    shlq %cl, %rax
7144; X64-NOBMI-NEXT:    shrq %cl, %rax
7145; X64-NOBMI-NEXT:    retq
7146;
7147; X64-BMI1NOTBM-LABEL: bextr64_d3_load_indexzext:
7148; X64-BMI1NOTBM:       # %bb.0:
7149; X64-BMI1NOTBM-NEXT:    # kill: def $edx killed $edx def $rdx
7150; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
7151; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
7152; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
7153; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rdi), %rax
7154; X64-BMI1NOTBM-NEXT:    retq
7155;
7156; X64-BMI1BMI2-LABEL: bextr64_d3_load_indexzext:
7157; X64-BMI1BMI2:       # %bb.0:
7158; X64-BMI1BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
7159; X64-BMI1BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
7160; X64-BMI1BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
7161; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7162; X64-BMI1BMI2-NEXT:    retq
7163  %val = load i64, i64* %w
7164  %skip = zext i8 %numskipbits to i64
7165  %shifted = lshr i64 %val, %skip
7166  %numhighbits = sub i8 64, %numlowbits
7167  %sh_prom = zext i8 %numhighbits to i64
7168  %highbitscleared = shl i64 %shifted, %sh_prom
7169  %masked = lshr i64 %highbitscleared, %sh_prom
7170  ret i64 %masked
7171}
7172
7173define i64 @bextr64_d5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
7174; X86-NOBMI-LABEL: bextr64_d5_skipextrauses:
7175; X86-NOBMI:       # %bb.0:
7176; X86-NOBMI-NEXT:    pushl %ebp
7177; X86-NOBMI-NEXT:    pushl %ebx
7178; X86-NOBMI-NEXT:    pushl %edi
7179; X86-NOBMI-NEXT:    pushl %esi
7180; X86-NOBMI-NEXT:    subl $12, %esp
7181; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
7182; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7183; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7184; X86-NOBMI-NEXT:    movl %edx, %esi
7185; X86-NOBMI-NEXT:    movl %eax, %ecx
7186; X86-NOBMI-NEXT:    shrl %cl, %esi
7187; X86-NOBMI-NEXT:    shrdl %cl, %edx, %ebx
7188; X86-NOBMI-NEXT:    xorl %edx, %edx
7189; X86-NOBMI-NEXT:    testb $32, %al
7190; X86-NOBMI-NEXT:    je .LBB56_2
7191; X86-NOBMI-NEXT:  # %bb.1:
7192; X86-NOBMI-NEXT:    movl %esi, %ebx
7193; X86-NOBMI-NEXT:    xorl %esi, %esi
7194; X86-NOBMI-NEXT:  .LBB56_2:
7195; X86-NOBMI-NEXT:    movb $64, %cl
7196; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7197; X86-NOBMI-NEXT:    shldl %cl, %ebx, %esi
7198; X86-NOBMI-NEXT:    shll %cl, %ebx
7199; X86-NOBMI-NEXT:    testb $32, %cl
7200; X86-NOBMI-NEXT:    movl %ebx, %ebp
7201; X86-NOBMI-NEXT:    jne .LBB56_4
7202; X86-NOBMI-NEXT:  # %bb.3:
7203; X86-NOBMI-NEXT:    movl %esi, %ebp
7204; X86-NOBMI-NEXT:  .LBB56_4:
7205; X86-NOBMI-NEXT:    movl %ebp, %esi
7206; X86-NOBMI-NEXT:    shrl %cl, %esi
7207; X86-NOBMI-NEXT:    testb $32, %cl
7208; X86-NOBMI-NEXT:    movl $0, %edi
7209; X86-NOBMI-NEXT:    jne .LBB56_6
7210; X86-NOBMI-NEXT:  # %bb.5:
7211; X86-NOBMI-NEXT:    movl %ebx, %edx
7212; X86-NOBMI-NEXT:    movl %esi, %edi
7213; X86-NOBMI-NEXT:  .LBB56_6:
7214; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %edx
7215; X86-NOBMI-NEXT:    testb $32, %cl
7216; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7217; X86-NOBMI-NEXT:    jne .LBB56_8
7218; X86-NOBMI-NEXT:  # %bb.7:
7219; X86-NOBMI-NEXT:    movl %edx, %esi
7220; X86-NOBMI-NEXT:  .LBB56_8:
7221; X86-NOBMI-NEXT:    subl $8, %esp
7222; X86-NOBMI-NEXT:    pushl %ecx
7223; X86-NOBMI-NEXT:    pushl %eax
7224; X86-NOBMI-NEXT:    calll use64
7225; X86-NOBMI-NEXT:    addl $16, %esp
7226; X86-NOBMI-NEXT:    movl %esi, %eax
7227; X86-NOBMI-NEXT:    movl %edi, %edx
7228; X86-NOBMI-NEXT:    addl $12, %esp
7229; X86-NOBMI-NEXT:    popl %esi
7230; X86-NOBMI-NEXT:    popl %edi
7231; X86-NOBMI-NEXT:    popl %ebx
7232; X86-NOBMI-NEXT:    popl %ebp
7233; X86-NOBMI-NEXT:    retl
7234;
7235; X86-BMI1NOTBM-LABEL: bextr64_d5_skipextrauses:
7236; X86-BMI1NOTBM:       # %bb.0:
7237; X86-BMI1NOTBM-NEXT:    pushl %ebp
7238; X86-BMI1NOTBM-NEXT:    pushl %ebx
7239; X86-BMI1NOTBM-NEXT:    pushl %edi
7240; X86-BMI1NOTBM-NEXT:    pushl %esi
7241; X86-BMI1NOTBM-NEXT:    subl $12, %esp
7242; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ebx
7243; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
7244; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7245; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
7246; X86-BMI1NOTBM-NEXT:    movl %eax, %ecx
7247; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
7248; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edx, %ebx
7249; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
7250; X86-BMI1NOTBM-NEXT:    testb $32, %al
7251; X86-BMI1NOTBM-NEXT:    je .LBB56_2
7252; X86-BMI1NOTBM-NEXT:  # %bb.1:
7253; X86-BMI1NOTBM-NEXT:    movl %esi, %ebx
7254; X86-BMI1NOTBM-NEXT:    xorl %esi, %esi
7255; X86-BMI1NOTBM-NEXT:  .LBB56_2:
7256; X86-BMI1NOTBM-NEXT:    movb $64, %cl
7257; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
7258; X86-BMI1NOTBM-NEXT:    shldl %cl, %ebx, %esi
7259; X86-BMI1NOTBM-NEXT:    shll %cl, %ebx
7260; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7261; X86-BMI1NOTBM-NEXT:    movl %ebx, %ebp
7262; X86-BMI1NOTBM-NEXT:    jne .LBB56_4
7263; X86-BMI1NOTBM-NEXT:  # %bb.3:
7264; X86-BMI1NOTBM-NEXT:    movl %esi, %ebp
7265; X86-BMI1NOTBM-NEXT:  .LBB56_4:
7266; X86-BMI1NOTBM-NEXT:    movl %ebp, %esi
7267; X86-BMI1NOTBM-NEXT:    shrl %cl, %esi
7268; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7269; X86-BMI1NOTBM-NEXT:    movl $0, %edi
7270; X86-BMI1NOTBM-NEXT:    jne .LBB56_6
7271; X86-BMI1NOTBM-NEXT:  # %bb.5:
7272; X86-BMI1NOTBM-NEXT:    movl %ebx, %edx
7273; X86-BMI1NOTBM-NEXT:    movl %esi, %edi
7274; X86-BMI1NOTBM-NEXT:  .LBB56_6:
7275; X86-BMI1NOTBM-NEXT:    shrdl %cl, %ebp, %edx
7276; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7277; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7278; X86-BMI1NOTBM-NEXT:    jne .LBB56_8
7279; X86-BMI1NOTBM-NEXT:  # %bb.7:
7280; X86-BMI1NOTBM-NEXT:    movl %edx, %esi
7281; X86-BMI1NOTBM-NEXT:  .LBB56_8:
7282; X86-BMI1NOTBM-NEXT:    subl $8, %esp
7283; X86-BMI1NOTBM-NEXT:    pushl %ecx
7284; X86-BMI1NOTBM-NEXT:    pushl %eax
7285; X86-BMI1NOTBM-NEXT:    calll use64
7286; X86-BMI1NOTBM-NEXT:    addl $16, %esp
7287; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
7288; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
7289; X86-BMI1NOTBM-NEXT:    addl $12, %esp
7290; X86-BMI1NOTBM-NEXT:    popl %esi
7291; X86-BMI1NOTBM-NEXT:    popl %edi
7292; X86-BMI1NOTBM-NEXT:    popl %ebx
7293; X86-BMI1NOTBM-NEXT:    popl %ebp
7294; X86-BMI1NOTBM-NEXT:    retl
7295;
7296; X86-BMI1BMI2-LABEL: bextr64_d5_skipextrauses:
7297; X86-BMI1BMI2:       # %bb.0:
7298; X86-BMI1BMI2-NEXT:    pushl %ebx
7299; X86-BMI1BMI2-NEXT:    pushl %edi
7300; X86-BMI1BMI2-NEXT:    pushl %esi
7301; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
7302; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7303; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7304; X86-BMI1BMI2-NEXT:    movl %eax, %ecx
7305; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %edi
7306; X86-BMI1BMI2-NEXT:    shrxl %eax, %edx, %edx
7307; X86-BMI1BMI2-NEXT:    xorl %esi, %esi
7308; X86-BMI1BMI2-NEXT:    testb $32, %al
7309; X86-BMI1BMI2-NEXT:    je .LBB56_2
7310; X86-BMI1BMI2-NEXT:  # %bb.1:
7311; X86-BMI1BMI2-NEXT:    movl %edx, %edi
7312; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
7313; X86-BMI1BMI2-NEXT:  .LBB56_2:
7314; X86-BMI1BMI2-NEXT:    movb $64, %cl
7315; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7316; X86-BMI1BMI2-NEXT:    shldl %cl, %edi, %edx
7317; X86-BMI1BMI2-NEXT:    shlxl %ecx, %edi, %ebx
7318; X86-BMI1BMI2-NEXT:    testb $32, %cl
7319; X86-BMI1BMI2-NEXT:    je .LBB56_4
7320; X86-BMI1BMI2-NEXT:  # %bb.3:
7321; X86-BMI1BMI2-NEXT:    movl %ebx, %edx
7322; X86-BMI1BMI2-NEXT:    movl $0, %ebx
7323; X86-BMI1BMI2-NEXT:  .LBB56_4:
7324; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edi
7325; X86-BMI1BMI2-NEXT:    jne .LBB56_6
7326; X86-BMI1BMI2-NEXT:  # %bb.5:
7327; X86-BMI1BMI2-NEXT:    movl %edi, %esi
7328; X86-BMI1BMI2-NEXT:  .LBB56_6:
7329; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %ebx
7330; X86-BMI1BMI2-NEXT:    testb $32, %cl
7331; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7332; X86-BMI1BMI2-NEXT:    jne .LBB56_8
7333; X86-BMI1BMI2-NEXT:  # %bb.7:
7334; X86-BMI1BMI2-NEXT:    movl %ebx, %edi
7335; X86-BMI1BMI2-NEXT:  .LBB56_8:
7336; X86-BMI1BMI2-NEXT:    subl $8, %esp
7337; X86-BMI1BMI2-NEXT:    pushl %ecx
7338; X86-BMI1BMI2-NEXT:    pushl %eax
7339; X86-BMI1BMI2-NEXT:    calll use64
7340; X86-BMI1BMI2-NEXT:    addl $16, %esp
7341; X86-BMI1BMI2-NEXT:    movl %edi, %eax
7342; X86-BMI1BMI2-NEXT:    movl %esi, %edx
7343; X86-BMI1BMI2-NEXT:    popl %esi
7344; X86-BMI1BMI2-NEXT:    popl %edi
7345; X86-BMI1BMI2-NEXT:    popl %ebx
7346; X86-BMI1BMI2-NEXT:    retl
7347;
7348; X64-NOBMI-LABEL: bextr64_d5_skipextrauses:
7349; X64-NOBMI:       # %bb.0:
7350; X64-NOBMI-NEXT:    pushq %rbx
7351; X64-NOBMI-NEXT:    movq %rdi, %rbx
7352; X64-NOBMI-NEXT:    movl %esi, %ecx
7353; X64-NOBMI-NEXT:    shrq %cl, %rbx
7354; X64-NOBMI-NEXT:    negb %dl
7355; X64-NOBMI-NEXT:    movl %edx, %ecx
7356; X64-NOBMI-NEXT:    shlq %cl, %rbx
7357; X64-NOBMI-NEXT:    shrq %cl, %rbx
7358; X64-NOBMI-NEXT:    movq %rsi, %rdi
7359; X64-NOBMI-NEXT:    callq use64
7360; X64-NOBMI-NEXT:    movq %rbx, %rax
7361; X64-NOBMI-NEXT:    popq %rbx
7362; X64-NOBMI-NEXT:    retq
7363;
7364; X64-BMI1NOTBM-LABEL: bextr64_d5_skipextrauses:
7365; X64-BMI1NOTBM:       # %bb.0:
7366; X64-BMI1NOTBM-NEXT:    pushq %rbx
7367; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
7368; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
7369; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
7370; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rbx
7371; X64-BMI1NOTBM-NEXT:    movq %rsi, %rdi
7372; X64-BMI1NOTBM-NEXT:    callq use64
7373; X64-BMI1NOTBM-NEXT:    movq %rbx, %rax
7374; X64-BMI1NOTBM-NEXT:    popq %rbx
7375; X64-BMI1NOTBM-NEXT:    retq
7376;
7377; X64-BMI1BMI2-LABEL: bextr64_d5_skipextrauses:
7378; X64-BMI1BMI2:       # %bb.0:
7379; X64-BMI1BMI2-NEXT:    pushq %rbx
7380; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7381; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
7382; X64-BMI1BMI2-NEXT:    movq %rsi, %rdi
7383; X64-BMI1BMI2-NEXT:    callq use64
7384; X64-BMI1BMI2-NEXT:    movq %rbx, %rax
7385; X64-BMI1BMI2-NEXT:    popq %rbx
7386; X64-BMI1BMI2-NEXT:    retq
7387  %shifted = lshr i64 %val, %numskipbits
7388  %numhighbits = sub i64 64, %numlowbits
7389  %highbitscleared = shl i64 %shifted, %numhighbits
7390  %masked = lshr i64 %highbitscleared, %numhighbits
7391  call void @use64(i64 %numskipbits)
7392  ret i64 %masked
7393}
7394
7395; 64-bit, but with 32-bit output
7396
7397; Everything done in 64-bit, truncation happens last.
7398define i32 @bextr64_32_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
7399; X86-NOBMI-LABEL: bextr64_32_d0:
7400; X86-NOBMI:       # %bb.0:
7401; X86-NOBMI-NEXT:    pushl %esi
7402; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
7403; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7404; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
7405; X86-NOBMI-NEXT:    movl %esi, %eax
7406; X86-NOBMI-NEXT:    shrl %cl, %eax
7407; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
7408; X86-NOBMI-NEXT:    testb $32, %cl
7409; X86-NOBMI-NEXT:    je .LBB57_2
7410; X86-NOBMI-NEXT:  # %bb.1:
7411; X86-NOBMI-NEXT:    movl %eax, %edx
7412; X86-NOBMI-NEXT:    xorl %eax, %eax
7413; X86-NOBMI-NEXT:  .LBB57_2:
7414; X86-NOBMI-NEXT:    movb $64, %cl
7415; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7416; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
7417; X86-NOBMI-NEXT:    shll %cl, %edx
7418; X86-NOBMI-NEXT:    testb $32, %cl
7419; X86-NOBMI-NEXT:    je .LBB57_4
7420; X86-NOBMI-NEXT:  # %bb.3:
7421; X86-NOBMI-NEXT:    movl %edx, %eax
7422; X86-NOBMI-NEXT:    xorl %edx, %edx
7423; X86-NOBMI-NEXT:  .LBB57_4:
7424; X86-NOBMI-NEXT:    shrdl %cl, %eax, %edx
7425; X86-NOBMI-NEXT:    shrl %cl, %eax
7426; X86-NOBMI-NEXT:    testb $32, %cl
7427; X86-NOBMI-NEXT:    jne .LBB57_6
7428; X86-NOBMI-NEXT:  # %bb.5:
7429; X86-NOBMI-NEXT:    movl %edx, %eax
7430; X86-NOBMI-NEXT:  .LBB57_6:
7431; X86-NOBMI-NEXT:    popl %esi
7432; X86-NOBMI-NEXT:    retl
7433;
7434; X86-BMI1NOTBM-LABEL: bextr64_32_d0:
7435; X86-BMI1NOTBM:       # %bb.0:
7436; X86-BMI1NOTBM-NEXT:    pushl %esi
7437; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
7438; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edx
7439; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
7440; X86-BMI1NOTBM-NEXT:    movl %esi, %eax
7441; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
7442; X86-BMI1NOTBM-NEXT:    shrdl %cl, %esi, %edx
7443; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7444; X86-BMI1NOTBM-NEXT:    je .LBB57_2
7445; X86-BMI1NOTBM-NEXT:  # %bb.1:
7446; X86-BMI1NOTBM-NEXT:    movl %eax, %edx
7447; X86-BMI1NOTBM-NEXT:    xorl %eax, %eax
7448; X86-BMI1NOTBM-NEXT:  .LBB57_2:
7449; X86-BMI1NOTBM-NEXT:    movb $64, %cl
7450; X86-BMI1NOTBM-NEXT:    subb {{[0-9]+}}(%esp), %cl
7451; X86-BMI1NOTBM-NEXT:    shldl %cl, %edx, %eax
7452; X86-BMI1NOTBM-NEXT:    shll %cl, %edx
7453; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7454; X86-BMI1NOTBM-NEXT:    je .LBB57_4
7455; X86-BMI1NOTBM-NEXT:  # %bb.3:
7456; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
7457; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
7458; X86-BMI1NOTBM-NEXT:  .LBB57_4:
7459; X86-BMI1NOTBM-NEXT:    shrdl %cl, %eax, %edx
7460; X86-BMI1NOTBM-NEXT:    shrl %cl, %eax
7461; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7462; X86-BMI1NOTBM-NEXT:    jne .LBB57_6
7463; X86-BMI1NOTBM-NEXT:  # %bb.5:
7464; X86-BMI1NOTBM-NEXT:    movl %edx, %eax
7465; X86-BMI1NOTBM-NEXT:  .LBB57_6:
7466; X86-BMI1NOTBM-NEXT:    popl %esi
7467; X86-BMI1NOTBM-NEXT:    retl
7468;
7469; X86-BMI1BMI2-LABEL: bextr64_32_d0:
7470; X86-BMI1BMI2:       # %bb.0:
7471; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
7472; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7473; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7474; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
7475; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %edx
7476; X86-BMI1BMI2-NEXT:    testb $32, %cl
7477; X86-BMI1BMI2-NEXT:    je .LBB57_2
7478; X86-BMI1BMI2-NEXT:  # %bb.1:
7479; X86-BMI1BMI2-NEXT:    movl %edx, %eax
7480; X86-BMI1BMI2-NEXT:    xorl %edx, %edx
7481; X86-BMI1BMI2-NEXT:  .LBB57_2:
7482; X86-BMI1BMI2-NEXT:    movb $64, %cl
7483; X86-BMI1BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7484; X86-BMI1BMI2-NEXT:    shldl %cl, %eax, %edx
7485; X86-BMI1BMI2-NEXT:    shlxl %ecx, %eax, %eax
7486; X86-BMI1BMI2-NEXT:    testb $32, %cl
7487; X86-BMI1BMI2-NEXT:    je .LBB57_4
7488; X86-BMI1BMI2-NEXT:  # %bb.3:
7489; X86-BMI1BMI2-NEXT:    movl %eax, %edx
7490; X86-BMI1BMI2-NEXT:    xorl %eax, %eax
7491; X86-BMI1BMI2-NEXT:  .LBB57_4:
7492; X86-BMI1BMI2-NEXT:    shrdl %cl, %edx, %eax
7493; X86-BMI1BMI2-NEXT:    testb $32, %cl
7494; X86-BMI1BMI2-NEXT:    je .LBB57_6
7495; X86-BMI1BMI2-NEXT:  # %bb.5:
7496; X86-BMI1BMI2-NEXT:    shrxl %ecx, %edx, %eax
7497; X86-BMI1BMI2-NEXT:  .LBB57_6:
7498; X86-BMI1BMI2-NEXT:    retl
7499;
7500; X64-NOBMI-LABEL: bextr64_32_d0:
7501; X64-NOBMI:       # %bb.0:
7502; X64-NOBMI-NEXT:    movq %rsi, %rcx
7503; X64-NOBMI-NEXT:    movq %rdi, %rax
7504; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
7505; X64-NOBMI-NEXT:    shrq %cl, %rax
7506; X64-NOBMI-NEXT:    negb %dl
7507; X64-NOBMI-NEXT:    movl %edx, %ecx
7508; X64-NOBMI-NEXT:    shlq %cl, %rax
7509; X64-NOBMI-NEXT:    shrq %cl, %rax
7510; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
7511; X64-NOBMI-NEXT:    retq
7512;
7513; X64-BMI1NOTBM-LABEL: bextr64_32_d0:
7514; X64-BMI1NOTBM:       # %bb.0:
7515; X64-BMI1NOTBM-NEXT:    shlq $8, %rdx
7516; X64-BMI1NOTBM-NEXT:    movzbl %sil, %eax
7517; X64-BMI1NOTBM-NEXT:    orq %rdx, %rax
7518; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
7519; X64-BMI1NOTBM-NEXT:    # kill: def $eax killed $eax killed $rax
7520; X64-BMI1NOTBM-NEXT:    retq
7521;
7522; X64-BMI1BMI2-LABEL: bextr64_32_d0:
7523; X64-BMI1BMI2:       # %bb.0:
7524; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7525; X64-BMI1BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7526; X64-BMI1BMI2-NEXT:    # kill: def $eax killed $eax killed $rax
7527; X64-BMI1BMI2-NEXT:    retq
7528  %shifted = lshr i64 %val, %numskipbits
7529  %numhighbits = sub i64 64, %numlowbits
7530  %highbitscleared = shl i64 %shifted, %numhighbits
7531  %masked = lshr i64 %highbitscleared, %numhighbits
7532  %res = trunc i64 %masked to i32
7533  ret i32 %res
7534}
7535
7536; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
7537define i32 @bextr64_32_d1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
7538; X86-NOBMI-LABEL: bextr64_32_d1:
7539; X86-NOBMI:       # %bb.0:
7540; X86-NOBMI-NEXT:    pushl %esi
7541; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
7542; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7543; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
7544; X86-NOBMI-NEXT:    movl %esi, %eax
7545; X86-NOBMI-NEXT:    shrl %cl, %eax
7546; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
7547; X86-NOBMI-NEXT:    testb $32, %cl
7548; X86-NOBMI-NEXT:    jne .LBB58_2
7549; X86-NOBMI-NEXT:  # %bb.1:
7550; X86-NOBMI-NEXT:    movl %edx, %eax
7551; X86-NOBMI-NEXT:  .LBB58_2:
7552; X86-NOBMI-NEXT:    xorl %ecx, %ecx
7553; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7554; X86-NOBMI-NEXT:    shll %cl, %eax
7555; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
7556; X86-NOBMI-NEXT:    shrl %cl, %eax
7557; X86-NOBMI-NEXT:    popl %esi
7558; X86-NOBMI-NEXT:    retl
7559;
7560; X86-BMI1NOTBM-LABEL: bextr64_32_d1:
7561; X86-BMI1NOTBM:       # %bb.0:
7562; X86-BMI1NOTBM-NEXT:    pushl %edi
7563; X86-BMI1NOTBM-NEXT:    pushl %esi
7564; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %al
7565; X86-BMI1NOTBM-NEXT:    movb {{[0-9]+}}(%esp), %cl
7566; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %esi
7567; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %edi
7568; X86-BMI1NOTBM-NEXT:    movl %edi, %edx
7569; X86-BMI1NOTBM-NEXT:    shrl %cl, %edx
7570; X86-BMI1NOTBM-NEXT:    shrdl %cl, %edi, %esi
7571; X86-BMI1NOTBM-NEXT:    testb $32, %cl
7572; X86-BMI1NOTBM-NEXT:    jne .LBB58_2
7573; X86-BMI1NOTBM-NEXT:  # %bb.1:
7574; X86-BMI1NOTBM-NEXT:    movl %esi, %edx
7575; X86-BMI1NOTBM-NEXT:  .LBB58_2:
7576; X86-BMI1NOTBM-NEXT:    shll $8, %eax
7577; X86-BMI1NOTBM-NEXT:    bextrl %eax, %edx, %eax
7578; X86-BMI1NOTBM-NEXT:    popl %esi
7579; X86-BMI1NOTBM-NEXT:    popl %edi
7580; X86-BMI1NOTBM-NEXT:    retl
7581;
7582; X86-BMI1BMI2-LABEL: bextr64_32_d1:
7583; X86-BMI1BMI2:       # %bb.0:
7584; X86-BMI1BMI2-NEXT:    pushl %esi
7585; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %al
7586; X86-BMI1BMI2-NEXT:    movb {{[0-9]+}}(%esp), %cl
7587; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7588; X86-BMI1BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
7589; X86-BMI1BMI2-NEXT:    shrdl %cl, %esi, %edx
7590; X86-BMI1BMI2-NEXT:    testb $32, %cl
7591; X86-BMI1BMI2-NEXT:    je .LBB58_2
7592; X86-BMI1BMI2-NEXT:  # %bb.1:
7593; X86-BMI1BMI2-NEXT:    shrxl %ecx, %esi, %edx
7594; X86-BMI1BMI2-NEXT:  .LBB58_2:
7595; X86-BMI1BMI2-NEXT:    bzhil %eax, %edx, %eax
7596; X86-BMI1BMI2-NEXT:    popl %esi
7597; X86-BMI1BMI2-NEXT:    retl
7598;
7599; X64-NOBMI-LABEL: bextr64_32_d1:
7600; X64-NOBMI:       # %bb.0:
7601; X64-NOBMI-NEXT:    movq %rsi, %rcx
7602; X64-NOBMI-NEXT:    movq %rdi, %rax
7603; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
7604; X64-NOBMI-NEXT:    shrq %cl, %rax
7605; X64-NOBMI-NEXT:    negb %dl
7606; X64-NOBMI-NEXT:    movl %edx, %ecx
7607; X64-NOBMI-NEXT:    shll %cl, %eax
7608; X64-NOBMI-NEXT:    shrl %cl, %eax
7609; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
7610; X64-NOBMI-NEXT:    retq
7611;
7612; X64-BMI1NOTBM-LABEL: bextr64_32_d1:
7613; X64-BMI1NOTBM:       # %bb.0:
7614; X64-BMI1NOTBM-NEXT:    movq %rsi, %rcx
7615; X64-BMI1NOTBM-NEXT:    # kill: def $cl killed $cl killed $rcx
7616; X64-BMI1NOTBM-NEXT:    shrq %cl, %rdi
7617; X64-BMI1NOTBM-NEXT:    shll $8, %edx
7618; X64-BMI1NOTBM-NEXT:    bextrl %edx, %edi, %eax
7619; X64-BMI1NOTBM-NEXT:    retq
7620;
7621; X64-BMI1BMI2-LABEL: bextr64_32_d1:
7622; X64-BMI1BMI2:       # %bb.0:
7623; X64-BMI1BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7624; X64-BMI1BMI2-NEXT:    bzhil %edx, %eax, %eax
7625; X64-BMI1BMI2-NEXT:    retq
7626  %shifted = lshr i64 %val, %numskipbits
7627  %truncshifted = trunc i64 %shifted to i32
7628  %numhighbits = sub i32 32, %numlowbits
7629  %highbitscleared = shl i32 %truncshifted, %numhighbits
7630  %masked = lshr i32 %highbitscleared, %numhighbits
7631  ret i32 %masked
7632}
7633
7634; ---------------------------------------------------------------------------- ;
7635; Constant
7636; ---------------------------------------------------------------------------- ;
7637
7638; https://bugs.llvm.org/show_bug.cgi?id=38938
7639define void @pr38938(i32* %a0, i64* %a1) nounwind {
7640; X86-NOBMI-LABEL: pr38938:
7641; X86-NOBMI:       # %bb.0:
7642; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7643; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7644; X86-NOBMI-NEXT:    movl (%ecx), %ecx
7645; X86-NOBMI-NEXT:    shrl $19, %ecx
7646; X86-NOBMI-NEXT:    andl $4092, %ecx # imm = 0xFFC
7647; X86-NOBMI-NEXT:    incl (%eax,%ecx)
7648; X86-NOBMI-NEXT:    retl
7649;
7650; X86-BMI1NOTBM-LABEL: pr38938:
7651; X86-BMI1NOTBM:       # %bb.0:
7652; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7653; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7654; X86-BMI1NOTBM-NEXT:    movl $2581, %edx # imm = 0xA15
7655; X86-BMI1NOTBM-NEXT:    bextrl %edx, (%ecx), %ecx
7656; X86-BMI1NOTBM-NEXT:    incl (%eax,%ecx,4)
7657; X86-BMI1NOTBM-NEXT:    retl
7658;
7659; X86-BMI1TBM-LABEL: pr38938:
7660; X86-BMI1TBM:       # %bb.0:
7661; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7662; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7663; X86-BMI1TBM-NEXT:    bextrl $2581, (%ecx), %ecx # imm = 0xA15
7664; X86-BMI1TBM-NEXT:    incl (%eax,%ecx,4)
7665; X86-BMI1TBM-NEXT:    retl
7666;
7667; X86-BMI1NOTBMBMI2-LABEL: pr38938:
7668; X86-BMI1NOTBMBMI2:       # %bb.0:
7669; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7670; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7671; X86-BMI1NOTBMBMI2-NEXT:    movl $2581, %edx # imm = 0xA15
7672; X86-BMI1NOTBMBMI2-NEXT:    bextrl %edx, (%ecx), %ecx
7673; X86-BMI1NOTBMBMI2-NEXT:    incl (%eax,%ecx,4)
7674; X86-BMI1NOTBMBMI2-NEXT:    retl
7675;
7676; X64-NOBMI-LABEL: pr38938:
7677; X64-NOBMI:       # %bb.0:
7678; X64-NOBMI-NEXT:    movq (%rsi), %rax
7679; X64-NOBMI-NEXT:    shrq $19, %rax
7680; X64-NOBMI-NEXT:    andl $4092, %eax # imm = 0xFFC
7681; X64-NOBMI-NEXT:    incl (%rdi,%rax)
7682; X64-NOBMI-NEXT:    retq
7683;
7684; X64-BMI1NOTBM-LABEL: pr38938:
7685; X64-BMI1NOTBM:       # %bb.0:
7686; X64-BMI1NOTBM-NEXT:    movl $2581, %eax # imm = 0xA15
7687; X64-BMI1NOTBM-NEXT:    bextrq %rax, (%rsi), %rax
7688; X64-BMI1NOTBM-NEXT:    incl (%rdi,%rax,4)
7689; X64-BMI1NOTBM-NEXT:    retq
7690;
7691; X64-BMI1TBM-LABEL: pr38938:
7692; X64-BMI1TBM:       # %bb.0:
7693; X64-BMI1TBM-NEXT:    bextrq $2581, (%rsi), %rax # imm = 0xA15
7694; X64-BMI1TBM-NEXT:    incl (%rdi,%rax,4)
7695; X64-BMI1TBM-NEXT:    retq
7696;
7697; X64-BMI1NOTBMBMI2-LABEL: pr38938:
7698; X64-BMI1NOTBMBMI2:       # %bb.0:
7699; X64-BMI1NOTBMBMI2-NEXT:    movl $2581, %eax # imm = 0xA15
7700; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, (%rsi), %rax
7701; X64-BMI1NOTBMBMI2-NEXT:    incl (%rdi,%rax,4)
7702; X64-BMI1NOTBMBMI2-NEXT:    retq
7703  %tmp = load i64, i64* %a1, align 8
7704  %tmp1 = lshr i64 %tmp, 21
7705  %tmp2 = and i64 %tmp1, 1023
7706  %tmp3 = getelementptr inbounds i32, i32* %a0, i64 %tmp2
7707  %tmp4 = load i32, i32* %tmp3, align 4
7708  %tmp5 = add nsw i32 %tmp4, 1
7709  store i32 %tmp5, i32* %tmp3, align 4
7710  ret void
7711}
7712
7713; The most canonical variant
7714define i32 @c0_i32(i32 %arg) nounwind {
7715; X86-NOBMI-LABEL: c0_i32:
7716; X86-NOBMI:       # %bb.0:
7717; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7718; X86-NOBMI-NEXT:    shrl $19, %eax
7719; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
7720; X86-NOBMI-NEXT:    retl
7721;
7722; X86-BMI1NOTBM-LABEL: c0_i32:
7723; X86-BMI1NOTBM:       # %bb.0:
7724; X86-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
7725; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
7726; X86-BMI1NOTBM-NEXT:    retl
7727;
7728; X86-BMI1TBM-LABEL: c0_i32:
7729; X86-BMI1TBM:       # %bb.0:
7730; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
7731; X86-BMI1TBM-NEXT:    retl
7732;
7733; X86-BMI1NOTBMBMI2-LABEL: c0_i32:
7734; X86-BMI1NOTBMBMI2:       # %bb.0:
7735; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
7736; X86-BMI1NOTBMBMI2-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
7737; X86-BMI1NOTBMBMI2-NEXT:    retl
7738;
7739; X64-NOBMI-LABEL: c0_i32:
7740; X64-NOBMI:       # %bb.0:
7741; X64-NOBMI-NEXT:    movl %edi, %eax
7742; X64-NOBMI-NEXT:    shrl $19, %eax
7743; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
7744; X64-NOBMI-NEXT:    retq
7745;
7746; X64-BMI1NOTBM-LABEL: c0_i32:
7747; X64-BMI1NOTBM:       # %bb.0:
7748; X64-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
7749; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
7750; X64-BMI1NOTBM-NEXT:    retq
7751;
7752; X64-BMI1TBM-LABEL: c0_i32:
7753; X64-BMI1TBM:       # %bb.0:
7754; X64-BMI1TBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
7755; X64-BMI1TBM-NEXT:    retq
7756;
7757; X64-BMI1NOTBMBMI2-LABEL: c0_i32:
7758; X64-BMI1NOTBMBMI2:       # %bb.0:
7759; X64-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
7760; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
7761; X64-BMI1NOTBMBMI2-NEXT:    retq
7762  %tmp0 = lshr i32 %arg, 19
7763  %tmp1 = and i32 %tmp0, 1023
7764  ret i32 %tmp1
7765}
7766
7767; Should be still fine, but the mask is shifted
7768define i32 @c1_i32(i32 %arg) nounwind {
7769; X86-LABEL: c1_i32:
7770; X86:       # %bb.0:
7771; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7772; X86-NEXT:    shrl $19, %eax
7773; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
7774; X86-NEXT:    retl
7775;
7776; X64-LABEL: c1_i32:
7777; X64:       # %bb.0:
7778; X64-NEXT:    movl %edi, %eax
7779; X64-NEXT:    shrl $19, %eax
7780; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
7781; X64-NEXT:    retq
7782  %tmp0 = lshr i32 %arg, 19
7783  %tmp1 = and i32 %tmp0, 4092
7784  ret i32 %tmp1
7785}
7786
7787; Should be still fine, but the result is shifted left afterwards
7788define i32 @c2_i32(i32 %arg) nounwind {
7789; X86-LABEL: c2_i32:
7790; X86:       # %bb.0:
7791; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7792; X86-NEXT:    shrl $17, %eax
7793; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
7794; X86-NEXT:    retl
7795;
7796; X64-LABEL: c2_i32:
7797; X64:       # %bb.0:
7798; X64-NEXT:    movl %edi, %eax
7799; X64-NEXT:    shrl $17, %eax
7800; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
7801; X64-NEXT:    retq
7802  %tmp0 = lshr i32 %arg, 19
7803  %tmp1 = and i32 %tmp0, 1023
7804  %tmp2 = shl i32 %tmp1, 2
7805  ret i32 %tmp2
7806}
7807
7808; The mask covers newly shifted-in bit
7809define i32 @c4_i32_bad(i32 %arg) nounwind {
7810; X86-LABEL: c4_i32_bad:
7811; X86:       # %bb.0:
7812; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7813; X86-NEXT:    shrl $19, %eax
7814; X86-NEXT:    andl $-2, %eax
7815; X86-NEXT:    retl
7816;
7817; X64-LABEL: c4_i32_bad:
7818; X64:       # %bb.0:
7819; X64-NEXT:    movl %edi, %eax
7820; X64-NEXT:    shrl $19, %eax
7821; X64-NEXT:    andl $-2, %eax
7822; X64-NEXT:    retq
7823  %tmp0 = lshr i32 %arg, 19
7824  %tmp1 = and i32 %tmp0, 16382
7825  ret i32 %tmp1
7826}
7827
7828; i64
7829
7830; The most canonical variant
7831define i64 @c0_i64(i64 %arg) nounwind {
7832; X86-NOBMI-LABEL: c0_i64:
7833; X86-NOBMI:       # %bb.0:
7834; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7835; X86-NOBMI-NEXT:    shrl $19, %eax
7836; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
7837; X86-NOBMI-NEXT:    xorl %edx, %edx
7838; X86-NOBMI-NEXT:    retl
7839;
7840; X86-BMI1NOTBM-LABEL: c0_i64:
7841; X86-BMI1NOTBM:       # %bb.0:
7842; X86-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
7843; X86-BMI1NOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
7844; X86-BMI1NOTBM-NEXT:    xorl %edx, %edx
7845; X86-BMI1NOTBM-NEXT:    retl
7846;
7847; X86-BMI1TBM-LABEL: c0_i64:
7848; X86-BMI1TBM:       # %bb.0:
7849; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
7850; X86-BMI1TBM-NEXT:    xorl %edx, %edx
7851; X86-BMI1TBM-NEXT:    retl
7852;
7853; X86-BMI1NOTBMBMI2-LABEL: c0_i64:
7854; X86-BMI1NOTBMBMI2:       # %bb.0:
7855; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
7856; X86-BMI1NOTBMBMI2-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
7857; X86-BMI1NOTBMBMI2-NEXT:    xorl %edx, %edx
7858; X86-BMI1NOTBMBMI2-NEXT:    retl
7859;
7860; X64-NOBMI-LABEL: c0_i64:
7861; X64-NOBMI:       # %bb.0:
7862; X64-NOBMI-NEXT:    movq %rdi, %rax
7863; X64-NOBMI-NEXT:    shrq $51, %rax
7864; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
7865; X64-NOBMI-NEXT:    retq
7866;
7867; X64-BMI1NOTBM-LABEL: c0_i64:
7868; X64-BMI1NOTBM:       # %bb.0:
7869; X64-BMI1NOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
7870; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
7871; X64-BMI1NOTBM-NEXT:    retq
7872;
7873; X64-BMI1TBM-LABEL: c0_i64:
7874; X64-BMI1TBM:       # %bb.0:
7875; X64-BMI1TBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
7876; X64-BMI1TBM-NEXT:    retq
7877;
7878; X64-BMI1NOTBMBMI2-LABEL: c0_i64:
7879; X64-BMI1NOTBMBMI2:       # %bb.0:
7880; X64-BMI1NOTBMBMI2-NEXT:    movl $2611, %eax # imm = 0xA33
7881; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
7882; X64-BMI1NOTBMBMI2-NEXT:    retq
7883  %tmp0 = lshr i64 %arg, 51
7884  %tmp1 = and i64 %tmp0, 1023
7885  ret i64 %tmp1
7886}
7887
7888; Should be still fine, but the mask is shifted
7889define i64 @c1_i64(i64 %arg) nounwind {
7890; X86-LABEL: c1_i64:
7891; X86:       # %bb.0:
7892; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7893; X86-NEXT:    shrl $19, %eax
7894; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
7895; X86-NEXT:    xorl %edx, %edx
7896; X86-NEXT:    retl
7897;
7898; X64-LABEL: c1_i64:
7899; X64:       # %bb.0:
7900; X64-NEXT:    movq %rdi, %rax
7901; X64-NEXT:    shrq $51, %rax
7902; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
7903; X64-NEXT:    retq
7904  %tmp0 = lshr i64 %arg, 51
7905  %tmp1 = and i64 %tmp0, 4092
7906  ret i64 %tmp1
7907}
7908
7909; Should be still fine, but the result is shifted left afterwards
7910define i64 @c2_i64(i64 %arg) nounwind {
7911; X86-LABEL: c2_i64:
7912; X86:       # %bb.0:
7913; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7914; X86-NEXT:    shrl $17, %eax
7915; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
7916; X86-NEXT:    xorl %edx, %edx
7917; X86-NEXT:    retl
7918;
7919; X64-LABEL: c2_i64:
7920; X64:       # %bb.0:
7921; X64-NEXT:    movq %rdi, %rax
7922; X64-NEXT:    shrq $49, %rax
7923; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
7924; X64-NEXT:    retq
7925  %tmp0 = lshr i64 %arg, 51
7926  %tmp1 = and i64 %tmp0, 1023
7927  %tmp2 = shl i64 %tmp1, 2
7928  ret i64 %tmp2
7929}
7930
7931; The mask covers newly shifted-in bit
7932define i64 @c4_i64_bad(i64 %arg) nounwind {
7933; X86-LABEL: c4_i64_bad:
7934; X86:       # %bb.0:
7935; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
7936; X86-NEXT:    shrl $19, %eax
7937; X86-NEXT:    andl $-2, %eax
7938; X86-NEXT:    xorl %edx, %edx
7939; X86-NEXT:    retl
7940;
7941; X64-LABEL: c4_i64_bad:
7942; X64:       # %bb.0:
7943; X64-NEXT:    movq %rdi, %rax
7944; X64-NEXT:    shrq $51, %rax
7945; X64-NEXT:    andl $-2, %eax
7946; X64-NEXT:    retq
7947  %tmp0 = lshr i64 %arg, 51
7948  %tmp1 = and i64 %tmp0, 16382
7949  ret i64 %tmp1
7950}
7951
7952; ---------------------------------------------------------------------------- ;
7953; Constant, storing the result afterwards.
7954; ---------------------------------------------------------------------------- ;
7955
7956; i32
7957
7958; The most canonical variant
7959define void @c5_i32(i32 %arg, i32* %ptr) nounwind {
7960; X86-NOBMI-LABEL: c5_i32:
7961; X86-NOBMI:       # %bb.0:
7962; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7963; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7964; X86-NOBMI-NEXT:    shrl $19, %ecx
7965; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
7966; X86-NOBMI-NEXT:    movl %ecx, (%eax)
7967; X86-NOBMI-NEXT:    retl
7968;
7969; X86-BMI1NOTBM-LABEL: c5_i32:
7970; X86-BMI1NOTBM:       # %bb.0:
7971; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7972; X86-BMI1NOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
7973; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
7974; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
7975; X86-BMI1NOTBM-NEXT:    retl
7976;
7977; X86-BMI1TBM-LABEL: c5_i32:
7978; X86-BMI1TBM:       # %bb.0:
7979; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
7980; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
7981; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
7982; X86-BMI1TBM-NEXT:    retl
7983;
7984; X86-BMI1NOTBMBMI2-LABEL: c5_i32:
7985; X86-BMI1NOTBMBMI2:       # %bb.0:
7986; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7987; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %ecx # imm = 0xA13
7988; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
7989; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
7990; X86-BMI1NOTBMBMI2-NEXT:    retl
7991;
7992; X64-NOBMI-LABEL: c5_i32:
7993; X64-NOBMI:       # %bb.0:
7994; X64-NOBMI-NEXT:    shrl $19, %edi
7995; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
7996; X64-NOBMI-NEXT:    movl %edi, (%rsi)
7997; X64-NOBMI-NEXT:    retq
7998;
7999; X64-BMI1NOTBM-LABEL: c5_i32:
8000; X64-BMI1NOTBM:       # %bb.0:
8001; X64-BMI1NOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
8002; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
8003; X64-BMI1NOTBM-NEXT:    movl %eax, (%rsi)
8004; X64-BMI1NOTBM-NEXT:    retq
8005;
8006; X64-BMI1TBM-LABEL: c5_i32:
8007; X64-BMI1TBM:       # %bb.0:
8008; X64-BMI1TBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
8009; X64-BMI1TBM-NEXT:    movl %eax, (%rsi)
8010; X64-BMI1TBM-NEXT:    retq
8011;
8012; X64-BMI1NOTBMBMI2-LABEL: c5_i32:
8013; X64-BMI1NOTBMBMI2:       # %bb.0:
8014; X64-BMI1NOTBMBMI2-NEXT:    movl $2579, %eax # imm = 0xA13
8015; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
8016; X64-BMI1NOTBMBMI2-NEXT:    movl %eax, (%rsi)
8017; X64-BMI1NOTBMBMI2-NEXT:    retq
8018  %tmp0 = lshr i32 %arg, 19
8019  %tmp1 = and i32 %tmp0, 1023
8020  store i32 %tmp1, i32* %ptr
8021  ret void
8022}
8023
8024; Should be still fine, but the mask is shifted
8025define void @c6_i32(i32 %arg, i32* %ptr) nounwind {
8026; X86-NOBMI-LABEL: c6_i32:
8027; X86-NOBMI:       # %bb.0:
8028; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8029; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8030; X86-NOBMI-NEXT:    shrl $19, %ecx
8031; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
8032; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8033; X86-NOBMI-NEXT:    retl
8034;
8035; X86-BMI1NOTBM-LABEL: c6_i32:
8036; X86-BMI1NOTBM:       # %bb.0:
8037; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8038; X86-BMI1NOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
8039; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8040; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
8041; X86-BMI1NOTBM-NEXT:    retl
8042;
8043; X86-BMI1TBM-LABEL: c6_i32:
8044; X86-BMI1TBM:       # %bb.0:
8045; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8046; X86-BMI1TBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
8047; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
8048; X86-BMI1TBM-NEXT:    retl
8049;
8050; X86-BMI1NOTBMBMI2-LABEL: c6_i32:
8051; X86-BMI1NOTBMBMI2:       # %bb.0:
8052; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
8053; X86-BMI1NOTBMBMI2-NEXT:    movl $3091, %ecx # imm = 0xC13
8054; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8055; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
8056; X86-BMI1NOTBMBMI2-NEXT:    retl
8057;
8058; X64-NOBMI-LABEL: c6_i32:
8059; X64-NOBMI:       # %bb.0:
8060; X64-NOBMI-NEXT:    shrl $19, %edi
8061; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
8062; X64-NOBMI-NEXT:    movl %edi, (%rsi)
8063; X64-NOBMI-NEXT:    retq
8064;
8065; X64-BMI1NOTBM-LABEL: c6_i32:
8066; X64-BMI1NOTBM:       # %bb.0:
8067; X64-BMI1NOTBM-NEXT:    movl $3091, %eax # imm = 0xC13
8068; X64-BMI1NOTBM-NEXT:    bextrl %eax, %edi, %eax
8069; X64-BMI1NOTBM-NEXT:    movl %eax, (%rsi)
8070; X64-BMI1NOTBM-NEXT:    retq
8071;
8072; X64-BMI1TBM-LABEL: c6_i32:
8073; X64-BMI1TBM:       # %bb.0:
8074; X64-BMI1TBM-NEXT:    bextrl $3091, %edi, %eax # imm = 0xC13
8075; X64-BMI1TBM-NEXT:    movl %eax, (%rsi)
8076; X64-BMI1TBM-NEXT:    retq
8077;
8078; X64-BMI1NOTBMBMI2-LABEL: c6_i32:
8079; X64-BMI1NOTBMBMI2:       # %bb.0:
8080; X64-BMI1NOTBMBMI2-NEXT:    movl $3091, %eax # imm = 0xC13
8081; X64-BMI1NOTBMBMI2-NEXT:    bextrl %eax, %edi, %eax
8082; X64-BMI1NOTBMBMI2-NEXT:    movl %eax, (%rsi)
8083; X64-BMI1NOTBMBMI2-NEXT:    retq
8084  %tmp0 = lshr i32 %arg, 19
8085  %tmp1 = and i32 %tmp0, 4095
8086  store i32 %tmp1, i32* %ptr
8087  ret void
8088}
8089
8090; Should be still fine, but the result is shifted left afterwards
8091define void @c7_i32(i32 %arg, i32* %ptr) nounwind {
8092; X86-LABEL: c7_i32:
8093; X86:       # %bb.0:
8094; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8095; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8096; X86-NEXT:    shrl $17, %ecx
8097; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
8098; X86-NEXT:    movl %ecx, (%eax)
8099; X86-NEXT:    retl
8100;
8101; X64-LABEL: c7_i32:
8102; X64:       # %bb.0:
8103; X64-NEXT:    shrl $17, %edi
8104; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
8105; X64-NEXT:    movl %edi, (%rsi)
8106; X64-NEXT:    retq
8107  %tmp0 = lshr i32 %arg, 19
8108  %tmp1 = and i32 %tmp0, 1023
8109  %tmp2 = shl i32 %tmp1, 2
8110  store i32 %tmp2, i32* %ptr
8111  ret void
8112}
8113
8114; i64
8115
8116; The most canonical variant
8117define void @c5_i64(i64 %arg, i64* %ptr) nounwind {
8118; X86-NOBMI-LABEL: c5_i64:
8119; X86-NOBMI:       # %bb.0:
8120; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8121; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8122; X86-NOBMI-NEXT:    shrl $19, %ecx
8123; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
8124; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8125; X86-NOBMI-NEXT:    movl $0, 4(%eax)
8126; X86-NOBMI-NEXT:    retl
8127;
8128; X86-BMI1NOTBM-LABEL: c5_i64:
8129; X86-BMI1NOTBM:       # %bb.0:
8130; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8131; X86-BMI1NOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
8132; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8133; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
8134; X86-BMI1NOTBM-NEXT:    movl $0, 4(%eax)
8135; X86-BMI1NOTBM-NEXT:    retl
8136;
8137; X86-BMI1TBM-LABEL: c5_i64:
8138; X86-BMI1TBM:       # %bb.0:
8139; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8140; X86-BMI1TBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
8141; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
8142; X86-BMI1TBM-NEXT:    movl $0, 4(%eax)
8143; X86-BMI1TBM-NEXT:    retl
8144;
8145; X86-BMI1NOTBMBMI2-LABEL: c5_i64:
8146; X86-BMI1NOTBMBMI2:       # %bb.0:
8147; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
8148; X86-BMI1NOTBMBMI2-NEXT:    movl $2579, %ecx # imm = 0xA13
8149; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8150; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
8151; X86-BMI1NOTBMBMI2-NEXT:    movl $0, 4(%eax)
8152; X86-BMI1NOTBMBMI2-NEXT:    retl
8153;
8154; X64-NOBMI-LABEL: c5_i64:
8155; X64-NOBMI:       # %bb.0:
8156; X64-NOBMI-NEXT:    shrq $51, %rdi
8157; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
8158; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
8159; X64-NOBMI-NEXT:    retq
8160;
8161; X64-BMI1NOTBM-LABEL: c5_i64:
8162; X64-BMI1NOTBM:       # %bb.0:
8163; X64-BMI1NOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
8164; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
8165; X64-BMI1NOTBM-NEXT:    movq %rax, (%rsi)
8166; X64-BMI1NOTBM-NEXT:    retq
8167;
8168; X64-BMI1TBM-LABEL: c5_i64:
8169; X64-BMI1TBM:       # %bb.0:
8170; X64-BMI1TBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
8171; X64-BMI1TBM-NEXT:    movq %rax, (%rsi)
8172; X64-BMI1TBM-NEXT:    retq
8173;
8174; X64-BMI1NOTBMBMI2-LABEL: c5_i64:
8175; X64-BMI1NOTBMBMI2:       # %bb.0:
8176; X64-BMI1NOTBMBMI2-NEXT:    movl $2611, %eax # imm = 0xA33
8177; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
8178; X64-BMI1NOTBMBMI2-NEXT:    movq %rax, (%rsi)
8179; X64-BMI1NOTBMBMI2-NEXT:    retq
8180  %tmp0 = lshr i64 %arg, 51
8181  %tmp1 = and i64 %tmp0, 1023
8182  store i64 %tmp1, i64* %ptr
8183  ret void
8184}
8185
8186; Should be still fine, but the mask is shifted
8187define void @c6_i64(i64 %arg, i64* %ptr) nounwind {
8188; X86-NOBMI-LABEL: c6_i64:
8189; X86-NOBMI:       # %bb.0:
8190; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8191; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8192; X86-NOBMI-NEXT:    shrl $19, %ecx
8193; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
8194; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8195; X86-NOBMI-NEXT:    movl $0, 4(%eax)
8196; X86-NOBMI-NEXT:    retl
8197;
8198; X86-BMI1NOTBM-LABEL: c6_i64:
8199; X86-BMI1NOTBM:       # %bb.0:
8200; X86-BMI1NOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8201; X86-BMI1NOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
8202; X86-BMI1NOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8203; X86-BMI1NOTBM-NEXT:    movl %ecx, (%eax)
8204; X86-BMI1NOTBM-NEXT:    movl $0, 4(%eax)
8205; X86-BMI1NOTBM-NEXT:    retl
8206;
8207; X86-BMI1TBM-LABEL: c6_i64:
8208; X86-BMI1TBM:       # %bb.0:
8209; X86-BMI1TBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8210; X86-BMI1TBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
8211; X86-BMI1TBM-NEXT:    movl %ecx, (%eax)
8212; X86-BMI1TBM-NEXT:    movl $0, 4(%eax)
8213; X86-BMI1TBM-NEXT:    retl
8214;
8215; X86-BMI1NOTBMBMI2-LABEL: c6_i64:
8216; X86-BMI1NOTBMBMI2:       # %bb.0:
8217; X86-BMI1NOTBMBMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
8218; X86-BMI1NOTBMBMI2-NEXT:    movl $3091, %ecx # imm = 0xC13
8219; X86-BMI1NOTBMBMI2-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8220; X86-BMI1NOTBMBMI2-NEXT:    movl %ecx, (%eax)
8221; X86-BMI1NOTBMBMI2-NEXT:    movl $0, 4(%eax)
8222; X86-BMI1NOTBMBMI2-NEXT:    retl
8223;
8224; X64-NOBMI-LABEL: c6_i64:
8225; X64-NOBMI:       # %bb.0:
8226; X64-NOBMI-NEXT:    shrq $51, %rdi
8227; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
8228; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
8229; X64-NOBMI-NEXT:    retq
8230;
8231; X64-BMI1NOTBM-LABEL: c6_i64:
8232; X64-BMI1NOTBM:       # %bb.0:
8233; X64-BMI1NOTBM-NEXT:    movl $3123, %eax # imm = 0xC33
8234; X64-BMI1NOTBM-NEXT:    bextrq %rax, %rdi, %rax
8235; X64-BMI1NOTBM-NEXT:    movq %rax, (%rsi)
8236; X64-BMI1NOTBM-NEXT:    retq
8237;
8238; X64-BMI1TBM-LABEL: c6_i64:
8239; X64-BMI1TBM:       # %bb.0:
8240; X64-BMI1TBM-NEXT:    bextrq $3123, %rdi, %rax # imm = 0xC33
8241; X64-BMI1TBM-NEXT:    movq %rax, (%rsi)
8242; X64-BMI1TBM-NEXT:    retq
8243;
8244; X64-BMI1NOTBMBMI2-LABEL: c6_i64:
8245; X64-BMI1NOTBMBMI2:       # %bb.0:
8246; X64-BMI1NOTBMBMI2-NEXT:    movl $3123, %eax # imm = 0xC33
8247; X64-BMI1NOTBMBMI2-NEXT:    bextrq %rax, %rdi, %rax
8248; X64-BMI1NOTBMBMI2-NEXT:    movq %rax, (%rsi)
8249; X64-BMI1NOTBMBMI2-NEXT:    retq
8250  %tmp0 = lshr i64 %arg, 51
8251  %tmp1 = and i64 %tmp0, 4095
8252  store i64 %tmp1, i64* %ptr
8253  ret void
8254}
8255
8256; Should be still fine, but the result is shifted left afterwards
8257define void @c7_i64(i64 %arg, i64* %ptr) nounwind {
8258; X86-LABEL: c7_i64:
8259; X86:       # %bb.0:
8260; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8261; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8262; X86-NEXT:    shrl $17, %ecx
8263; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
8264; X86-NEXT:    movl %ecx, (%eax)
8265; X86-NEXT:    movl $0, 4(%eax)
8266; X86-NEXT:    retl
8267;
8268; X64-LABEL: c7_i64:
8269; X64:       # %bb.0:
8270; X64-NEXT:    shrq $49, %rdi
8271; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
8272; X64-NEXT:    movq %rdi, (%rsi)
8273; X64-NEXT:    retq
8274  %tmp0 = lshr i64 %arg, 51
8275  %tmp1 = and i64 %tmp0, 1023
8276  %tmp2 = shl i64 %tmp1, 2
8277  store i64 %tmp2, i64* %ptr
8278  ret void
8279}
8280