xref: /llvm-project/llvm/test/CodeGen/X86/extract-bits.ll (revision d96529af3c362c53ef2e8c883a9e571fb3626927)
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=X86,X86-NOBMI
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMINOTBM,X86-BMI1
4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMITBM,X86-BMI1
5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMITBM,X86-BMI2
6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMINOTBM,X86-BMI2
7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI
8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMINOTBM,X64-BMI1
9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMITBM,X64-BMI1
10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMITBM,X64-BMI2
11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMINOTBM,X64-BMI2
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:    movzbl {{[0-9]+}}(%esp), %edx
38; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
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-BMI1-LABEL: bextr32_a0:
50; X86-BMI1:       # %bb.0:
51; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
52; X86-BMI1-NEXT:    shll $8, %eax
53; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
54; X86-BMI1-NEXT:    orl %eax, %ecx
55; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
56; X86-BMI1-NEXT:    retl
57;
58; X86-BMI2-LABEL: bextr32_a0:
59; X86-BMI2:       # %bb.0:
60; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
61; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
62; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
63; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
64; X86-BMI2-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-BMI1-LABEL: bextr32_a0:
79; X64-BMI1:       # %bb.0:
80; X64-BMI1-NEXT:    shll $8, %edx
81; X64-BMI1-NEXT:    movzbl %sil, %eax
82; X64-BMI1-NEXT:    orl %edx, %eax
83; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
84; X64-BMI1-NEXT:    retq
85;
86; X64-BMI2-LABEL: bextr32_a0:
87; X64-BMI2:       # %bb.0:
88; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
89; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
90; X64-BMI2-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:    movzbl {{[0-9]+}}(%esp), %edx
103; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
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-BMI1-LABEL: bextr32_a0_arithmetic:
115; X86-BMI1:       # %bb.0:
116; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
117; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
118; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
119; X86-BMI1-NEXT:    sarl %cl, %edx
120; X86-BMI1-NEXT:    shll $8, %eax
121; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
122; X86-BMI1-NEXT:    retl
123;
124; X86-BMI2-LABEL: bextr32_a0_arithmetic:
125; X86-BMI2:       # %bb.0:
126; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
127; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
128; X86-BMI2-NEXT:    sarxl %ecx, {{[0-9]+}}(%esp), %ecx
129; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
130; X86-BMI2-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-BMI1-LABEL: bextr32_a0_arithmetic:
145; X64-BMI1:       # %bb.0:
146; X64-BMI1-NEXT:    movl %esi, %ecx
147; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
148; X64-BMI1-NEXT:    sarl %cl, %edi
149; X64-BMI1-NEXT:    shll $8, %edx
150; X64-BMI1-NEXT:    bextrl %edx, %edi, %eax
151; X64-BMI1-NEXT:    retq
152;
153; X64-BMI2-LABEL: bextr32_a0_arithmetic:
154; X64-BMI2:       # %bb.0:
155; X64-BMI2-NEXT:    sarxl %esi, %edi, %eax
156; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
157; X64-BMI2-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:    movzbl {{[0-9]+}}(%esp), %edx
170; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
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-BMI1-LABEL: bextr32_a1_indexzext:
182; X86-BMI1:       # %bb.0:
183; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
184; X86-BMI1-NEXT:    shll $8, %eax
185; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
186; X86-BMI1-NEXT:    orl %eax, %ecx
187; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
188; X86-BMI1-NEXT:    retl
189;
190; X86-BMI2-LABEL: bextr32_a1_indexzext:
191; X86-BMI2:       # %bb.0:
192; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
193; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
194; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
195; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
196; X86-BMI2-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-BMI1-LABEL: bextr32_a1_indexzext:
211; X64-BMI1:       # %bb.0:
212; X64-BMI1-NEXT:    shll $8, %edx
213; X64-BMI1-NEXT:    orl %esi, %edx
214; X64-BMI1-NEXT:    bextrl %edx, %edi, %eax
215; X64-BMI1-NEXT:    retq
216;
217; X64-BMI2-LABEL: bextr32_a1_indexzext:
218; X64-BMI2:       # %bb.0:
219; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
220; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
221; X64-BMI2-NEXT:    retq
222  %skip = zext i8 %numskipbits to i32
223  %shifted = lshr i32 %val, %skip
224  %conv = zext i8 %numlowbits to i32
225  %onebit = shl i32 1, %conv
226  %mask = add nsw i32 %onebit, -1
227  %masked = and i32 %mask, %shifted
228  ret i32 %masked
229}
230
231define i32 @bextr32_a2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {
232; X86-NOBMI-LABEL: bextr32_a2_load:
233; X86-NOBMI:       # %bb.0:
234; X86-NOBMI-NEXT:    pushl %esi
235; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
236; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
237; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
238; X86-NOBMI-NEXT:    movl (%eax), %esi
239; X86-NOBMI-NEXT:    shrl %cl, %esi
240; X86-NOBMI-NEXT:    movl $1, %eax
241; X86-NOBMI-NEXT:    movl %edx, %ecx
242; X86-NOBMI-NEXT:    shll %cl, %eax
243; X86-NOBMI-NEXT:    decl %eax
244; X86-NOBMI-NEXT:    andl %esi, %eax
245; X86-NOBMI-NEXT:    popl %esi
246; X86-NOBMI-NEXT:    retl
247;
248; X86-BMI1-LABEL: bextr32_a2_load:
249; X86-BMI1:       # %bb.0:
250; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
251; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
252; X86-BMI1-NEXT:    shll $8, %ecx
253; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
254; X86-BMI1-NEXT:    orl %ecx, %edx
255; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
256; X86-BMI1-NEXT:    retl
257;
258; X86-BMI2-LABEL: bextr32_a2_load:
259; X86-BMI2:       # %bb.0:
260; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
261; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
262; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
263; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
264; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
265; X86-BMI2-NEXT:    retl
266;
267; X64-NOBMI-LABEL: bextr32_a2_load:
268; X64-NOBMI:       # %bb.0:
269; X64-NOBMI-NEXT:    movl %esi, %ecx
270; X64-NOBMI-NEXT:    movl (%rdi), %esi
271; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
272; X64-NOBMI-NEXT:    shrl %cl, %esi
273; X64-NOBMI-NEXT:    movl $1, %eax
274; X64-NOBMI-NEXT:    movl %edx, %ecx
275; X64-NOBMI-NEXT:    shll %cl, %eax
276; X64-NOBMI-NEXT:    decl %eax
277; X64-NOBMI-NEXT:    andl %esi, %eax
278; X64-NOBMI-NEXT:    retq
279;
280; X64-BMI1-LABEL: bextr32_a2_load:
281; X64-BMI1:       # %bb.0:
282; X64-BMI1-NEXT:    shll $8, %edx
283; X64-BMI1-NEXT:    movzbl %sil, %eax
284; X64-BMI1-NEXT:    orl %edx, %eax
285; X64-BMI1-NEXT:    bextrl %eax, (%rdi), %eax
286; X64-BMI1-NEXT:    retq
287;
288; X64-BMI2-LABEL: bextr32_a2_load:
289; X64-BMI2:       # %bb.0:
290; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
291; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
292; X64-BMI2-NEXT:    retq
293  %val = load i32, ptr %w
294  %shifted = lshr i32 %val, %numskipbits
295  %onebit = shl i32 1, %numlowbits
296  %mask = add nsw i32 %onebit, -1
297  %masked = and i32 %mask, %shifted
298  ret i32 %masked
299}
300
301define i32 @bextr32_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
302; X86-NOBMI-LABEL: bextr32_a3_load_indexzext:
303; X86-NOBMI:       # %bb.0:
304; X86-NOBMI-NEXT:    pushl %esi
305; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
306; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
307; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
308; X86-NOBMI-NEXT:    movl (%eax), %esi
309; X86-NOBMI-NEXT:    shrl %cl, %esi
310; X86-NOBMI-NEXT:    movl $1, %eax
311; X86-NOBMI-NEXT:    movl %edx, %ecx
312; X86-NOBMI-NEXT:    shll %cl, %eax
313; X86-NOBMI-NEXT:    decl %eax
314; X86-NOBMI-NEXT:    andl %esi, %eax
315; X86-NOBMI-NEXT:    popl %esi
316; X86-NOBMI-NEXT:    retl
317;
318; X86-BMI1-LABEL: bextr32_a3_load_indexzext:
319; X86-BMI1:       # %bb.0:
320; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
321; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
322; X86-BMI1-NEXT:    shll $8, %ecx
323; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
324; X86-BMI1-NEXT:    orl %ecx, %edx
325; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
326; X86-BMI1-NEXT:    retl
327;
328; X86-BMI2-LABEL: bextr32_a3_load_indexzext:
329; X86-BMI2:       # %bb.0:
330; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
331; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
332; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
333; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
334; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
335; X86-BMI2-NEXT:    retl
336;
337; X64-NOBMI-LABEL: bextr32_a3_load_indexzext:
338; X64-NOBMI:       # %bb.0:
339; X64-NOBMI-NEXT:    movl %esi, %ecx
340; X64-NOBMI-NEXT:    movl (%rdi), %esi
341; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
342; X64-NOBMI-NEXT:    shrl %cl, %esi
343; X64-NOBMI-NEXT:    movl $1, %eax
344; X64-NOBMI-NEXT:    movl %edx, %ecx
345; X64-NOBMI-NEXT:    shll %cl, %eax
346; X64-NOBMI-NEXT:    decl %eax
347; X64-NOBMI-NEXT:    andl %esi, %eax
348; X64-NOBMI-NEXT:    retq
349;
350; X64-BMI1-LABEL: bextr32_a3_load_indexzext:
351; X64-BMI1:       # %bb.0:
352; X64-BMI1-NEXT:    shll $8, %edx
353; X64-BMI1-NEXT:    orl %esi, %edx
354; X64-BMI1-NEXT:    bextrl %edx, (%rdi), %eax
355; X64-BMI1-NEXT:    retq
356;
357; X64-BMI2-LABEL: bextr32_a3_load_indexzext:
358; X64-BMI2:       # %bb.0:
359; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
360; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
361; X64-BMI2-NEXT:    retq
362  %val = load i32, ptr %w
363  %skip = zext i8 %numskipbits to i32
364  %shifted = lshr i32 %val, %skip
365  %conv = zext i8 %numlowbits to i32
366  %onebit = shl i32 1, %conv
367  %mask = add nsw i32 %onebit, -1
368  %masked = and i32 %mask, %shifted
369  ret i32 %masked
370}
371
372define i32 @bextr32_a4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
373; X86-NOBMI-LABEL: bextr32_a4_commutative:
374; X86-NOBMI:       # %bb.0:
375; X86-NOBMI-NEXT:    pushl %esi
376; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
377; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
378; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
379; X86-NOBMI-NEXT:    shrl %cl, %esi
380; X86-NOBMI-NEXT:    movl $1, %eax
381; X86-NOBMI-NEXT:    movl %edx, %ecx
382; X86-NOBMI-NEXT:    shll %cl, %eax
383; X86-NOBMI-NEXT:    decl %eax
384; X86-NOBMI-NEXT:    andl %esi, %eax
385; X86-NOBMI-NEXT:    popl %esi
386; X86-NOBMI-NEXT:    retl
387;
388; X86-BMI1-LABEL: bextr32_a4_commutative:
389; X86-BMI1:       # %bb.0:
390; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
391; X86-BMI1-NEXT:    shll $8, %eax
392; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
393; X86-BMI1-NEXT:    orl %eax, %ecx
394; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
395; X86-BMI1-NEXT:    retl
396;
397; X86-BMI2-LABEL: bextr32_a4_commutative:
398; X86-BMI2:       # %bb.0:
399; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
400; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
401; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
402; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
403; X86-BMI2-NEXT:    retl
404;
405; X64-NOBMI-LABEL: bextr32_a4_commutative:
406; X64-NOBMI:       # %bb.0:
407; X64-NOBMI-NEXT:    movl %esi, %ecx
408; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
409; X64-NOBMI-NEXT:    shrl %cl, %edi
410; X64-NOBMI-NEXT:    movl $1, %eax
411; X64-NOBMI-NEXT:    movl %edx, %ecx
412; X64-NOBMI-NEXT:    shll %cl, %eax
413; X64-NOBMI-NEXT:    decl %eax
414; X64-NOBMI-NEXT:    andl %edi, %eax
415; X64-NOBMI-NEXT:    retq
416;
417; X64-BMI1-LABEL: bextr32_a4_commutative:
418; X64-BMI1:       # %bb.0:
419; X64-BMI1-NEXT:    shll $8, %edx
420; X64-BMI1-NEXT:    movzbl %sil, %eax
421; X64-BMI1-NEXT:    orl %edx, %eax
422; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
423; X64-BMI1-NEXT:    retq
424;
425; X64-BMI2-LABEL: bextr32_a4_commutative:
426; X64-BMI2:       # %bb.0:
427; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
428; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
429; X64-BMI2-NEXT:    retq
430  %shifted = lshr i32 %val, %numskipbits
431  %onebit = shl i32 1, %numlowbits
432  %mask = add nsw i32 %onebit, -1
433  %masked = and i32 %shifted, %mask ; swapped order
434  ret i32 %masked
435}
436
437define i32 @bextr32_a5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
438; X86-NOBMI-LABEL: bextr32_a5_skipextrauses:
439; X86-NOBMI:       # %bb.0:
440; X86-NOBMI-NEXT:    pushl %edi
441; X86-NOBMI-NEXT:    pushl %esi
442; X86-NOBMI-NEXT:    pushl %eax
443; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
444; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
445; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
446; X86-NOBMI-NEXT:    movl %eax, %ecx
447; X86-NOBMI-NEXT:    shrl %cl, %edi
448; X86-NOBMI-NEXT:    movl $1, %esi
449; X86-NOBMI-NEXT:    movl %edx, %ecx
450; X86-NOBMI-NEXT:    shll %cl, %esi
451; X86-NOBMI-NEXT:    decl %esi
452; X86-NOBMI-NEXT:    andl %edi, %esi
453; X86-NOBMI-NEXT:    movl %eax, (%esp)
454; X86-NOBMI-NEXT:    calll use32@PLT
455; X86-NOBMI-NEXT:    movl %esi, %eax
456; X86-NOBMI-NEXT:    addl $4, %esp
457; X86-NOBMI-NEXT:    popl %esi
458; X86-NOBMI-NEXT:    popl %edi
459; X86-NOBMI-NEXT:    retl
460;
461; X86-BMI1-LABEL: bextr32_a5_skipextrauses:
462; X86-BMI1:       # %bb.0:
463; X86-BMI1-NEXT:    pushl %esi
464; X86-BMI1-NEXT:    subl $8, %esp
465; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
466; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
467; X86-BMI1-NEXT:    shll $8, %ecx
468; X86-BMI1-NEXT:    movzbl %al, %edx
469; X86-BMI1-NEXT:    orl %ecx, %edx
470; X86-BMI1-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
471; X86-BMI1-NEXT:    movl %eax, (%esp)
472; X86-BMI1-NEXT:    calll use32@PLT
473; X86-BMI1-NEXT:    movl %esi, %eax
474; X86-BMI1-NEXT:    addl $8, %esp
475; X86-BMI1-NEXT:    popl %esi
476; X86-BMI1-NEXT:    retl
477;
478; X86-BMI2-LABEL: bextr32_a5_skipextrauses:
479; X86-BMI2:       # %bb.0:
480; X86-BMI2-NEXT:    pushl %esi
481; X86-BMI2-NEXT:    subl $8, %esp
482; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
483; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
484; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
485; X86-BMI2-NEXT:    bzhil %eax, %edx, %esi
486; X86-BMI2-NEXT:    movl %ecx, (%esp)
487; X86-BMI2-NEXT:    calll use32@PLT
488; X86-BMI2-NEXT:    movl %esi, %eax
489; X86-BMI2-NEXT:    addl $8, %esp
490; X86-BMI2-NEXT:    popl %esi
491; X86-BMI2-NEXT:    retl
492;
493; X64-NOBMI-LABEL: bextr32_a5_skipextrauses:
494; X64-NOBMI:       # %bb.0:
495; X64-NOBMI-NEXT:    pushq %rbx
496; X64-NOBMI-NEXT:    movl %esi, %ecx
497; X64-NOBMI-NEXT:    shrl %cl, %edi
498; X64-NOBMI-NEXT:    movl $1, %ebx
499; X64-NOBMI-NEXT:    movl %edx, %ecx
500; X64-NOBMI-NEXT:    shll %cl, %ebx
501; X64-NOBMI-NEXT:    decl %ebx
502; X64-NOBMI-NEXT:    andl %edi, %ebx
503; X64-NOBMI-NEXT:    movl %esi, %edi
504; X64-NOBMI-NEXT:    callq use32@PLT
505; X64-NOBMI-NEXT:    movl %ebx, %eax
506; X64-NOBMI-NEXT:    popq %rbx
507; X64-NOBMI-NEXT:    retq
508;
509; X64-BMI1-LABEL: bextr32_a5_skipextrauses:
510; X64-BMI1:       # %bb.0:
511; X64-BMI1-NEXT:    pushq %rbx
512; X64-BMI1-NEXT:    shll $8, %edx
513; X64-BMI1-NEXT:    movzbl %sil, %eax
514; X64-BMI1-NEXT:    orl %edx, %eax
515; X64-BMI1-NEXT:    bextrl %eax, %edi, %ebx
516; X64-BMI1-NEXT:    movl %esi, %edi
517; X64-BMI1-NEXT:    callq use32@PLT
518; X64-BMI1-NEXT:    movl %ebx, %eax
519; X64-BMI1-NEXT:    popq %rbx
520; X64-BMI1-NEXT:    retq
521;
522; X64-BMI2-LABEL: bextr32_a5_skipextrauses:
523; X64-BMI2:       # %bb.0:
524; X64-BMI2-NEXT:    pushq %rbx
525; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
526; X64-BMI2-NEXT:    bzhil %edx, %eax, %ebx
527; X64-BMI2-NEXT:    movl %esi, %edi
528; X64-BMI2-NEXT:    callq use32@PLT
529; X64-BMI2-NEXT:    movl %ebx, %eax
530; X64-BMI2-NEXT:    popq %rbx
531; X64-BMI2-NEXT:    retq
532  %shifted = lshr i32 %val, %numskipbits
533  %onebit = shl i32 1, %numlowbits
534  %mask = add nsw i32 %onebit, -1
535  %masked = and i32 %mask, %shifted
536  call void @use32(i32 %numskipbits)
537  ret i32 %masked
538}
539
540; 64-bit
541
542define i64 @bextr64_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
543; X86-NOBMI-LABEL: bextr64_a0:
544; X86-NOBMI:       # %bb.0:
545; X86-NOBMI-NEXT:    pushl %edi
546; X86-NOBMI-NEXT:    pushl %esi
547; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
548; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
549; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
550; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
551; X86-NOBMI-NEXT:    movl %eax, %edi
552; X86-NOBMI-NEXT:    shrl %cl, %edi
553; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
554; X86-NOBMI-NEXT:    testb $32, %cl
555; X86-NOBMI-NEXT:    je .LBB7_2
556; X86-NOBMI-NEXT:  # %bb.1:
557; X86-NOBMI-NEXT:    movl %edi, %esi
558; X86-NOBMI-NEXT:    xorl %edi, %edi
559; X86-NOBMI-NEXT:  .LBB7_2:
560; X86-NOBMI-NEXT:    movl $1, %eax
561; X86-NOBMI-NEXT:    xorl %edx, %edx
562; X86-NOBMI-NEXT:    movb %ch, %cl
563; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
564; X86-NOBMI-NEXT:    shll %cl, %eax
565; X86-NOBMI-NEXT:    testb $32, %ch
566; X86-NOBMI-NEXT:    je .LBB7_4
567; X86-NOBMI-NEXT:  # %bb.3:
568; X86-NOBMI-NEXT:    movl %eax, %edx
569; X86-NOBMI-NEXT:    xorl %eax, %eax
570; X86-NOBMI-NEXT:  .LBB7_4:
571; X86-NOBMI-NEXT:    addl $-1, %eax
572; X86-NOBMI-NEXT:    adcl $-1, %edx
573; X86-NOBMI-NEXT:    andl %esi, %eax
574; X86-NOBMI-NEXT:    andl %edi, %edx
575; X86-NOBMI-NEXT:    popl %esi
576; X86-NOBMI-NEXT:    popl %edi
577; X86-NOBMI-NEXT:    retl
578;
579; X86-BMI1-LABEL: bextr64_a0:
580; X86-BMI1:       # %bb.0:
581; X86-BMI1-NEXT:    pushl %edi
582; X86-BMI1-NEXT:    pushl %esi
583; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
584; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
585; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
586; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
587; X86-BMI1-NEXT:    movl %eax, %edi
588; X86-BMI1-NEXT:    shrl %cl, %edi
589; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
590; X86-BMI1-NEXT:    testb $32, %cl
591; X86-BMI1-NEXT:    je .LBB7_2
592; X86-BMI1-NEXT:  # %bb.1:
593; X86-BMI1-NEXT:    movl %edi, %esi
594; X86-BMI1-NEXT:    xorl %edi, %edi
595; X86-BMI1-NEXT:  .LBB7_2:
596; X86-BMI1-NEXT:    movl $1, %eax
597; X86-BMI1-NEXT:    xorl %edx, %edx
598; X86-BMI1-NEXT:    movb %ch, %cl
599; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
600; X86-BMI1-NEXT:    shll %cl, %eax
601; X86-BMI1-NEXT:    testb $32, %ch
602; X86-BMI1-NEXT:    je .LBB7_4
603; X86-BMI1-NEXT:  # %bb.3:
604; X86-BMI1-NEXT:    movl %eax, %edx
605; X86-BMI1-NEXT:    xorl %eax, %eax
606; X86-BMI1-NEXT:  .LBB7_4:
607; X86-BMI1-NEXT:    addl $-1, %eax
608; X86-BMI1-NEXT:    adcl $-1, %edx
609; X86-BMI1-NEXT:    andl %esi, %eax
610; X86-BMI1-NEXT:    andl %edi, %edx
611; X86-BMI1-NEXT:    popl %esi
612; X86-BMI1-NEXT:    popl %edi
613; X86-BMI1-NEXT:    retl
614;
615; X86-BMI2-LABEL: bextr64_a0:
616; X86-BMI2:       # %bb.0:
617; X86-BMI2-NEXT:    pushl %ebx
618; X86-BMI2-NEXT:    pushl %edi
619; X86-BMI2-NEXT:    pushl %esi
620; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
621; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
622; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
623; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
624; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
625; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
626; X86-BMI2-NEXT:    testb $32, %cl
627; X86-BMI2-NEXT:    je .LBB7_2
628; X86-BMI2-NEXT:  # %bb.1:
629; X86-BMI2-NEXT:    movl %edi, %esi
630; X86-BMI2-NEXT:    xorl %edi, %edi
631; X86-BMI2-NEXT:  .LBB7_2:
632; X86-BMI2-NEXT:    movl $1, %eax
633; X86-BMI2-NEXT:    xorl %edx, %edx
634; X86-BMI2-NEXT:    movl %ebx, %ecx
635; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
636; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
637; X86-BMI2-NEXT:    testb $32, %bl
638; X86-BMI2-NEXT:    je .LBB7_4
639; X86-BMI2-NEXT:  # %bb.3:
640; X86-BMI2-NEXT:    movl %eax, %edx
641; X86-BMI2-NEXT:    xorl %eax, %eax
642; X86-BMI2-NEXT:  .LBB7_4:
643; X86-BMI2-NEXT:    addl $-1, %eax
644; X86-BMI2-NEXT:    adcl $-1, %edx
645; X86-BMI2-NEXT:    andl %esi, %eax
646; X86-BMI2-NEXT:    andl %edi, %edx
647; X86-BMI2-NEXT:    popl %esi
648; X86-BMI2-NEXT:    popl %edi
649; X86-BMI2-NEXT:    popl %ebx
650; X86-BMI2-NEXT:    retl
651;
652; X64-NOBMI-LABEL: bextr64_a0:
653; X64-NOBMI:       # %bb.0:
654; X64-NOBMI-NEXT:    movq %rsi, %rcx
655; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
656; X64-NOBMI-NEXT:    shrq %cl, %rdi
657; X64-NOBMI-NEXT:    movl $1, %eax
658; X64-NOBMI-NEXT:    movl %edx, %ecx
659; X64-NOBMI-NEXT:    shlq %cl, %rax
660; X64-NOBMI-NEXT:    decq %rax
661; X64-NOBMI-NEXT:    andq %rdi, %rax
662; X64-NOBMI-NEXT:    retq
663;
664; X64-BMI1-LABEL: bextr64_a0:
665; X64-BMI1:       # %bb.0:
666; X64-BMI1-NEXT:    shll $8, %edx
667; X64-BMI1-NEXT:    movzbl %sil, %eax
668; X64-BMI1-NEXT:    orl %edx, %eax
669; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
670; X64-BMI1-NEXT:    retq
671;
672; X64-BMI2-LABEL: bextr64_a0:
673; X64-BMI2:       # %bb.0:
674; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
675; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
676; X64-BMI2-NEXT:    retq
677  %shifted = lshr i64 %val, %numskipbits
678  %onebit = shl i64 1, %numlowbits
679  %mask = add nsw i64 %onebit, -1
680  %masked = and i64 %mask, %shifted
681  ret i64 %masked
682}
683
684define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
685; X86-NOBMI-LABEL: bextr64_a0_arithmetic:
686; X86-NOBMI:       # %bb.0:
687; X86-NOBMI-NEXT:    pushl %edi
688; X86-NOBMI-NEXT:    pushl %esi
689; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
690; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
691; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
692; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
693; X86-NOBMI-NEXT:    movl %eax, %esi
694; X86-NOBMI-NEXT:    sarl %cl, %esi
695; X86-NOBMI-NEXT:    shrdl %cl, %eax, %edi
696; X86-NOBMI-NEXT:    testb $32, %cl
697; X86-NOBMI-NEXT:    je .LBB8_2
698; X86-NOBMI-NEXT:  # %bb.1:
699; X86-NOBMI-NEXT:    sarl $31, %eax
700; X86-NOBMI-NEXT:    movl %esi, %edi
701; X86-NOBMI-NEXT:    movl %eax, %esi
702; X86-NOBMI-NEXT:  .LBB8_2:
703; X86-NOBMI-NEXT:    movl $1, %eax
704; X86-NOBMI-NEXT:    xorl %edx, %edx
705; X86-NOBMI-NEXT:    movb %ch, %cl
706; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
707; X86-NOBMI-NEXT:    shll %cl, %eax
708; X86-NOBMI-NEXT:    testb $32, %ch
709; X86-NOBMI-NEXT:    je .LBB8_4
710; X86-NOBMI-NEXT:  # %bb.3:
711; X86-NOBMI-NEXT:    movl %eax, %edx
712; X86-NOBMI-NEXT:    xorl %eax, %eax
713; X86-NOBMI-NEXT:  .LBB8_4:
714; X86-NOBMI-NEXT:    addl $-1, %eax
715; X86-NOBMI-NEXT:    adcl $-1, %edx
716; X86-NOBMI-NEXT:    andl %edi, %eax
717; X86-NOBMI-NEXT:    andl %esi, %edx
718; X86-NOBMI-NEXT:    popl %esi
719; X86-NOBMI-NEXT:    popl %edi
720; X86-NOBMI-NEXT:    retl
721;
722; X86-BMI1-LABEL: bextr64_a0_arithmetic:
723; X86-BMI1:       # %bb.0:
724; X86-BMI1-NEXT:    pushl %edi
725; X86-BMI1-NEXT:    pushl %esi
726; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
727; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
728; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
729; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
730; X86-BMI1-NEXT:    movl %eax, %esi
731; X86-BMI1-NEXT:    sarl %cl, %esi
732; X86-BMI1-NEXT:    shrdl %cl, %eax, %edi
733; X86-BMI1-NEXT:    testb $32, %cl
734; X86-BMI1-NEXT:    je .LBB8_2
735; X86-BMI1-NEXT:  # %bb.1:
736; X86-BMI1-NEXT:    sarl $31, %eax
737; X86-BMI1-NEXT:    movl %esi, %edi
738; X86-BMI1-NEXT:    movl %eax, %esi
739; X86-BMI1-NEXT:  .LBB8_2:
740; X86-BMI1-NEXT:    movl $1, %eax
741; X86-BMI1-NEXT:    xorl %edx, %edx
742; X86-BMI1-NEXT:    movb %ch, %cl
743; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
744; X86-BMI1-NEXT:    shll %cl, %eax
745; X86-BMI1-NEXT:    testb $32, %ch
746; X86-BMI1-NEXT:    je .LBB8_4
747; X86-BMI1-NEXT:  # %bb.3:
748; X86-BMI1-NEXT:    movl %eax, %edx
749; X86-BMI1-NEXT:    xorl %eax, %eax
750; X86-BMI1-NEXT:  .LBB8_4:
751; X86-BMI1-NEXT:    addl $-1, %eax
752; X86-BMI1-NEXT:    adcl $-1, %edx
753; X86-BMI1-NEXT:    andl %edi, %eax
754; X86-BMI1-NEXT:    andl %esi, %edx
755; X86-BMI1-NEXT:    popl %esi
756; X86-BMI1-NEXT:    popl %edi
757; X86-BMI1-NEXT:    retl
758;
759; X86-BMI2-LABEL: bextr64_a0_arithmetic:
760; X86-BMI2:       # %bb.0:
761; X86-BMI2-NEXT:    pushl %ebx
762; X86-BMI2-NEXT:    pushl %edi
763; X86-BMI2-NEXT:    pushl %esi
764; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
765; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
766; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
767; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
768; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
769; X86-BMI2-NEXT:    sarxl %ecx, %eax, %edi
770; X86-BMI2-NEXT:    testb $32, %cl
771; X86-BMI2-NEXT:    je .LBB8_2
772; X86-BMI2-NEXT:  # %bb.1:
773; X86-BMI2-NEXT:    sarl $31, %eax
774; X86-BMI2-NEXT:    movl %edi, %esi
775; X86-BMI2-NEXT:    movl %eax, %edi
776; X86-BMI2-NEXT:  .LBB8_2:
777; X86-BMI2-NEXT:    movl $1, %eax
778; X86-BMI2-NEXT:    xorl %edx, %edx
779; X86-BMI2-NEXT:    movl %ebx, %ecx
780; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
781; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
782; X86-BMI2-NEXT:    testb $32, %bl
783; X86-BMI2-NEXT:    je .LBB8_4
784; X86-BMI2-NEXT:  # %bb.3:
785; X86-BMI2-NEXT:    movl %eax, %edx
786; X86-BMI2-NEXT:    xorl %eax, %eax
787; X86-BMI2-NEXT:  .LBB8_4:
788; X86-BMI2-NEXT:    addl $-1, %eax
789; X86-BMI2-NEXT:    adcl $-1, %edx
790; X86-BMI2-NEXT:    andl %esi, %eax
791; X86-BMI2-NEXT:    andl %edi, %edx
792; X86-BMI2-NEXT:    popl %esi
793; X86-BMI2-NEXT:    popl %edi
794; X86-BMI2-NEXT:    popl %ebx
795; X86-BMI2-NEXT:    retl
796;
797; X64-NOBMI-LABEL: bextr64_a0_arithmetic:
798; X64-NOBMI:       # %bb.0:
799; X64-NOBMI-NEXT:    movq %rsi, %rcx
800; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
801; X64-NOBMI-NEXT:    sarq %cl, %rdi
802; X64-NOBMI-NEXT:    movl $1, %eax
803; X64-NOBMI-NEXT:    movl %edx, %ecx
804; X64-NOBMI-NEXT:    shlq %cl, %rax
805; X64-NOBMI-NEXT:    decq %rax
806; X64-NOBMI-NEXT:    andq %rdi, %rax
807; X64-NOBMI-NEXT:    retq
808;
809; X64-BMI1-LABEL: bextr64_a0_arithmetic:
810; X64-BMI1:       # %bb.0:
811; X64-BMI1-NEXT:    movq %rsi, %rcx
812; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
813; X64-BMI1-NEXT:    sarq %cl, %rdi
814; X64-BMI1-NEXT:    shll $8, %edx
815; X64-BMI1-NEXT:    bextrq %rdx, %rdi, %rax
816; X64-BMI1-NEXT:    retq
817;
818; X64-BMI2-LABEL: bextr64_a0_arithmetic:
819; X64-BMI2:       # %bb.0:
820; X64-BMI2-NEXT:    sarxq %rsi, %rdi, %rax
821; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
822; X64-BMI2-NEXT:    retq
823  %shifted = ashr i64 %val, %numskipbits
824  %onebit = shl i64 1, %numlowbits
825  %mask = add nsw i64 %onebit, -1
826  %masked = and i64 %mask, %shifted
827  ret i64 %masked
828}
829
830define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
831; X86-NOBMI-LABEL: bextr64_a1_indexzext:
832; X86-NOBMI:       # %bb.0:
833; X86-NOBMI-NEXT:    pushl %edi
834; X86-NOBMI-NEXT:    pushl %esi
835; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
836; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
837; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
838; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
839; X86-NOBMI-NEXT:    movl %eax, %edi
840; X86-NOBMI-NEXT:    shrl %cl, %edi
841; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
842; X86-NOBMI-NEXT:    testb $32, %cl
843; X86-NOBMI-NEXT:    je .LBB9_2
844; X86-NOBMI-NEXT:  # %bb.1:
845; X86-NOBMI-NEXT:    movl %edi, %esi
846; X86-NOBMI-NEXT:    xorl %edi, %edi
847; X86-NOBMI-NEXT:  .LBB9_2:
848; X86-NOBMI-NEXT:    movl $1, %eax
849; X86-NOBMI-NEXT:    xorl %edx, %edx
850; X86-NOBMI-NEXT:    movb %ch, %cl
851; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
852; X86-NOBMI-NEXT:    shll %cl, %eax
853; X86-NOBMI-NEXT:    testb $32, %ch
854; X86-NOBMI-NEXT:    je .LBB9_4
855; X86-NOBMI-NEXT:  # %bb.3:
856; X86-NOBMI-NEXT:    movl %eax, %edx
857; X86-NOBMI-NEXT:    xorl %eax, %eax
858; X86-NOBMI-NEXT:  .LBB9_4:
859; X86-NOBMI-NEXT:    addl $-1, %eax
860; X86-NOBMI-NEXT:    adcl $-1, %edx
861; X86-NOBMI-NEXT:    andl %esi, %eax
862; X86-NOBMI-NEXT:    andl %edi, %edx
863; X86-NOBMI-NEXT:    popl %esi
864; X86-NOBMI-NEXT:    popl %edi
865; X86-NOBMI-NEXT:    retl
866;
867; X86-BMI1-LABEL: bextr64_a1_indexzext:
868; X86-BMI1:       # %bb.0:
869; X86-BMI1-NEXT:    pushl %edi
870; X86-BMI1-NEXT:    pushl %esi
871; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
872; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
873; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
874; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
875; X86-BMI1-NEXT:    movl %eax, %edi
876; X86-BMI1-NEXT:    shrl %cl, %edi
877; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
878; X86-BMI1-NEXT:    testb $32, %cl
879; X86-BMI1-NEXT:    je .LBB9_2
880; X86-BMI1-NEXT:  # %bb.1:
881; X86-BMI1-NEXT:    movl %edi, %esi
882; X86-BMI1-NEXT:    xorl %edi, %edi
883; X86-BMI1-NEXT:  .LBB9_2:
884; X86-BMI1-NEXT:    movl $1, %eax
885; X86-BMI1-NEXT:    xorl %edx, %edx
886; X86-BMI1-NEXT:    movb %ch, %cl
887; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
888; X86-BMI1-NEXT:    shll %cl, %eax
889; X86-BMI1-NEXT:    testb $32, %ch
890; X86-BMI1-NEXT:    je .LBB9_4
891; X86-BMI1-NEXT:  # %bb.3:
892; X86-BMI1-NEXT:    movl %eax, %edx
893; X86-BMI1-NEXT:    xorl %eax, %eax
894; X86-BMI1-NEXT:  .LBB9_4:
895; X86-BMI1-NEXT:    addl $-1, %eax
896; X86-BMI1-NEXT:    adcl $-1, %edx
897; X86-BMI1-NEXT:    andl %esi, %eax
898; X86-BMI1-NEXT:    andl %edi, %edx
899; X86-BMI1-NEXT:    popl %esi
900; X86-BMI1-NEXT:    popl %edi
901; X86-BMI1-NEXT:    retl
902;
903; X86-BMI2-LABEL: bextr64_a1_indexzext:
904; X86-BMI2:       # %bb.0:
905; X86-BMI2-NEXT:    pushl %ebx
906; X86-BMI2-NEXT:    pushl %edi
907; X86-BMI2-NEXT:    pushl %esi
908; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
909; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
910; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
911; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
912; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
913; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
914; X86-BMI2-NEXT:    testb $32, %cl
915; X86-BMI2-NEXT:    je .LBB9_2
916; X86-BMI2-NEXT:  # %bb.1:
917; X86-BMI2-NEXT:    movl %edi, %esi
918; X86-BMI2-NEXT:    xorl %edi, %edi
919; X86-BMI2-NEXT:  .LBB9_2:
920; X86-BMI2-NEXT:    movl $1, %eax
921; X86-BMI2-NEXT:    xorl %edx, %edx
922; X86-BMI2-NEXT:    movl %ebx, %ecx
923; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
924; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
925; X86-BMI2-NEXT:    testb $32, %bl
926; X86-BMI2-NEXT:    je .LBB9_4
927; X86-BMI2-NEXT:  # %bb.3:
928; X86-BMI2-NEXT:    movl %eax, %edx
929; X86-BMI2-NEXT:    xorl %eax, %eax
930; X86-BMI2-NEXT:  .LBB9_4:
931; X86-BMI2-NEXT:    addl $-1, %eax
932; X86-BMI2-NEXT:    adcl $-1, %edx
933; X86-BMI2-NEXT:    andl %esi, %eax
934; X86-BMI2-NEXT:    andl %edi, %edx
935; X86-BMI2-NEXT:    popl %esi
936; X86-BMI2-NEXT:    popl %edi
937; X86-BMI2-NEXT:    popl %ebx
938; X86-BMI2-NEXT:    retl
939;
940; X64-NOBMI-LABEL: bextr64_a1_indexzext:
941; X64-NOBMI:       # %bb.0:
942; X64-NOBMI-NEXT:    movl %esi, %ecx
943; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
944; X64-NOBMI-NEXT:    shrq %cl, %rdi
945; X64-NOBMI-NEXT:    movl $1, %eax
946; X64-NOBMI-NEXT:    movl %edx, %ecx
947; X64-NOBMI-NEXT:    shlq %cl, %rax
948; X64-NOBMI-NEXT:    decq %rax
949; X64-NOBMI-NEXT:    andq %rdi, %rax
950; X64-NOBMI-NEXT:    retq
951;
952; X64-BMI1-LABEL: bextr64_a1_indexzext:
953; X64-BMI1:       # %bb.0:
954; X64-BMI1-NEXT:    # kill: def $edx killed $edx def $rdx
955; X64-BMI1-NEXT:    shll $8, %edx
956; X64-BMI1-NEXT:    orl %esi, %edx
957; X64-BMI1-NEXT:    bextrq %rdx, %rdi, %rax
958; X64-BMI1-NEXT:    retq
959;
960; X64-BMI2-LABEL: bextr64_a1_indexzext:
961; X64-BMI2:       # %bb.0:
962; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
963; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
964; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
965; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
966; X64-BMI2-NEXT:    retq
967  %skip = zext i8 %numskipbits to i64
968  %shifted = lshr i64 %val, %skip
969  %conv = zext i8 %numlowbits to i64
970  %onebit = shl i64 1, %conv
971  %mask = add nsw i64 %onebit, -1
972  %masked = and i64 %mask, %shifted
973  ret i64 %masked
974}
975
976define i64 @bextr64_a2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {
977; X86-NOBMI-LABEL: bextr64_a2_load:
978; X86-NOBMI:       # %bb.0:
979; X86-NOBMI-NEXT:    pushl %edi
980; X86-NOBMI-NEXT:    pushl %esi
981; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
982; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
983; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
984; X86-NOBMI-NEXT:    movl (%eax), %esi
985; X86-NOBMI-NEXT:    movl 4(%eax), %eax
986; X86-NOBMI-NEXT:    movl %eax, %edi
987; X86-NOBMI-NEXT:    shrl %cl, %edi
988; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
989; X86-NOBMI-NEXT:    testb $32, %cl
990; X86-NOBMI-NEXT:    je .LBB10_2
991; X86-NOBMI-NEXT:  # %bb.1:
992; X86-NOBMI-NEXT:    movl %edi, %esi
993; X86-NOBMI-NEXT:    xorl %edi, %edi
994; X86-NOBMI-NEXT:  .LBB10_2:
995; X86-NOBMI-NEXT:    movl $1, %eax
996; X86-NOBMI-NEXT:    xorl %edx, %edx
997; X86-NOBMI-NEXT:    movb %ch, %cl
998; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
999; X86-NOBMI-NEXT:    shll %cl, %eax
1000; X86-NOBMI-NEXT:    testb $32, %ch
1001; X86-NOBMI-NEXT:    je .LBB10_4
1002; X86-NOBMI-NEXT:  # %bb.3:
1003; X86-NOBMI-NEXT:    movl %eax, %edx
1004; X86-NOBMI-NEXT:    xorl %eax, %eax
1005; X86-NOBMI-NEXT:  .LBB10_4:
1006; X86-NOBMI-NEXT:    addl $-1, %eax
1007; X86-NOBMI-NEXT:    adcl $-1, %edx
1008; X86-NOBMI-NEXT:    andl %esi, %eax
1009; X86-NOBMI-NEXT:    andl %edi, %edx
1010; X86-NOBMI-NEXT:    popl %esi
1011; X86-NOBMI-NEXT:    popl %edi
1012; X86-NOBMI-NEXT:    retl
1013;
1014; X86-BMI1-LABEL: bextr64_a2_load:
1015; X86-BMI1:       # %bb.0:
1016; X86-BMI1-NEXT:    pushl %edi
1017; X86-BMI1-NEXT:    pushl %esi
1018; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
1019; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
1020; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1021; X86-BMI1-NEXT:    movl (%eax), %esi
1022; X86-BMI1-NEXT:    movl 4(%eax), %eax
1023; X86-BMI1-NEXT:    movl %eax, %edi
1024; X86-BMI1-NEXT:    shrl %cl, %edi
1025; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
1026; X86-BMI1-NEXT:    testb $32, %cl
1027; X86-BMI1-NEXT:    je .LBB10_2
1028; X86-BMI1-NEXT:  # %bb.1:
1029; X86-BMI1-NEXT:    movl %edi, %esi
1030; X86-BMI1-NEXT:    xorl %edi, %edi
1031; X86-BMI1-NEXT:  .LBB10_2:
1032; X86-BMI1-NEXT:    movl $1, %eax
1033; X86-BMI1-NEXT:    xorl %edx, %edx
1034; X86-BMI1-NEXT:    movb %ch, %cl
1035; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
1036; X86-BMI1-NEXT:    shll %cl, %eax
1037; X86-BMI1-NEXT:    testb $32, %ch
1038; X86-BMI1-NEXT:    je .LBB10_4
1039; X86-BMI1-NEXT:  # %bb.3:
1040; X86-BMI1-NEXT:    movl %eax, %edx
1041; X86-BMI1-NEXT:    xorl %eax, %eax
1042; X86-BMI1-NEXT:  .LBB10_4:
1043; X86-BMI1-NEXT:    addl $-1, %eax
1044; X86-BMI1-NEXT:    adcl $-1, %edx
1045; X86-BMI1-NEXT:    andl %esi, %eax
1046; X86-BMI1-NEXT:    andl %edi, %edx
1047; X86-BMI1-NEXT:    popl %esi
1048; X86-BMI1-NEXT:    popl %edi
1049; X86-BMI1-NEXT:    retl
1050;
1051; X86-BMI2-LABEL: bextr64_a2_load:
1052; X86-BMI2:       # %bb.0:
1053; X86-BMI2-NEXT:    pushl %ebx
1054; X86-BMI2-NEXT:    pushl %edi
1055; X86-BMI2-NEXT:    pushl %esi
1056; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1057; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1058; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1059; X86-BMI2-NEXT:    movl (%eax), %esi
1060; X86-BMI2-NEXT:    movl 4(%eax), %eax
1061; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
1062; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
1063; X86-BMI2-NEXT:    testb $32, %cl
1064; X86-BMI2-NEXT:    je .LBB10_2
1065; X86-BMI2-NEXT:  # %bb.1:
1066; X86-BMI2-NEXT:    movl %edi, %esi
1067; X86-BMI2-NEXT:    xorl %edi, %edi
1068; X86-BMI2-NEXT:  .LBB10_2:
1069; X86-BMI2-NEXT:    movl $1, %eax
1070; X86-BMI2-NEXT:    xorl %edx, %edx
1071; X86-BMI2-NEXT:    movl %ebx, %ecx
1072; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
1073; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
1074; X86-BMI2-NEXT:    testb $32, %bl
1075; X86-BMI2-NEXT:    je .LBB10_4
1076; X86-BMI2-NEXT:  # %bb.3:
1077; X86-BMI2-NEXT:    movl %eax, %edx
1078; X86-BMI2-NEXT:    xorl %eax, %eax
1079; X86-BMI2-NEXT:  .LBB10_4:
1080; X86-BMI2-NEXT:    addl $-1, %eax
1081; X86-BMI2-NEXT:    adcl $-1, %edx
1082; X86-BMI2-NEXT:    andl %esi, %eax
1083; X86-BMI2-NEXT:    andl %edi, %edx
1084; X86-BMI2-NEXT:    popl %esi
1085; X86-BMI2-NEXT:    popl %edi
1086; X86-BMI2-NEXT:    popl %ebx
1087; X86-BMI2-NEXT:    retl
1088;
1089; X64-NOBMI-LABEL: bextr64_a2_load:
1090; X64-NOBMI:       # %bb.0:
1091; X64-NOBMI-NEXT:    movq %rsi, %rcx
1092; X64-NOBMI-NEXT:    movq (%rdi), %rsi
1093; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1094; X64-NOBMI-NEXT:    shrq %cl, %rsi
1095; X64-NOBMI-NEXT:    movl $1, %eax
1096; X64-NOBMI-NEXT:    movl %edx, %ecx
1097; X64-NOBMI-NEXT:    shlq %cl, %rax
1098; X64-NOBMI-NEXT:    decq %rax
1099; X64-NOBMI-NEXT:    andq %rsi, %rax
1100; X64-NOBMI-NEXT:    retq
1101;
1102; X64-BMI1-LABEL: bextr64_a2_load:
1103; X64-BMI1:       # %bb.0:
1104; X64-BMI1-NEXT:    shll $8, %edx
1105; X64-BMI1-NEXT:    movzbl %sil, %eax
1106; X64-BMI1-NEXT:    orl %edx, %eax
1107; X64-BMI1-NEXT:    bextrq %rax, (%rdi), %rax
1108; X64-BMI1-NEXT:    retq
1109;
1110; X64-BMI2-LABEL: bextr64_a2_load:
1111; X64-BMI2:       # %bb.0:
1112; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1113; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1114; X64-BMI2-NEXT:    retq
1115  %val = load i64, ptr %w
1116  %shifted = lshr i64 %val, %numskipbits
1117  %onebit = shl i64 1, %numlowbits
1118  %mask = add nsw i64 %onebit, -1
1119  %masked = and i64 %mask, %shifted
1120  ret i64 %masked
1121}
1122
1123define i64 @bextr64_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
1124; X86-NOBMI-LABEL: bextr64_a3_load_indexzext:
1125; X86-NOBMI:       # %bb.0:
1126; X86-NOBMI-NEXT:    pushl %edi
1127; X86-NOBMI-NEXT:    pushl %esi
1128; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
1129; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1130; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1131; X86-NOBMI-NEXT:    movl (%eax), %esi
1132; X86-NOBMI-NEXT:    movl 4(%eax), %eax
1133; X86-NOBMI-NEXT:    movl %eax, %edi
1134; X86-NOBMI-NEXT:    shrl %cl, %edi
1135; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
1136; X86-NOBMI-NEXT:    testb $32, %cl
1137; X86-NOBMI-NEXT:    je .LBB11_2
1138; X86-NOBMI-NEXT:  # %bb.1:
1139; X86-NOBMI-NEXT:    movl %edi, %esi
1140; X86-NOBMI-NEXT:    xorl %edi, %edi
1141; X86-NOBMI-NEXT:  .LBB11_2:
1142; X86-NOBMI-NEXT:    movl $1, %eax
1143; X86-NOBMI-NEXT:    xorl %edx, %edx
1144; X86-NOBMI-NEXT:    movb %ch, %cl
1145; X86-NOBMI-NEXT:    shldl %cl, %eax, %edx
1146; X86-NOBMI-NEXT:    shll %cl, %eax
1147; X86-NOBMI-NEXT:    testb $32, %ch
1148; X86-NOBMI-NEXT:    je .LBB11_4
1149; X86-NOBMI-NEXT:  # %bb.3:
1150; X86-NOBMI-NEXT:    movl %eax, %edx
1151; X86-NOBMI-NEXT:    xorl %eax, %eax
1152; X86-NOBMI-NEXT:  .LBB11_4:
1153; X86-NOBMI-NEXT:    addl $-1, %eax
1154; X86-NOBMI-NEXT:    adcl $-1, %edx
1155; X86-NOBMI-NEXT:    andl %esi, %eax
1156; X86-NOBMI-NEXT:    andl %edi, %edx
1157; X86-NOBMI-NEXT:    popl %esi
1158; X86-NOBMI-NEXT:    popl %edi
1159; X86-NOBMI-NEXT:    retl
1160;
1161; X86-BMI1-LABEL: bextr64_a3_load_indexzext:
1162; X86-BMI1:       # %bb.0:
1163; X86-BMI1-NEXT:    pushl %edi
1164; X86-BMI1-NEXT:    pushl %esi
1165; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
1166; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
1167; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1168; X86-BMI1-NEXT:    movl (%eax), %esi
1169; X86-BMI1-NEXT:    movl 4(%eax), %eax
1170; X86-BMI1-NEXT:    movl %eax, %edi
1171; X86-BMI1-NEXT:    shrl %cl, %edi
1172; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
1173; X86-BMI1-NEXT:    testb $32, %cl
1174; X86-BMI1-NEXT:    je .LBB11_2
1175; X86-BMI1-NEXT:  # %bb.1:
1176; X86-BMI1-NEXT:    movl %edi, %esi
1177; X86-BMI1-NEXT:    xorl %edi, %edi
1178; X86-BMI1-NEXT:  .LBB11_2:
1179; X86-BMI1-NEXT:    movl $1, %eax
1180; X86-BMI1-NEXT:    xorl %edx, %edx
1181; X86-BMI1-NEXT:    movb %ch, %cl
1182; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
1183; X86-BMI1-NEXT:    shll %cl, %eax
1184; X86-BMI1-NEXT:    testb $32, %ch
1185; X86-BMI1-NEXT:    je .LBB11_4
1186; X86-BMI1-NEXT:  # %bb.3:
1187; X86-BMI1-NEXT:    movl %eax, %edx
1188; X86-BMI1-NEXT:    xorl %eax, %eax
1189; X86-BMI1-NEXT:  .LBB11_4:
1190; X86-BMI1-NEXT:    addl $-1, %eax
1191; X86-BMI1-NEXT:    adcl $-1, %edx
1192; X86-BMI1-NEXT:    andl %esi, %eax
1193; X86-BMI1-NEXT:    andl %edi, %edx
1194; X86-BMI1-NEXT:    popl %esi
1195; X86-BMI1-NEXT:    popl %edi
1196; X86-BMI1-NEXT:    retl
1197;
1198; X86-BMI2-LABEL: bextr64_a3_load_indexzext:
1199; X86-BMI2:       # %bb.0:
1200; X86-BMI2-NEXT:    pushl %ebx
1201; X86-BMI2-NEXT:    pushl %edi
1202; X86-BMI2-NEXT:    pushl %esi
1203; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1204; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1205; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1206; X86-BMI2-NEXT:    movl (%eax), %esi
1207; X86-BMI2-NEXT:    movl 4(%eax), %eax
1208; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
1209; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
1210; X86-BMI2-NEXT:    testb $32, %cl
1211; X86-BMI2-NEXT:    je .LBB11_2
1212; X86-BMI2-NEXT:  # %bb.1:
1213; X86-BMI2-NEXT:    movl %edi, %esi
1214; X86-BMI2-NEXT:    xorl %edi, %edi
1215; X86-BMI2-NEXT:  .LBB11_2:
1216; X86-BMI2-NEXT:    movl $1, %eax
1217; X86-BMI2-NEXT:    xorl %edx, %edx
1218; X86-BMI2-NEXT:    movl %ebx, %ecx
1219; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
1220; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
1221; X86-BMI2-NEXT:    testb $32, %bl
1222; X86-BMI2-NEXT:    je .LBB11_4
1223; X86-BMI2-NEXT:  # %bb.3:
1224; X86-BMI2-NEXT:    movl %eax, %edx
1225; X86-BMI2-NEXT:    xorl %eax, %eax
1226; X86-BMI2-NEXT:  .LBB11_4:
1227; X86-BMI2-NEXT:    addl $-1, %eax
1228; X86-BMI2-NEXT:    adcl $-1, %edx
1229; X86-BMI2-NEXT:    andl %esi, %eax
1230; X86-BMI2-NEXT:    andl %edi, %edx
1231; X86-BMI2-NEXT:    popl %esi
1232; X86-BMI2-NEXT:    popl %edi
1233; X86-BMI2-NEXT:    popl %ebx
1234; X86-BMI2-NEXT:    retl
1235;
1236; X64-NOBMI-LABEL: bextr64_a3_load_indexzext:
1237; X64-NOBMI:       # %bb.0:
1238; X64-NOBMI-NEXT:    movl %esi, %ecx
1239; X64-NOBMI-NEXT:    movq (%rdi), %rsi
1240; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
1241; X64-NOBMI-NEXT:    shrq %cl, %rsi
1242; X64-NOBMI-NEXT:    movl $1, %eax
1243; X64-NOBMI-NEXT:    movl %edx, %ecx
1244; X64-NOBMI-NEXT:    shlq %cl, %rax
1245; X64-NOBMI-NEXT:    decq %rax
1246; X64-NOBMI-NEXT:    andq %rsi, %rax
1247; X64-NOBMI-NEXT:    retq
1248;
1249; X64-BMI1-LABEL: bextr64_a3_load_indexzext:
1250; X64-BMI1:       # %bb.0:
1251; X64-BMI1-NEXT:    # kill: def $edx killed $edx def $rdx
1252; X64-BMI1-NEXT:    shll $8, %edx
1253; X64-BMI1-NEXT:    orl %esi, %edx
1254; X64-BMI1-NEXT:    bextrq %rdx, (%rdi), %rax
1255; X64-BMI1-NEXT:    retq
1256;
1257; X64-BMI2-LABEL: bextr64_a3_load_indexzext:
1258; X64-BMI2:       # %bb.0:
1259; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
1260; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
1261; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
1262; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1263; X64-BMI2-NEXT:    retq
1264  %val = load i64, ptr %w
1265  %skip = zext i8 %numskipbits to i64
1266  %shifted = lshr i64 %val, %skip
1267  %conv = zext i8 %numlowbits to i64
1268  %onebit = shl i64 1, %conv
1269  %mask = add nsw i64 %onebit, -1
1270  %masked = and i64 %mask, %shifted
1271  ret i64 %masked
1272}
1273
1274define i64 @bextr64_a4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1275; X86-NOBMI-LABEL: bextr64_a4_commutative:
1276; X86-NOBMI:       # %bb.0:
1277; X86-NOBMI-NEXT:    pushl %edi
1278; X86-NOBMI-NEXT:    pushl %esi
1279; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
1280; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
1281; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1282; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1283; X86-NOBMI-NEXT:    movl %esi, %edx
1284; X86-NOBMI-NEXT:    shrl %cl, %edx
1285; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
1286; X86-NOBMI-NEXT:    testb $32, %cl
1287; X86-NOBMI-NEXT:    je .LBB12_2
1288; X86-NOBMI-NEXT:  # %bb.1:
1289; X86-NOBMI-NEXT:    movl %edx, %eax
1290; X86-NOBMI-NEXT:    xorl %edx, %edx
1291; X86-NOBMI-NEXT:  .LBB12_2:
1292; X86-NOBMI-NEXT:    movl $1, %esi
1293; X86-NOBMI-NEXT:    xorl %edi, %edi
1294; X86-NOBMI-NEXT:    movb %ch, %cl
1295; X86-NOBMI-NEXT:    shldl %cl, %esi, %edi
1296; X86-NOBMI-NEXT:    shll %cl, %esi
1297; X86-NOBMI-NEXT:    testb $32, %ch
1298; X86-NOBMI-NEXT:    je .LBB12_4
1299; X86-NOBMI-NEXT:  # %bb.3:
1300; X86-NOBMI-NEXT:    movl %esi, %edi
1301; X86-NOBMI-NEXT:    xorl %esi, %esi
1302; X86-NOBMI-NEXT:  .LBB12_4:
1303; X86-NOBMI-NEXT:    addl $-1, %esi
1304; X86-NOBMI-NEXT:    adcl $-1, %edi
1305; X86-NOBMI-NEXT:    andl %esi, %eax
1306; X86-NOBMI-NEXT:    andl %edi, %edx
1307; X86-NOBMI-NEXT:    popl %esi
1308; X86-NOBMI-NEXT:    popl %edi
1309; X86-NOBMI-NEXT:    retl
1310;
1311; X86-BMI1-LABEL: bextr64_a4_commutative:
1312; X86-BMI1:       # %bb.0:
1313; X86-BMI1-NEXT:    pushl %edi
1314; X86-BMI1-NEXT:    pushl %esi
1315; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %ch
1316; X86-BMI1-NEXT:    movb {{[0-9]+}}(%esp), %cl
1317; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1318; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
1319; X86-BMI1-NEXT:    movl %esi, %edx
1320; X86-BMI1-NEXT:    shrl %cl, %edx
1321; X86-BMI1-NEXT:    shrdl %cl, %esi, %eax
1322; X86-BMI1-NEXT:    testb $32, %cl
1323; X86-BMI1-NEXT:    je .LBB12_2
1324; X86-BMI1-NEXT:  # %bb.1:
1325; X86-BMI1-NEXT:    movl %edx, %eax
1326; X86-BMI1-NEXT:    xorl %edx, %edx
1327; X86-BMI1-NEXT:  .LBB12_2:
1328; X86-BMI1-NEXT:    movl $1, %esi
1329; X86-BMI1-NEXT:    xorl %edi, %edi
1330; X86-BMI1-NEXT:    movb %ch, %cl
1331; X86-BMI1-NEXT:    shldl %cl, %esi, %edi
1332; X86-BMI1-NEXT:    shll %cl, %esi
1333; X86-BMI1-NEXT:    testb $32, %ch
1334; X86-BMI1-NEXT:    je .LBB12_4
1335; X86-BMI1-NEXT:  # %bb.3:
1336; X86-BMI1-NEXT:    movl %esi, %edi
1337; X86-BMI1-NEXT:    xorl %esi, %esi
1338; X86-BMI1-NEXT:  .LBB12_4:
1339; X86-BMI1-NEXT:    addl $-1, %esi
1340; X86-BMI1-NEXT:    adcl $-1, %edi
1341; X86-BMI1-NEXT:    andl %esi, %eax
1342; X86-BMI1-NEXT:    andl %edi, %edx
1343; X86-BMI1-NEXT:    popl %esi
1344; X86-BMI1-NEXT:    popl %edi
1345; X86-BMI1-NEXT:    retl
1346;
1347; X86-BMI2-LABEL: bextr64_a4_commutative:
1348; X86-BMI2:       # %bb.0:
1349; X86-BMI2-NEXT:    pushl %ebx
1350; X86-BMI2-NEXT:    pushl %edi
1351; X86-BMI2-NEXT:    pushl %esi
1352; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1353; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1354; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1355; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1356; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
1357; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
1358; X86-BMI2-NEXT:    testb $32, %cl
1359; X86-BMI2-NEXT:    je .LBB12_2
1360; X86-BMI2-NEXT:  # %bb.1:
1361; X86-BMI2-NEXT:    movl %edx, %eax
1362; X86-BMI2-NEXT:    xorl %edx, %edx
1363; X86-BMI2-NEXT:  .LBB12_2:
1364; X86-BMI2-NEXT:    movl $1, %edi
1365; X86-BMI2-NEXT:    xorl %esi, %esi
1366; X86-BMI2-NEXT:    movl %ebx, %ecx
1367; X86-BMI2-NEXT:    shldl %cl, %edi, %esi
1368; X86-BMI2-NEXT:    shlxl %ebx, %edi, %ecx
1369; X86-BMI2-NEXT:    testb $32, %bl
1370; X86-BMI2-NEXT:    je .LBB12_4
1371; X86-BMI2-NEXT:  # %bb.3:
1372; X86-BMI2-NEXT:    movl %ecx, %esi
1373; X86-BMI2-NEXT:    xorl %ecx, %ecx
1374; X86-BMI2-NEXT:  .LBB12_4:
1375; X86-BMI2-NEXT:    addl $-1, %ecx
1376; X86-BMI2-NEXT:    adcl $-1, %esi
1377; X86-BMI2-NEXT:    andl %ecx, %eax
1378; X86-BMI2-NEXT:    andl %esi, %edx
1379; X86-BMI2-NEXT:    popl %esi
1380; X86-BMI2-NEXT:    popl %edi
1381; X86-BMI2-NEXT:    popl %ebx
1382; X86-BMI2-NEXT:    retl
1383;
1384; X64-NOBMI-LABEL: bextr64_a4_commutative:
1385; X64-NOBMI:       # %bb.0:
1386; X64-NOBMI-NEXT:    movq %rsi, %rcx
1387; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1388; X64-NOBMI-NEXT:    shrq %cl, %rdi
1389; X64-NOBMI-NEXT:    movl $1, %eax
1390; X64-NOBMI-NEXT:    movl %edx, %ecx
1391; X64-NOBMI-NEXT:    shlq %cl, %rax
1392; X64-NOBMI-NEXT:    decq %rax
1393; X64-NOBMI-NEXT:    andq %rdi, %rax
1394; X64-NOBMI-NEXT:    retq
1395;
1396; X64-BMI1-LABEL: bextr64_a4_commutative:
1397; X64-BMI1:       # %bb.0:
1398; X64-BMI1-NEXT:    shll $8, %edx
1399; X64-BMI1-NEXT:    movzbl %sil, %eax
1400; X64-BMI1-NEXT:    orl %edx, %eax
1401; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
1402; X64-BMI1-NEXT:    retq
1403;
1404; X64-BMI2-LABEL: bextr64_a4_commutative:
1405; X64-BMI2:       # %bb.0:
1406; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1407; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
1408; X64-BMI2-NEXT:    retq
1409  %shifted = lshr i64 %val, %numskipbits
1410  %onebit = shl i64 1, %numlowbits
1411  %mask = add nsw i64 %onebit, -1
1412  %masked = and i64 %shifted, %mask ; swapped order
1413  ret i64 %masked
1414}
1415
1416define i64 @bextr64_a5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1417; X86-NOBMI-LABEL: bextr64_a5_skipextrauses:
1418; X86-NOBMI:       # %bb.0:
1419; X86-NOBMI-NEXT:    pushl %ebp
1420; X86-NOBMI-NEXT:    pushl %ebx
1421; X86-NOBMI-NEXT:    pushl %edi
1422; X86-NOBMI-NEXT:    pushl %esi
1423; X86-NOBMI-NEXT:    subl $12, %esp
1424; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1425; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1426; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
1427; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1428; X86-NOBMI-NEXT:    movl %esi, %ebp
1429; X86-NOBMI-NEXT:    movl %eax, %ecx
1430; X86-NOBMI-NEXT:    shrl %cl, %ebp
1431; X86-NOBMI-NEXT:    shrdl %cl, %esi, %ebx
1432; X86-NOBMI-NEXT:    testb $32, %al
1433; X86-NOBMI-NEXT:    je .LBB13_2
1434; X86-NOBMI-NEXT:  # %bb.1:
1435; X86-NOBMI-NEXT:    movl %ebp, %ebx
1436; X86-NOBMI-NEXT:    xorl %ebp, %ebp
1437; X86-NOBMI-NEXT:  .LBB13_2:
1438; X86-NOBMI-NEXT:    movl $1, %esi
1439; X86-NOBMI-NEXT:    xorl %edi, %edi
1440; X86-NOBMI-NEXT:    movl %edx, %ecx
1441; X86-NOBMI-NEXT:    shldl %cl, %esi, %edi
1442; X86-NOBMI-NEXT:    shll %cl, %esi
1443; X86-NOBMI-NEXT:    testb $32, %dl
1444; X86-NOBMI-NEXT:    je .LBB13_4
1445; X86-NOBMI-NEXT:  # %bb.3:
1446; X86-NOBMI-NEXT:    movl %esi, %edi
1447; X86-NOBMI-NEXT:    xorl %esi, %esi
1448; X86-NOBMI-NEXT:  .LBB13_4:
1449; X86-NOBMI-NEXT:    addl $-1, %esi
1450; X86-NOBMI-NEXT:    adcl $-1, %edi
1451; X86-NOBMI-NEXT:    andl %ebx, %esi
1452; X86-NOBMI-NEXT:    andl %ebp, %edi
1453; X86-NOBMI-NEXT:    subl $8, %esp
1454; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
1455; X86-NOBMI-NEXT:    pushl %eax
1456; X86-NOBMI-NEXT:    calll use64@PLT
1457; X86-NOBMI-NEXT:    addl $16, %esp
1458; X86-NOBMI-NEXT:    movl %esi, %eax
1459; X86-NOBMI-NEXT:    movl %edi, %edx
1460; X86-NOBMI-NEXT:    addl $12, %esp
1461; X86-NOBMI-NEXT:    popl %esi
1462; X86-NOBMI-NEXT:    popl %edi
1463; X86-NOBMI-NEXT:    popl %ebx
1464; X86-NOBMI-NEXT:    popl %ebp
1465; X86-NOBMI-NEXT:    retl
1466;
1467; X86-BMI1-LABEL: bextr64_a5_skipextrauses:
1468; X86-BMI1:       # %bb.0:
1469; X86-BMI1-NEXT:    pushl %ebp
1470; X86-BMI1-NEXT:    pushl %ebx
1471; X86-BMI1-NEXT:    pushl %edi
1472; X86-BMI1-NEXT:    pushl %esi
1473; X86-BMI1-NEXT:    subl $12, %esp
1474; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1475; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1476; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
1477; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1478; X86-BMI1-NEXT:    movl %esi, %ebp
1479; X86-BMI1-NEXT:    movl %eax, %ecx
1480; X86-BMI1-NEXT:    shrl %cl, %ebp
1481; X86-BMI1-NEXT:    shrdl %cl, %esi, %ebx
1482; X86-BMI1-NEXT:    testb $32, %al
1483; X86-BMI1-NEXT:    je .LBB13_2
1484; X86-BMI1-NEXT:  # %bb.1:
1485; X86-BMI1-NEXT:    movl %ebp, %ebx
1486; X86-BMI1-NEXT:    xorl %ebp, %ebp
1487; X86-BMI1-NEXT:  .LBB13_2:
1488; X86-BMI1-NEXT:    movl $1, %esi
1489; X86-BMI1-NEXT:    xorl %edi, %edi
1490; X86-BMI1-NEXT:    movl %edx, %ecx
1491; X86-BMI1-NEXT:    shldl %cl, %esi, %edi
1492; X86-BMI1-NEXT:    shll %cl, %esi
1493; X86-BMI1-NEXT:    testb $32, %dl
1494; X86-BMI1-NEXT:    je .LBB13_4
1495; X86-BMI1-NEXT:  # %bb.3:
1496; X86-BMI1-NEXT:    movl %esi, %edi
1497; X86-BMI1-NEXT:    xorl %esi, %esi
1498; X86-BMI1-NEXT:  .LBB13_4:
1499; X86-BMI1-NEXT:    addl $-1, %esi
1500; X86-BMI1-NEXT:    adcl $-1, %edi
1501; X86-BMI1-NEXT:    andl %ebx, %esi
1502; X86-BMI1-NEXT:    andl %ebp, %edi
1503; X86-BMI1-NEXT:    subl $8, %esp
1504; X86-BMI1-NEXT:    pushl {{[0-9]+}}(%esp)
1505; X86-BMI1-NEXT:    pushl %eax
1506; X86-BMI1-NEXT:    calll use64@PLT
1507; X86-BMI1-NEXT:    addl $16, %esp
1508; X86-BMI1-NEXT:    movl %esi, %eax
1509; X86-BMI1-NEXT:    movl %edi, %edx
1510; X86-BMI1-NEXT:    addl $12, %esp
1511; X86-BMI1-NEXT:    popl %esi
1512; X86-BMI1-NEXT:    popl %edi
1513; X86-BMI1-NEXT:    popl %ebx
1514; X86-BMI1-NEXT:    popl %ebp
1515; X86-BMI1-NEXT:    retl
1516;
1517; X86-BMI2-LABEL: bextr64_a5_skipextrauses:
1518; X86-BMI2:       # %bb.0:
1519; X86-BMI2-NEXT:    pushl %ebp
1520; X86-BMI2-NEXT:    pushl %ebx
1521; X86-BMI2-NEXT:    pushl %edi
1522; X86-BMI2-NEXT:    pushl %esi
1523; X86-BMI2-NEXT:    subl $12, %esp
1524; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1525; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1526; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1527; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1528; X86-BMI2-NEXT:    movl %eax, %ecx
1529; X86-BMI2-NEXT:    shrdl %cl, %esi, %ebx
1530; X86-BMI2-NEXT:    shrxl %eax, %esi, %ebp
1531; X86-BMI2-NEXT:    testb $32, %al
1532; X86-BMI2-NEXT:    je .LBB13_2
1533; X86-BMI2-NEXT:  # %bb.1:
1534; X86-BMI2-NEXT:    movl %ebp, %ebx
1535; X86-BMI2-NEXT:    xorl %ebp, %ebp
1536; X86-BMI2-NEXT:  .LBB13_2:
1537; X86-BMI2-NEXT:    movl $1, %edi
1538; X86-BMI2-NEXT:    xorl %esi, %esi
1539; X86-BMI2-NEXT:    movl %edx, %ecx
1540; X86-BMI2-NEXT:    shldl %cl, %edi, %esi
1541; X86-BMI2-NEXT:    shlxl %edx, %edi, %edi
1542; X86-BMI2-NEXT:    testb $32, %dl
1543; X86-BMI2-NEXT:    je .LBB13_4
1544; X86-BMI2-NEXT:  # %bb.3:
1545; X86-BMI2-NEXT:    movl %edi, %esi
1546; X86-BMI2-NEXT:    xorl %edi, %edi
1547; X86-BMI2-NEXT:  .LBB13_4:
1548; X86-BMI2-NEXT:    addl $-1, %edi
1549; X86-BMI2-NEXT:    adcl $-1, %esi
1550; X86-BMI2-NEXT:    andl %ebx, %edi
1551; X86-BMI2-NEXT:    andl %ebp, %esi
1552; X86-BMI2-NEXT:    subl $8, %esp
1553; X86-BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
1554; X86-BMI2-NEXT:    pushl %eax
1555; X86-BMI2-NEXT:    calll use64@PLT
1556; X86-BMI2-NEXT:    addl $16, %esp
1557; X86-BMI2-NEXT:    movl %edi, %eax
1558; X86-BMI2-NEXT:    movl %esi, %edx
1559; X86-BMI2-NEXT:    addl $12, %esp
1560; X86-BMI2-NEXT:    popl %esi
1561; X86-BMI2-NEXT:    popl %edi
1562; X86-BMI2-NEXT:    popl %ebx
1563; X86-BMI2-NEXT:    popl %ebp
1564; X86-BMI2-NEXT:    retl
1565;
1566; X64-NOBMI-LABEL: bextr64_a5_skipextrauses:
1567; X64-NOBMI:       # %bb.0:
1568; X64-NOBMI-NEXT:    pushq %rbx
1569; X64-NOBMI-NEXT:    movl %esi, %ecx
1570; X64-NOBMI-NEXT:    shrq %cl, %rdi
1571; X64-NOBMI-NEXT:    movl $1, %ebx
1572; X64-NOBMI-NEXT:    movl %edx, %ecx
1573; X64-NOBMI-NEXT:    shlq %cl, %rbx
1574; X64-NOBMI-NEXT:    decq %rbx
1575; X64-NOBMI-NEXT:    andq %rdi, %rbx
1576; X64-NOBMI-NEXT:    movq %rsi, %rdi
1577; X64-NOBMI-NEXT:    callq use64@PLT
1578; X64-NOBMI-NEXT:    movq %rbx, %rax
1579; X64-NOBMI-NEXT:    popq %rbx
1580; X64-NOBMI-NEXT:    retq
1581;
1582; X64-BMI1-LABEL: bextr64_a5_skipextrauses:
1583; X64-BMI1:       # %bb.0:
1584; X64-BMI1-NEXT:    pushq %rbx
1585; X64-BMI1-NEXT:    shll $8, %edx
1586; X64-BMI1-NEXT:    movzbl %sil, %eax
1587; X64-BMI1-NEXT:    orl %edx, %eax
1588; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rbx
1589; X64-BMI1-NEXT:    movq %rsi, %rdi
1590; X64-BMI1-NEXT:    callq use64@PLT
1591; X64-BMI1-NEXT:    movq %rbx, %rax
1592; X64-BMI1-NEXT:    popq %rbx
1593; X64-BMI1-NEXT:    retq
1594;
1595; X64-BMI2-LABEL: bextr64_a5_skipextrauses:
1596; X64-BMI2:       # %bb.0:
1597; X64-BMI2-NEXT:    pushq %rbx
1598; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1599; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
1600; X64-BMI2-NEXT:    movq %rsi, %rdi
1601; X64-BMI2-NEXT:    callq use64@PLT
1602; X64-BMI2-NEXT:    movq %rbx, %rax
1603; X64-BMI2-NEXT:    popq %rbx
1604; X64-BMI2-NEXT:    retq
1605  %shifted = lshr i64 %val, %numskipbits
1606  %onebit = shl i64 1, %numlowbits
1607  %mask = add nsw i64 %onebit, -1
1608  %masked = and i64 %mask, %shifted
1609  call void @use64(i64 %numskipbits)
1610  ret i64 %masked
1611}
1612
1613; 64-bit, but with 32-bit output
1614
1615; Everything done in 64-bit, truncation happens last.
1616define i32 @bextr64_32_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
1617; X86-NOBMI-LABEL: bextr64_32_a0:
1618; X86-NOBMI:       # %bb.0:
1619; X86-NOBMI-NEXT:    pushl %edi
1620; X86-NOBMI-NEXT:    pushl %esi
1621; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1622; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1623; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1624; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1625; X86-NOBMI-NEXT:    movl %edi, %esi
1626; X86-NOBMI-NEXT:    shrl %cl, %esi
1627; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1628; X86-NOBMI-NEXT:    testb $32, %cl
1629; X86-NOBMI-NEXT:    jne .LBB14_2
1630; X86-NOBMI-NEXT:  # %bb.1:
1631; X86-NOBMI-NEXT:    movl %eax, %esi
1632; X86-NOBMI-NEXT:  .LBB14_2:
1633; X86-NOBMI-NEXT:    movl $1, %edi
1634; X86-NOBMI-NEXT:    movl %edx, %ecx
1635; X86-NOBMI-NEXT:    shll %cl, %edi
1636; X86-NOBMI-NEXT:    xorl %eax, %eax
1637; X86-NOBMI-NEXT:    testb $32, %dl
1638; X86-NOBMI-NEXT:    jne .LBB14_4
1639; X86-NOBMI-NEXT:  # %bb.3:
1640; X86-NOBMI-NEXT:    movl %edi, %eax
1641; X86-NOBMI-NEXT:  .LBB14_4:
1642; X86-NOBMI-NEXT:    decl %eax
1643; X86-NOBMI-NEXT:    andl %esi, %eax
1644; X86-NOBMI-NEXT:    popl %esi
1645; X86-NOBMI-NEXT:    popl %edi
1646; X86-NOBMI-NEXT:    retl
1647;
1648; X86-BMI1-LABEL: bextr64_32_a0:
1649; X86-BMI1:       # %bb.0:
1650; X86-BMI1-NEXT:    pushl %edi
1651; X86-BMI1-NEXT:    pushl %esi
1652; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1653; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1654; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1655; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
1656; X86-BMI1-NEXT:    movl %edi, %esi
1657; X86-BMI1-NEXT:    shrl %cl, %esi
1658; X86-BMI1-NEXT:    shrdl %cl, %edi, %eax
1659; X86-BMI1-NEXT:    testb $32, %cl
1660; X86-BMI1-NEXT:    jne .LBB14_2
1661; X86-BMI1-NEXT:  # %bb.1:
1662; X86-BMI1-NEXT:    movl %eax, %esi
1663; X86-BMI1-NEXT:  .LBB14_2:
1664; X86-BMI1-NEXT:    movl $1, %edi
1665; X86-BMI1-NEXT:    movl %edx, %ecx
1666; X86-BMI1-NEXT:    shll %cl, %edi
1667; X86-BMI1-NEXT:    xorl %eax, %eax
1668; X86-BMI1-NEXT:    testb $32, %dl
1669; X86-BMI1-NEXT:    jne .LBB14_4
1670; X86-BMI1-NEXT:  # %bb.3:
1671; X86-BMI1-NEXT:    movl %edi, %eax
1672; X86-BMI1-NEXT:  .LBB14_4:
1673; X86-BMI1-NEXT:    decl %eax
1674; X86-BMI1-NEXT:    andl %esi, %eax
1675; X86-BMI1-NEXT:    popl %esi
1676; X86-BMI1-NEXT:    popl %edi
1677; X86-BMI1-NEXT:    retl
1678;
1679; X86-BMI2-LABEL: bextr64_32_a0:
1680; X86-BMI2:       # %bb.0:
1681; X86-BMI2-NEXT:    pushl %ebx
1682; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1683; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1684; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1685; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1686; X86-BMI2-NEXT:    shrdl %cl, %eax, %edx
1687; X86-BMI2-NEXT:    testb $32, %cl
1688; X86-BMI2-NEXT:    je .LBB14_2
1689; X86-BMI2-NEXT:  # %bb.1:
1690; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
1691; X86-BMI2-NEXT:  .LBB14_2:
1692; X86-BMI2-NEXT:    xorl %eax, %eax
1693; X86-BMI2-NEXT:    testb $32, %bl
1694; X86-BMI2-NEXT:    jne .LBB14_4
1695; X86-BMI2-NEXT:  # %bb.3:
1696; X86-BMI2-NEXT:    movl $1, %eax
1697; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
1698; X86-BMI2-NEXT:  .LBB14_4:
1699; X86-BMI2-NEXT:    decl %eax
1700; X86-BMI2-NEXT:    andl %edx, %eax
1701; X86-BMI2-NEXT:    popl %ebx
1702; X86-BMI2-NEXT:    retl
1703;
1704; X64-NOBMI-LABEL: bextr64_32_a0:
1705; X64-NOBMI:       # %bb.0:
1706; X64-NOBMI-NEXT:    movq %rsi, %rcx
1707; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1708; X64-NOBMI-NEXT:    shrq %cl, %rdi
1709; X64-NOBMI-NEXT:    movl $1, %eax
1710; X64-NOBMI-NEXT:    movl %edx, %ecx
1711; X64-NOBMI-NEXT:    shlq %cl, %rax
1712; X64-NOBMI-NEXT:    decl %eax
1713; X64-NOBMI-NEXT:    andl %edi, %eax
1714; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
1715; X64-NOBMI-NEXT:    retq
1716;
1717; X64-BMI1-LABEL: bextr64_32_a0:
1718; X64-BMI1:       # %bb.0:
1719; X64-BMI1-NEXT:    shll $8, %edx
1720; X64-BMI1-NEXT:    movzbl %sil, %eax
1721; X64-BMI1-NEXT:    orl %edx, %eax
1722; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
1723; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
1724; X64-BMI1-NEXT:    retq
1725;
1726; X64-BMI2-LABEL: bextr64_32_a0:
1727; X64-BMI2:       # %bb.0:
1728; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1729; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
1730; X64-BMI2-NEXT:    retq
1731  %shifted = lshr i64 %val, %numskipbits
1732  %onebit = shl i64 1, %numlowbits
1733  %mask = add nsw i64 %onebit, -1
1734  %masked = and i64 %mask, %shifted
1735  %res = trunc i64 %masked to i32
1736  ret i32 %res
1737}
1738
1739; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
1740define i32 @bextr64_32_a1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
1741; X86-NOBMI-LABEL: bextr64_32_a1:
1742; X86-NOBMI:       # %bb.0:
1743; X86-NOBMI-NEXT:    pushl %edi
1744; X86-NOBMI-NEXT:    pushl %esi
1745; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1746; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1747; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1748; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1749; X86-NOBMI-NEXT:    movl %edi, %esi
1750; X86-NOBMI-NEXT:    shrl %cl, %esi
1751; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1752; X86-NOBMI-NEXT:    testb $32, %cl
1753; X86-NOBMI-NEXT:    jne .LBB15_2
1754; X86-NOBMI-NEXT:  # %bb.1:
1755; X86-NOBMI-NEXT:    movl %eax, %esi
1756; X86-NOBMI-NEXT:  .LBB15_2:
1757; X86-NOBMI-NEXT:    movl $1, %eax
1758; X86-NOBMI-NEXT:    movl %edx, %ecx
1759; X86-NOBMI-NEXT:    shll %cl, %eax
1760; X86-NOBMI-NEXT:    decl %eax
1761; X86-NOBMI-NEXT:    andl %esi, %eax
1762; X86-NOBMI-NEXT:    popl %esi
1763; X86-NOBMI-NEXT:    popl %edi
1764; X86-NOBMI-NEXT:    retl
1765;
1766; X86-BMI1-LABEL: bextr64_32_a1:
1767; X86-BMI1:       # %bb.0:
1768; X86-BMI1-NEXT:    pushl %edi
1769; X86-BMI1-NEXT:    pushl %esi
1770; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
1771; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1772; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
1773; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
1774; X86-BMI1-NEXT:    movl %edi, %edx
1775; X86-BMI1-NEXT:    shrl %cl, %edx
1776; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
1777; X86-BMI1-NEXT:    testb $32, %cl
1778; X86-BMI1-NEXT:    jne .LBB15_2
1779; X86-BMI1-NEXT:  # %bb.1:
1780; X86-BMI1-NEXT:    movl %esi, %edx
1781; X86-BMI1-NEXT:  .LBB15_2:
1782; X86-BMI1-NEXT:    shll $8, %eax
1783; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
1784; X86-BMI1-NEXT:    popl %esi
1785; X86-BMI1-NEXT:    popl %edi
1786; X86-BMI1-NEXT:    retl
1787;
1788; X86-BMI2-LABEL: bextr64_32_a1:
1789; X86-BMI2:       # %bb.0:
1790; X86-BMI2-NEXT:    pushl %esi
1791; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
1792; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1793; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
1794; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1795; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
1796; X86-BMI2-NEXT:    testb $32, %cl
1797; X86-BMI2-NEXT:    je .LBB15_2
1798; X86-BMI2-NEXT:  # %bb.1:
1799; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
1800; X86-BMI2-NEXT:  .LBB15_2:
1801; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
1802; X86-BMI2-NEXT:    popl %esi
1803; X86-BMI2-NEXT:    retl
1804;
1805; X64-NOBMI-LABEL: bextr64_32_a1:
1806; X64-NOBMI:       # %bb.0:
1807; X64-NOBMI-NEXT:    movq %rsi, %rcx
1808; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1809; X64-NOBMI-NEXT:    shrq %cl, %rdi
1810; X64-NOBMI-NEXT:    movl $1, %eax
1811; X64-NOBMI-NEXT:    movl %edx, %ecx
1812; X64-NOBMI-NEXT:    shll %cl, %eax
1813; X64-NOBMI-NEXT:    decl %eax
1814; X64-NOBMI-NEXT:    andl %edi, %eax
1815; X64-NOBMI-NEXT:    retq
1816;
1817; X64-BMI1-LABEL: bextr64_32_a1:
1818; X64-BMI1:       # %bb.0:
1819; X64-BMI1-NEXT:    shll $8, %edx
1820; X64-BMI1-NEXT:    movzbl %sil, %eax
1821; X64-BMI1-NEXT:    orl %edx, %eax
1822; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
1823; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
1824; X64-BMI1-NEXT:    retq
1825;
1826; X64-BMI2-LABEL: bextr64_32_a1:
1827; X64-BMI2:       # %bb.0:
1828; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
1829; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
1830; X64-BMI2-NEXT:    retq
1831  %shifted = lshr i64 %val, %numskipbits
1832  %truncshifted = trunc i64 %shifted to i32
1833  %onebit = shl i32 1, %numlowbits
1834  %mask = add nsw i32 %onebit, -1
1835  %masked = and i32 %mask, %truncshifted
1836  ret i32 %masked
1837}
1838
1839; Shifting happens in 64-bit, then truncation (with extra use).
1840; Masking is 32-bit.
1841define i32 @bextr64_32_a1_trunc_extrause(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
1842; X86-NOBMI-LABEL: bextr64_32_a1_trunc_extrause:
1843; X86-NOBMI:       # %bb.0:
1844; X86-NOBMI-NEXT:    pushl %ebx
1845; X86-NOBMI-NEXT:    pushl %esi
1846; X86-NOBMI-NEXT:    pushl %eax
1847; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1848; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1849; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1850; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
1851; X86-NOBMI-NEXT:    movl %edx, %esi
1852; X86-NOBMI-NEXT:    shrl %cl, %esi
1853; X86-NOBMI-NEXT:    shrdl %cl, %edx, %eax
1854; X86-NOBMI-NEXT:    testb $32, %cl
1855; X86-NOBMI-NEXT:    jne .LBB16_2
1856; X86-NOBMI-NEXT:  # %bb.1:
1857; X86-NOBMI-NEXT:    movl %eax, %esi
1858; X86-NOBMI-NEXT:  .LBB16_2:
1859; X86-NOBMI-NEXT:    movl %esi, (%esp)
1860; X86-NOBMI-NEXT:    calll use32@PLT
1861; X86-NOBMI-NEXT:    movl $1, %eax
1862; X86-NOBMI-NEXT:    movl %ebx, %ecx
1863; X86-NOBMI-NEXT:    shll %cl, %eax
1864; X86-NOBMI-NEXT:    decl %eax
1865; X86-NOBMI-NEXT:    andl %esi, %eax
1866; X86-NOBMI-NEXT:    addl $4, %esp
1867; X86-NOBMI-NEXT:    popl %esi
1868; X86-NOBMI-NEXT:    popl %ebx
1869; X86-NOBMI-NEXT:    retl
1870;
1871; X86-BMI1-LABEL: bextr64_32_a1_trunc_extrause:
1872; X86-BMI1:       # %bb.0:
1873; X86-BMI1-NEXT:    pushl %ebx
1874; X86-BMI1-NEXT:    pushl %esi
1875; X86-BMI1-NEXT:    pushl %eax
1876; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1877; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1878; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
1879; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
1880; X86-BMI1-NEXT:    movl %edx, %esi
1881; X86-BMI1-NEXT:    shrl %cl, %esi
1882; X86-BMI1-NEXT:    shrdl %cl, %edx, %eax
1883; X86-BMI1-NEXT:    testb $32, %cl
1884; X86-BMI1-NEXT:    jne .LBB16_2
1885; X86-BMI1-NEXT:  # %bb.1:
1886; X86-BMI1-NEXT:    movl %eax, %esi
1887; X86-BMI1-NEXT:  .LBB16_2:
1888; X86-BMI1-NEXT:    movl %esi, (%esp)
1889; X86-BMI1-NEXT:    calll use32@PLT
1890; X86-BMI1-NEXT:    shll $8, %ebx
1891; X86-BMI1-NEXT:    bextrl %ebx, %esi, %eax
1892; X86-BMI1-NEXT:    addl $4, %esp
1893; X86-BMI1-NEXT:    popl %esi
1894; X86-BMI1-NEXT:    popl %ebx
1895; X86-BMI1-NEXT:    retl
1896;
1897; X86-BMI2-LABEL: bextr64_32_a1_trunc_extrause:
1898; X86-BMI2:       # %bb.0:
1899; X86-BMI2-NEXT:    pushl %ebx
1900; X86-BMI2-NEXT:    pushl %esi
1901; X86-BMI2-NEXT:    pushl %eax
1902; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
1903; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1904; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
1905; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
1906; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
1907; X86-BMI2-NEXT:    testb $32, %cl
1908; X86-BMI2-NEXT:    je .LBB16_2
1909; X86-BMI2-NEXT:  # %bb.1:
1910; X86-BMI2-NEXT:    shrxl %ecx, %eax, %esi
1911; X86-BMI2-NEXT:  .LBB16_2:
1912; X86-BMI2-NEXT:    movl %esi, (%esp)
1913; X86-BMI2-NEXT:    calll use32@PLT
1914; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
1915; X86-BMI2-NEXT:    addl $4, %esp
1916; X86-BMI2-NEXT:    popl %esi
1917; X86-BMI2-NEXT:    popl %ebx
1918; X86-BMI2-NEXT:    retl
1919;
1920; X64-NOBMI-LABEL: bextr64_32_a1_trunc_extrause:
1921; X64-NOBMI:       # %bb.0:
1922; X64-NOBMI-NEXT:    pushq %r14
1923; X64-NOBMI-NEXT:    pushq %rbx
1924; X64-NOBMI-NEXT:    pushq %rax
1925; X64-NOBMI-NEXT:    movl %edx, %ebx
1926; X64-NOBMI-NEXT:    movq %rsi, %rcx
1927; X64-NOBMI-NEXT:    movq %rdi, %r14
1928; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
1929; X64-NOBMI-NEXT:    shrq %cl, %r14
1930; X64-NOBMI-NEXT:    movl %r14d, %edi
1931; X64-NOBMI-NEXT:    callq use32@PLT
1932; X64-NOBMI-NEXT:    movl $1, %eax
1933; X64-NOBMI-NEXT:    movl %ebx, %ecx
1934; X64-NOBMI-NEXT:    shll %cl, %eax
1935; X64-NOBMI-NEXT:    decl %eax
1936; X64-NOBMI-NEXT:    andl %r14d, %eax
1937; X64-NOBMI-NEXT:    addq $8, %rsp
1938; X64-NOBMI-NEXT:    popq %rbx
1939; X64-NOBMI-NEXT:    popq %r14
1940; X64-NOBMI-NEXT:    retq
1941;
1942; X64-BMI1-LABEL: bextr64_32_a1_trunc_extrause:
1943; X64-BMI1:       # %bb.0:
1944; X64-BMI1-NEXT:    pushq %r14
1945; X64-BMI1-NEXT:    pushq %rbx
1946; X64-BMI1-NEXT:    pushq %rax
1947; X64-BMI1-NEXT:    movl %edx, %ebx
1948; X64-BMI1-NEXT:    movq %rsi, %rcx
1949; X64-BMI1-NEXT:    movq %rdi, %r14
1950; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
1951; X64-BMI1-NEXT:    shrq %cl, %r14
1952; X64-BMI1-NEXT:    movl %r14d, %edi
1953; X64-BMI1-NEXT:    callq use32@PLT
1954; X64-BMI1-NEXT:    shll $8, %ebx
1955; X64-BMI1-NEXT:    bextrl %ebx, %r14d, %eax
1956; X64-BMI1-NEXT:    addq $8, %rsp
1957; X64-BMI1-NEXT:    popq %rbx
1958; X64-BMI1-NEXT:    popq %r14
1959; X64-BMI1-NEXT:    retq
1960;
1961; X64-BMI2-LABEL: bextr64_32_a1_trunc_extrause:
1962; X64-BMI2:       # %bb.0:
1963; X64-BMI2-NEXT:    pushq %r14
1964; X64-BMI2-NEXT:    pushq %rbx
1965; X64-BMI2-NEXT:    pushq %rax
1966; X64-BMI2-NEXT:    movl %edx, %ebx
1967; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %r14
1968; X64-BMI2-NEXT:    movl %r14d, %edi
1969; X64-BMI2-NEXT:    callq use32@PLT
1970; X64-BMI2-NEXT:    bzhil %ebx, %r14d, %eax
1971; X64-BMI2-NEXT:    addq $8, %rsp
1972; X64-BMI2-NEXT:    popq %rbx
1973; X64-BMI2-NEXT:    popq %r14
1974; X64-BMI2-NEXT:    retq
1975  %shifted = lshr i64 %val, %numskipbits
1976  %truncshifted = trunc i64 %shifted to i32
1977  call void @use32(i32 %truncshifted)
1978  %onebit = shl i32 1, %numlowbits
1979  %mask = add nsw i32 %onebit, -1
1980  %masked = and i32 %mask, %truncshifted
1981  ret i32 %masked
1982}
1983
1984; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
1985; Masking is 64-bit. Then truncation.
1986define i32 @bextr64_32_a2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
1987; X86-NOBMI-LABEL: bextr64_32_a2:
1988; X86-NOBMI:       # %bb.0:
1989; X86-NOBMI-NEXT:    pushl %edi
1990; X86-NOBMI-NEXT:    pushl %esi
1991; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
1992; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1993; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
1994; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
1995; X86-NOBMI-NEXT:    movl %edi, %esi
1996; X86-NOBMI-NEXT:    shrl %cl, %esi
1997; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
1998; X86-NOBMI-NEXT:    testb $32, %cl
1999; X86-NOBMI-NEXT:    jne .LBB17_2
2000; X86-NOBMI-NEXT:  # %bb.1:
2001; X86-NOBMI-NEXT:    movl %eax, %esi
2002; X86-NOBMI-NEXT:  .LBB17_2:
2003; X86-NOBMI-NEXT:    movl $1, %eax
2004; X86-NOBMI-NEXT:    movl %edx, %ecx
2005; X86-NOBMI-NEXT:    shll %cl, %eax
2006; X86-NOBMI-NEXT:    decl %eax
2007; X86-NOBMI-NEXT:    andl %esi, %eax
2008; X86-NOBMI-NEXT:    popl %esi
2009; X86-NOBMI-NEXT:    popl %edi
2010; X86-NOBMI-NEXT:    retl
2011;
2012; X86-BMI1-LABEL: bextr64_32_a2:
2013; X86-BMI1:       # %bb.0:
2014; X86-BMI1-NEXT:    pushl %edi
2015; X86-BMI1-NEXT:    pushl %esi
2016; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2017; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2018; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
2019; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
2020; X86-BMI1-NEXT:    movl %edi, %edx
2021; X86-BMI1-NEXT:    shrl %cl, %edx
2022; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
2023; X86-BMI1-NEXT:    testb $32, %cl
2024; X86-BMI1-NEXT:    jne .LBB17_2
2025; X86-BMI1-NEXT:  # %bb.1:
2026; X86-BMI1-NEXT:    movl %esi, %edx
2027; X86-BMI1-NEXT:  .LBB17_2:
2028; X86-BMI1-NEXT:    shll $8, %eax
2029; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
2030; X86-BMI1-NEXT:    popl %esi
2031; X86-BMI1-NEXT:    popl %edi
2032; X86-BMI1-NEXT:    retl
2033;
2034; X86-BMI2-LABEL: bextr64_32_a2:
2035; X86-BMI2:       # %bb.0:
2036; X86-BMI2-NEXT:    pushl %esi
2037; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2038; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2039; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2040; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
2041; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
2042; X86-BMI2-NEXT:    testb $32, %cl
2043; X86-BMI2-NEXT:    je .LBB17_2
2044; X86-BMI2-NEXT:  # %bb.1:
2045; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
2046; X86-BMI2-NEXT:  .LBB17_2:
2047; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
2048; X86-BMI2-NEXT:    popl %esi
2049; X86-BMI2-NEXT:    retl
2050;
2051; X64-NOBMI-LABEL: bextr64_32_a2:
2052; X64-NOBMI:       # %bb.0:
2053; X64-NOBMI-NEXT:    movq %rsi, %rcx
2054; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2055; X64-NOBMI-NEXT:    shrq %cl, %rdi
2056; X64-NOBMI-NEXT:    movl $1, %eax
2057; X64-NOBMI-NEXT:    movl %edx, %ecx
2058; X64-NOBMI-NEXT:    shll %cl, %eax
2059; X64-NOBMI-NEXT:    decl %eax
2060; X64-NOBMI-NEXT:    andl %edi, %eax
2061; X64-NOBMI-NEXT:    retq
2062;
2063; X64-BMI1-LABEL: bextr64_32_a2:
2064; X64-BMI1:       # %bb.0:
2065; X64-BMI1-NEXT:    shll $8, %edx
2066; X64-BMI1-NEXT:    movzbl %sil, %eax
2067; X64-BMI1-NEXT:    orl %edx, %eax
2068; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
2069; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
2070; X64-BMI1-NEXT:    retq
2071;
2072; X64-BMI2-LABEL: bextr64_32_a2:
2073; X64-BMI2:       # %bb.0:
2074; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2075; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2076; X64-BMI2-NEXT:    retq
2077  %shifted = lshr i64 %val, %numskipbits
2078  %onebit = shl i32 1, %numlowbits
2079  %mask = add nsw i32 %onebit, -1
2080  %zextmask = zext i32 %mask to i64
2081  %masked = and i64 %zextmask, %shifted
2082  %truncmasked = trunc i64 %masked to i32
2083  ret i32 %truncmasked
2084}
2085
2086; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit.
2087; Masking is 64-bit. Then truncation.
2088define i32 @bextr64_32_a3(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2089; X86-NOBMI-LABEL: bextr64_32_a3:
2090; X86-NOBMI:       # %bb.0:
2091; X86-NOBMI-NEXT:    pushl %edi
2092; X86-NOBMI-NEXT:    pushl %esi
2093; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2094; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2095; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2096; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
2097; X86-NOBMI-NEXT:    movl %edi, %esi
2098; X86-NOBMI-NEXT:    shrl %cl, %esi
2099; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
2100; X86-NOBMI-NEXT:    testb $32, %cl
2101; X86-NOBMI-NEXT:    jne .LBB18_2
2102; X86-NOBMI-NEXT:  # %bb.1:
2103; X86-NOBMI-NEXT:    movl %eax, %esi
2104; X86-NOBMI-NEXT:  .LBB18_2:
2105; X86-NOBMI-NEXT:    movl $1, %edi
2106; X86-NOBMI-NEXT:    movl %edx, %ecx
2107; X86-NOBMI-NEXT:    shll %cl, %edi
2108; X86-NOBMI-NEXT:    xorl %eax, %eax
2109; X86-NOBMI-NEXT:    testb $32, %dl
2110; X86-NOBMI-NEXT:    jne .LBB18_4
2111; X86-NOBMI-NEXT:  # %bb.3:
2112; X86-NOBMI-NEXT:    movl %edi, %eax
2113; X86-NOBMI-NEXT:  .LBB18_4:
2114; X86-NOBMI-NEXT:    decl %eax
2115; X86-NOBMI-NEXT:    andl %esi, %eax
2116; X86-NOBMI-NEXT:    popl %esi
2117; X86-NOBMI-NEXT:    popl %edi
2118; X86-NOBMI-NEXT:    retl
2119;
2120; X86-BMI1-LABEL: bextr64_32_a3:
2121; X86-BMI1:       # %bb.0:
2122; X86-BMI1-NEXT:    pushl %edi
2123; X86-BMI1-NEXT:    pushl %esi
2124; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2125; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2126; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
2127; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
2128; X86-BMI1-NEXT:    movl %edi, %esi
2129; X86-BMI1-NEXT:    shrl %cl, %esi
2130; X86-BMI1-NEXT:    shrdl %cl, %edi, %eax
2131; X86-BMI1-NEXT:    testb $32, %cl
2132; X86-BMI1-NEXT:    jne .LBB18_2
2133; X86-BMI1-NEXT:  # %bb.1:
2134; X86-BMI1-NEXT:    movl %eax, %esi
2135; X86-BMI1-NEXT:  .LBB18_2:
2136; X86-BMI1-NEXT:    movl $1, %edi
2137; X86-BMI1-NEXT:    movl %edx, %ecx
2138; X86-BMI1-NEXT:    shll %cl, %edi
2139; X86-BMI1-NEXT:    xorl %eax, %eax
2140; X86-BMI1-NEXT:    testb $32, %dl
2141; X86-BMI1-NEXT:    jne .LBB18_4
2142; X86-BMI1-NEXT:  # %bb.3:
2143; X86-BMI1-NEXT:    movl %edi, %eax
2144; X86-BMI1-NEXT:  .LBB18_4:
2145; X86-BMI1-NEXT:    decl %eax
2146; X86-BMI1-NEXT:    andl %esi, %eax
2147; X86-BMI1-NEXT:    popl %esi
2148; X86-BMI1-NEXT:    popl %edi
2149; X86-BMI1-NEXT:    retl
2150;
2151; X86-BMI2-LABEL: bextr64_32_a3:
2152; X86-BMI2:       # %bb.0:
2153; X86-BMI2-NEXT:    pushl %ebx
2154; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
2155; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2156; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2157; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2158; X86-BMI2-NEXT:    shrdl %cl, %eax, %edx
2159; X86-BMI2-NEXT:    testb $32, %cl
2160; X86-BMI2-NEXT:    je .LBB18_2
2161; X86-BMI2-NEXT:  # %bb.1:
2162; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
2163; X86-BMI2-NEXT:  .LBB18_2:
2164; X86-BMI2-NEXT:    xorl %eax, %eax
2165; X86-BMI2-NEXT:    testb $32, %bl
2166; X86-BMI2-NEXT:    jne .LBB18_4
2167; X86-BMI2-NEXT:  # %bb.3:
2168; X86-BMI2-NEXT:    movl $1, %eax
2169; X86-BMI2-NEXT:    shlxl %ebx, %eax, %eax
2170; X86-BMI2-NEXT:  .LBB18_4:
2171; X86-BMI2-NEXT:    decl %eax
2172; X86-BMI2-NEXT:    andl %edx, %eax
2173; X86-BMI2-NEXT:    popl %ebx
2174; X86-BMI2-NEXT:    retl
2175;
2176; X64-NOBMI-LABEL: bextr64_32_a3:
2177; X64-NOBMI:       # %bb.0:
2178; X64-NOBMI-NEXT:    movq %rsi, %rcx
2179; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2180; X64-NOBMI-NEXT:    shrq %cl, %rdi
2181; X64-NOBMI-NEXT:    movl $1, %eax
2182; X64-NOBMI-NEXT:    movl %edx, %ecx
2183; X64-NOBMI-NEXT:    shlq %cl, %rax
2184; X64-NOBMI-NEXT:    decl %eax
2185; X64-NOBMI-NEXT:    andl %edi, %eax
2186; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
2187; X64-NOBMI-NEXT:    retq
2188;
2189; X64-BMI1-LABEL: bextr64_32_a3:
2190; X64-BMI1:       # %bb.0:
2191; X64-BMI1-NEXT:    shll $8, %edx
2192; X64-BMI1-NEXT:    movzbl %sil, %eax
2193; X64-BMI1-NEXT:    orl %edx, %eax
2194; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
2195; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
2196; X64-BMI1-NEXT:    retq
2197;
2198; X64-BMI2-LABEL: bextr64_32_a3:
2199; X64-BMI2:       # %bb.0:
2200; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2201; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2202; X64-BMI2-NEXT:    retq
2203  %shifted = lshr i64 %val, %numskipbits
2204  %onebit = shl i64 1, %numlowbits
2205  %mask = add nsw i64 %onebit, 4294967295
2206  %masked = and i64 %mask, %shifted
2207  %truncmasked = trunc i64 %masked to i32
2208  ret i32 %truncmasked
2209}
2210
2211; ---------------------------------------------------------------------------- ;
2212; Pattern b. 32-bit
2213; ---------------------------------------------------------------------------- ;
2214
2215define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2216; X86-NOBMI-LABEL: bextr32_b0:
2217; X86-NOBMI:       # %bb.0:
2218; X86-NOBMI-NEXT:    pushl %esi
2219; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2220; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2221; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2222; X86-NOBMI-NEXT:    shrl %cl, %esi
2223; X86-NOBMI-NEXT:    movl $-1, %eax
2224; X86-NOBMI-NEXT:    movl %edx, %ecx
2225; X86-NOBMI-NEXT:    shll %cl, %eax
2226; X86-NOBMI-NEXT:    notl %eax
2227; X86-NOBMI-NEXT:    andl %esi, %eax
2228; X86-NOBMI-NEXT:    popl %esi
2229; X86-NOBMI-NEXT:    retl
2230;
2231; X86-BMI1-LABEL: bextr32_b0:
2232; X86-BMI1:       # %bb.0:
2233; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2234; X86-BMI1-NEXT:    shll $8, %eax
2235; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2236; X86-BMI1-NEXT:    orl %eax, %ecx
2237; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
2238; X86-BMI1-NEXT:    retl
2239;
2240; X86-BMI2-LABEL: bextr32_b0:
2241; X86-BMI2:       # %bb.0:
2242; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2243; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2244; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
2245; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
2246; X86-BMI2-NEXT:    retl
2247;
2248; X64-NOBMI-LABEL: bextr32_b0:
2249; X64-NOBMI:       # %bb.0:
2250; X64-NOBMI-NEXT:    movl %esi, %ecx
2251; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2252; X64-NOBMI-NEXT:    shrl %cl, %edi
2253; X64-NOBMI-NEXT:    movl $-1, %eax
2254; X64-NOBMI-NEXT:    movl %edx, %ecx
2255; X64-NOBMI-NEXT:    shll %cl, %eax
2256; X64-NOBMI-NEXT:    notl %eax
2257; X64-NOBMI-NEXT:    andl %edi, %eax
2258; X64-NOBMI-NEXT:    retq
2259;
2260; X64-BMI1-LABEL: bextr32_b0:
2261; X64-BMI1:       # %bb.0:
2262; X64-BMI1-NEXT:    shll $8, %edx
2263; X64-BMI1-NEXT:    movzbl %sil, %eax
2264; X64-BMI1-NEXT:    orl %edx, %eax
2265; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
2266; X64-BMI1-NEXT:    retq
2267;
2268; X64-BMI2-LABEL: bextr32_b0:
2269; X64-BMI2:       # %bb.0:
2270; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
2271; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2272; X64-BMI2-NEXT:    retq
2273  %shifted = lshr i32 %val, %numskipbits
2274  %notmask = shl i32 -1, %numlowbits
2275  %mask = xor i32 %notmask, -1
2276  %masked = and i32 %mask, %shifted
2277  ret i32 %masked
2278}
2279
2280define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2281; X86-NOBMI-LABEL: bextr32_b1_indexzext:
2282; X86-NOBMI:       # %bb.0:
2283; X86-NOBMI-NEXT:    pushl %esi
2284; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2285; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2286; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2287; X86-NOBMI-NEXT:    shrl %cl, %esi
2288; X86-NOBMI-NEXT:    movl $-1, %eax
2289; X86-NOBMI-NEXT:    movl %edx, %ecx
2290; X86-NOBMI-NEXT:    shll %cl, %eax
2291; X86-NOBMI-NEXT:    notl %eax
2292; X86-NOBMI-NEXT:    andl %esi, %eax
2293; X86-NOBMI-NEXT:    popl %esi
2294; X86-NOBMI-NEXT:    retl
2295;
2296; X86-BMI1-LABEL: bextr32_b1_indexzext:
2297; X86-BMI1:       # %bb.0:
2298; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2299; X86-BMI1-NEXT:    shll $8, %eax
2300; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2301; X86-BMI1-NEXT:    orl %eax, %ecx
2302; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
2303; X86-BMI1-NEXT:    retl
2304;
2305; X86-BMI2-LABEL: bextr32_b1_indexzext:
2306; X86-BMI2:       # %bb.0:
2307; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2308; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2309; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
2310; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
2311; X86-BMI2-NEXT:    retl
2312;
2313; X64-NOBMI-LABEL: bextr32_b1_indexzext:
2314; X64-NOBMI:       # %bb.0:
2315; X64-NOBMI-NEXT:    movl %esi, %ecx
2316; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2317; X64-NOBMI-NEXT:    shrl %cl, %edi
2318; X64-NOBMI-NEXT:    movl $-1, %eax
2319; X64-NOBMI-NEXT:    movl %edx, %ecx
2320; X64-NOBMI-NEXT:    shll %cl, %eax
2321; X64-NOBMI-NEXT:    notl %eax
2322; X64-NOBMI-NEXT:    andl %edi, %eax
2323; X64-NOBMI-NEXT:    retq
2324;
2325; X64-BMI1-LABEL: bextr32_b1_indexzext:
2326; X64-BMI1:       # %bb.0:
2327; X64-BMI1-NEXT:    shll $8, %edx
2328; X64-BMI1-NEXT:    orl %esi, %edx
2329; X64-BMI1-NEXT:    bextrl %edx, %edi, %eax
2330; X64-BMI1-NEXT:    retq
2331;
2332; X64-BMI2-LABEL: bextr32_b1_indexzext:
2333; X64-BMI2:       # %bb.0:
2334; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
2335; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2336; X64-BMI2-NEXT:    retq
2337  %skip = zext i8 %numskipbits to i32
2338  %shifted = lshr i32 %val, %skip
2339  %conv = zext i8 %numlowbits to i32
2340  %notmask = shl i32 -1, %conv
2341  %mask = xor i32 %notmask, -1
2342  %masked = and i32 %mask, %shifted
2343  ret i32 %masked
2344}
2345
2346define i32 @bextr32_b2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {
2347; X86-NOBMI-LABEL: bextr32_b2_load:
2348; X86-NOBMI:       # %bb.0:
2349; X86-NOBMI-NEXT:    pushl %esi
2350; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2351; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2352; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2353; X86-NOBMI-NEXT:    movl (%eax), %esi
2354; X86-NOBMI-NEXT:    shrl %cl, %esi
2355; X86-NOBMI-NEXT:    movl $-1, %eax
2356; X86-NOBMI-NEXT:    movl %edx, %ecx
2357; X86-NOBMI-NEXT:    shll %cl, %eax
2358; X86-NOBMI-NEXT:    notl %eax
2359; X86-NOBMI-NEXT:    andl %esi, %eax
2360; X86-NOBMI-NEXT:    popl %esi
2361; X86-NOBMI-NEXT:    retl
2362;
2363; X86-BMI1-LABEL: bextr32_b2_load:
2364; X86-BMI1:       # %bb.0:
2365; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
2366; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2367; X86-BMI1-NEXT:    shll $8, %ecx
2368; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2369; X86-BMI1-NEXT:    orl %ecx, %edx
2370; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
2371; X86-BMI1-NEXT:    retl
2372;
2373; X86-BMI2-LABEL: bextr32_b2_load:
2374; X86-BMI2:       # %bb.0:
2375; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2376; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2377; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2378; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
2379; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
2380; X86-BMI2-NEXT:    retl
2381;
2382; X64-NOBMI-LABEL: bextr32_b2_load:
2383; X64-NOBMI:       # %bb.0:
2384; X64-NOBMI-NEXT:    movl %esi, %ecx
2385; X64-NOBMI-NEXT:    movl (%rdi), %esi
2386; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2387; X64-NOBMI-NEXT:    shrl %cl, %esi
2388; X64-NOBMI-NEXT:    movl $-1, %eax
2389; X64-NOBMI-NEXT:    movl %edx, %ecx
2390; X64-NOBMI-NEXT:    shll %cl, %eax
2391; X64-NOBMI-NEXT:    notl %eax
2392; X64-NOBMI-NEXT:    andl %esi, %eax
2393; X64-NOBMI-NEXT:    retq
2394;
2395; X64-BMI1-LABEL: bextr32_b2_load:
2396; X64-BMI1:       # %bb.0:
2397; X64-BMI1-NEXT:    shll $8, %edx
2398; X64-BMI1-NEXT:    movzbl %sil, %eax
2399; X64-BMI1-NEXT:    orl %edx, %eax
2400; X64-BMI1-NEXT:    bextrl %eax, (%rdi), %eax
2401; X64-BMI1-NEXT:    retq
2402;
2403; X64-BMI2-LABEL: bextr32_b2_load:
2404; X64-BMI2:       # %bb.0:
2405; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
2406; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2407; X64-BMI2-NEXT:    retq
2408  %val = load i32, ptr %w
2409  %shifted = lshr i32 %val, %numskipbits
2410  %notmask = shl i32 -1, %numlowbits
2411  %mask = xor i32 %notmask, -1
2412  %masked = and i32 %mask, %shifted
2413  ret i32 %masked
2414}
2415
2416define i32 @bextr32_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2417; X86-NOBMI-LABEL: bextr32_b3_load_indexzext:
2418; X86-NOBMI:       # %bb.0:
2419; X86-NOBMI-NEXT:    pushl %esi
2420; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2421; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2422; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2423; X86-NOBMI-NEXT:    movl (%eax), %esi
2424; X86-NOBMI-NEXT:    shrl %cl, %esi
2425; X86-NOBMI-NEXT:    movl $-1, %eax
2426; X86-NOBMI-NEXT:    movl %edx, %ecx
2427; X86-NOBMI-NEXT:    shll %cl, %eax
2428; X86-NOBMI-NEXT:    notl %eax
2429; X86-NOBMI-NEXT:    andl %esi, %eax
2430; X86-NOBMI-NEXT:    popl %esi
2431; X86-NOBMI-NEXT:    retl
2432;
2433; X86-BMI1-LABEL: bextr32_b3_load_indexzext:
2434; X86-BMI1:       # %bb.0:
2435; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
2436; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2437; X86-BMI1-NEXT:    shll $8, %ecx
2438; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2439; X86-BMI1-NEXT:    orl %ecx, %edx
2440; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
2441; X86-BMI1-NEXT:    retl
2442;
2443; X86-BMI2-LABEL: bextr32_b3_load_indexzext:
2444; X86-BMI2:       # %bb.0:
2445; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2446; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2447; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2448; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
2449; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
2450; X86-BMI2-NEXT:    retl
2451;
2452; X64-NOBMI-LABEL: bextr32_b3_load_indexzext:
2453; X64-NOBMI:       # %bb.0:
2454; X64-NOBMI-NEXT:    movl %esi, %ecx
2455; X64-NOBMI-NEXT:    movl (%rdi), %esi
2456; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2457; X64-NOBMI-NEXT:    shrl %cl, %esi
2458; X64-NOBMI-NEXT:    movl $-1, %eax
2459; X64-NOBMI-NEXT:    movl %edx, %ecx
2460; X64-NOBMI-NEXT:    shll %cl, %eax
2461; X64-NOBMI-NEXT:    notl %eax
2462; X64-NOBMI-NEXT:    andl %esi, %eax
2463; X64-NOBMI-NEXT:    retq
2464;
2465; X64-BMI1-LABEL: bextr32_b3_load_indexzext:
2466; X64-BMI1:       # %bb.0:
2467; X64-BMI1-NEXT:    shll $8, %edx
2468; X64-BMI1-NEXT:    orl %esi, %edx
2469; X64-BMI1-NEXT:    bextrl %edx, (%rdi), %eax
2470; X64-BMI1-NEXT:    retq
2471;
2472; X64-BMI2-LABEL: bextr32_b3_load_indexzext:
2473; X64-BMI2:       # %bb.0:
2474; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
2475; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2476; X64-BMI2-NEXT:    retq
2477  %val = load i32, ptr %w
2478  %skip = zext i8 %numskipbits to i32
2479  %shifted = lshr i32 %val, %skip
2480  %conv = zext i8 %numlowbits to i32
2481  %notmask = shl i32 -1, %conv
2482  %mask = xor i32 %notmask, -1
2483  %masked = and i32 %mask, %shifted
2484  ret i32 %masked
2485}
2486
2487define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2488; X86-NOBMI-LABEL: bextr32_b4_commutative:
2489; X86-NOBMI:       # %bb.0:
2490; X86-NOBMI-NEXT:    pushl %esi
2491; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2492; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2493; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2494; X86-NOBMI-NEXT:    shrl %cl, %esi
2495; X86-NOBMI-NEXT:    movl $-1, %eax
2496; X86-NOBMI-NEXT:    movl %edx, %ecx
2497; X86-NOBMI-NEXT:    shll %cl, %eax
2498; X86-NOBMI-NEXT:    notl %eax
2499; X86-NOBMI-NEXT:    andl %esi, %eax
2500; X86-NOBMI-NEXT:    popl %esi
2501; X86-NOBMI-NEXT:    retl
2502;
2503; X86-BMI1-LABEL: bextr32_b4_commutative:
2504; X86-BMI1:       # %bb.0:
2505; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2506; X86-BMI1-NEXT:    shll $8, %eax
2507; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2508; X86-BMI1-NEXT:    orl %eax, %ecx
2509; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
2510; X86-BMI1-NEXT:    retl
2511;
2512; X86-BMI2-LABEL: bextr32_b4_commutative:
2513; X86-BMI2:       # %bb.0:
2514; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2515; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2516; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
2517; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
2518; X86-BMI2-NEXT:    retl
2519;
2520; X64-NOBMI-LABEL: bextr32_b4_commutative:
2521; X64-NOBMI:       # %bb.0:
2522; X64-NOBMI-NEXT:    movl %esi, %ecx
2523; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2524; X64-NOBMI-NEXT:    shrl %cl, %edi
2525; X64-NOBMI-NEXT:    movl $-1, %eax
2526; X64-NOBMI-NEXT:    movl %edx, %ecx
2527; X64-NOBMI-NEXT:    shll %cl, %eax
2528; X64-NOBMI-NEXT:    notl %eax
2529; X64-NOBMI-NEXT:    andl %edi, %eax
2530; X64-NOBMI-NEXT:    retq
2531;
2532; X64-BMI1-LABEL: bextr32_b4_commutative:
2533; X64-BMI1:       # %bb.0:
2534; X64-BMI1-NEXT:    shll $8, %edx
2535; X64-BMI1-NEXT:    movzbl %sil, %eax
2536; X64-BMI1-NEXT:    orl %edx, %eax
2537; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
2538; X64-BMI1-NEXT:    retq
2539;
2540; X64-BMI2-LABEL: bextr32_b4_commutative:
2541; X64-BMI2:       # %bb.0:
2542; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
2543; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
2544; X64-BMI2-NEXT:    retq
2545  %shifted = lshr i32 %val, %numskipbits
2546  %notmask = shl i32 -1, %numlowbits
2547  %mask = xor i32 %notmask, -1
2548  %masked = and i32 %shifted, %mask ; swapped order
2549  ret i32 %masked
2550}
2551
2552define i32 @bextr32_b5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
2553; X86-NOBMI-LABEL: bextr32_b5_skipextrauses:
2554; X86-NOBMI:       # %bb.0:
2555; X86-NOBMI-NEXT:    pushl %edi
2556; X86-NOBMI-NEXT:    pushl %esi
2557; X86-NOBMI-NEXT:    pushl %eax
2558; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
2559; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
2560; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2561; X86-NOBMI-NEXT:    movl %eax, %ecx
2562; X86-NOBMI-NEXT:    shrl %cl, %edi
2563; X86-NOBMI-NEXT:    movl $-1, %esi
2564; X86-NOBMI-NEXT:    movl %edx, %ecx
2565; X86-NOBMI-NEXT:    shll %cl, %esi
2566; X86-NOBMI-NEXT:    notl %esi
2567; X86-NOBMI-NEXT:    andl %edi, %esi
2568; X86-NOBMI-NEXT:    movl %eax, (%esp)
2569; X86-NOBMI-NEXT:    calll use32@PLT
2570; X86-NOBMI-NEXT:    movl %esi, %eax
2571; X86-NOBMI-NEXT:    addl $4, %esp
2572; X86-NOBMI-NEXT:    popl %esi
2573; X86-NOBMI-NEXT:    popl %edi
2574; X86-NOBMI-NEXT:    retl
2575;
2576; X86-BMI1-LABEL: bextr32_b5_skipextrauses:
2577; X86-BMI1:       # %bb.0:
2578; X86-BMI1-NEXT:    pushl %esi
2579; X86-BMI1-NEXT:    subl $8, %esp
2580; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2581; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
2582; X86-BMI1-NEXT:    shll $8, %ecx
2583; X86-BMI1-NEXT:    movzbl %al, %edx
2584; X86-BMI1-NEXT:    orl %ecx, %edx
2585; X86-BMI1-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
2586; X86-BMI1-NEXT:    movl %eax, (%esp)
2587; X86-BMI1-NEXT:    calll use32@PLT
2588; X86-BMI1-NEXT:    movl %esi, %eax
2589; X86-BMI1-NEXT:    addl $8, %esp
2590; X86-BMI1-NEXT:    popl %esi
2591; X86-BMI1-NEXT:    retl
2592;
2593; X86-BMI2-LABEL: bextr32_b5_skipextrauses:
2594; X86-BMI2:       # %bb.0:
2595; X86-BMI2-NEXT:    pushl %esi
2596; X86-BMI2-NEXT:    subl $8, %esp
2597; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2598; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2599; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
2600; X86-BMI2-NEXT:    bzhil %eax, %edx, %esi
2601; X86-BMI2-NEXT:    movl %ecx, (%esp)
2602; X86-BMI2-NEXT:    calll use32@PLT
2603; X86-BMI2-NEXT:    movl %esi, %eax
2604; X86-BMI2-NEXT:    addl $8, %esp
2605; X86-BMI2-NEXT:    popl %esi
2606; X86-BMI2-NEXT:    retl
2607;
2608; X64-NOBMI-LABEL: bextr32_b5_skipextrauses:
2609; X64-NOBMI:       # %bb.0:
2610; X64-NOBMI-NEXT:    pushq %rbx
2611; X64-NOBMI-NEXT:    movl %esi, %ecx
2612; X64-NOBMI-NEXT:    shrl %cl, %edi
2613; X64-NOBMI-NEXT:    movl $-1, %ebx
2614; X64-NOBMI-NEXT:    movl %edx, %ecx
2615; X64-NOBMI-NEXT:    shll %cl, %ebx
2616; X64-NOBMI-NEXT:    notl %ebx
2617; X64-NOBMI-NEXT:    andl %edi, %ebx
2618; X64-NOBMI-NEXT:    movl %esi, %edi
2619; X64-NOBMI-NEXT:    callq use32@PLT
2620; X64-NOBMI-NEXT:    movl %ebx, %eax
2621; X64-NOBMI-NEXT:    popq %rbx
2622; X64-NOBMI-NEXT:    retq
2623;
2624; X64-BMI1-LABEL: bextr32_b5_skipextrauses:
2625; X64-BMI1:       # %bb.0:
2626; X64-BMI1-NEXT:    pushq %rbx
2627; X64-BMI1-NEXT:    shll $8, %edx
2628; X64-BMI1-NEXT:    movzbl %sil, %eax
2629; X64-BMI1-NEXT:    orl %edx, %eax
2630; X64-BMI1-NEXT:    bextrl %eax, %edi, %ebx
2631; X64-BMI1-NEXT:    movl %esi, %edi
2632; X64-BMI1-NEXT:    callq use32@PLT
2633; X64-BMI1-NEXT:    movl %ebx, %eax
2634; X64-BMI1-NEXT:    popq %rbx
2635; X64-BMI1-NEXT:    retq
2636;
2637; X64-BMI2-LABEL: bextr32_b5_skipextrauses:
2638; X64-BMI2:       # %bb.0:
2639; X64-BMI2-NEXT:    pushq %rbx
2640; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
2641; X64-BMI2-NEXT:    bzhil %edx, %eax, %ebx
2642; X64-BMI2-NEXT:    movl %esi, %edi
2643; X64-BMI2-NEXT:    callq use32@PLT
2644; X64-BMI2-NEXT:    movl %ebx, %eax
2645; X64-BMI2-NEXT:    popq %rbx
2646; X64-BMI2-NEXT:    retq
2647  %shifted = lshr i32 %val, %numskipbits
2648  %notmask = shl i32 -1, %numlowbits
2649  %mask = xor i32 %notmask, -1
2650  %masked = and i32 %mask, %shifted
2651  call void @use32(i32 %numskipbits)
2652  ret i32 %masked
2653}
2654
2655; 64-bit
2656
2657define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
2658; X86-NOBMI-LABEL: bextr64_b0:
2659; X86-NOBMI:       # %bb.0:
2660; X86-NOBMI-NEXT:    pushl %ebx
2661; X86-NOBMI-NEXT:    pushl %edi
2662; X86-NOBMI-NEXT:    pushl %esi
2663; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2664; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2665; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2666; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2667; X86-NOBMI-NEXT:    movl %eax, %edi
2668; X86-NOBMI-NEXT:    shrl %cl, %edi
2669; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2670; X86-NOBMI-NEXT:    xorl %eax, %eax
2671; X86-NOBMI-NEXT:    testb $32, %cl
2672; X86-NOBMI-NEXT:    je .LBB25_2
2673; X86-NOBMI-NEXT:  # %bb.1:
2674; X86-NOBMI-NEXT:    movl %edi, %esi
2675; X86-NOBMI-NEXT:    xorl %edi, %edi
2676; X86-NOBMI-NEXT:  .LBB25_2:
2677; X86-NOBMI-NEXT:    movl $-1, %edx
2678; X86-NOBMI-NEXT:    movl $-1, %ebx
2679; X86-NOBMI-NEXT:    movb %ch, %cl
2680; X86-NOBMI-NEXT:    shll %cl, %ebx
2681; X86-NOBMI-NEXT:    testb $32, %ch
2682; X86-NOBMI-NEXT:    jne .LBB25_3
2683; X86-NOBMI-NEXT:  # %bb.4:
2684; X86-NOBMI-NEXT:    movl %ebx, %eax
2685; X86-NOBMI-NEXT:    jmp .LBB25_5
2686; X86-NOBMI-NEXT:  .LBB25_3:
2687; X86-NOBMI-NEXT:    movl %ebx, %edx
2688; X86-NOBMI-NEXT:  .LBB25_5:
2689; X86-NOBMI-NEXT:    notl %edx
2690; X86-NOBMI-NEXT:    andl %edi, %edx
2691; X86-NOBMI-NEXT:    notl %eax
2692; X86-NOBMI-NEXT:    andl %esi, %eax
2693; X86-NOBMI-NEXT:    popl %esi
2694; X86-NOBMI-NEXT:    popl %edi
2695; X86-NOBMI-NEXT:    popl %ebx
2696; X86-NOBMI-NEXT:    retl
2697;
2698; X86-BMI1-LABEL: bextr64_b0:
2699; X86-BMI1:       # %bb.0:
2700; X86-BMI1-NEXT:    pushl %ebx
2701; X86-BMI1-NEXT:    pushl %edi
2702; X86-BMI1-NEXT:    pushl %esi
2703; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2704; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2705; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
2706; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
2707; X86-BMI1-NEXT:    movl %edi, %edx
2708; X86-BMI1-NEXT:    shrl %cl, %edx
2709; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
2710; X86-BMI1-NEXT:    testb $32, %cl
2711; X86-BMI1-NEXT:    je .LBB25_2
2712; X86-BMI1-NEXT:  # %bb.1:
2713; X86-BMI1-NEXT:    movl %edx, %esi
2714; X86-BMI1-NEXT:    xorl %edx, %edx
2715; X86-BMI1-NEXT:  .LBB25_2:
2716; X86-BMI1-NEXT:    movl $-1, %edi
2717; X86-BMI1-NEXT:    movl $-1, %ebx
2718; X86-BMI1-NEXT:    movl %eax, %ecx
2719; X86-BMI1-NEXT:    shll %cl, %ebx
2720; X86-BMI1-NEXT:    testb $32, %al
2721; X86-BMI1-NEXT:    je .LBB25_4
2722; X86-BMI1-NEXT:  # %bb.3:
2723; X86-BMI1-NEXT:    movl %ebx, %edi
2724; X86-BMI1-NEXT:    xorl %ebx, %ebx
2725; X86-BMI1-NEXT:  .LBB25_4:
2726; X86-BMI1-NEXT:    andnl %edx, %edi, %edx
2727; X86-BMI1-NEXT:    andnl %esi, %ebx, %eax
2728; X86-BMI1-NEXT:    popl %esi
2729; X86-BMI1-NEXT:    popl %edi
2730; X86-BMI1-NEXT:    popl %ebx
2731; X86-BMI1-NEXT:    retl
2732;
2733; X86-BMI2-LABEL: bextr64_b0:
2734; X86-BMI2:       # %bb.0:
2735; X86-BMI2-NEXT:    pushl %ebx
2736; X86-BMI2-NEXT:    pushl %esi
2737; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
2738; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2739; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2740; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2741; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
2742; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
2743; X86-BMI2-NEXT:    testb $32, %cl
2744; X86-BMI2-NEXT:    je .LBB25_2
2745; X86-BMI2-NEXT:  # %bb.1:
2746; X86-BMI2-NEXT:    movl %edx, %eax
2747; X86-BMI2-NEXT:    xorl %edx, %edx
2748; X86-BMI2-NEXT:  .LBB25_2:
2749; X86-BMI2-NEXT:    movl $-1, %esi
2750; X86-BMI2-NEXT:    shlxl %ebx, %esi, %ecx
2751; X86-BMI2-NEXT:    testb $32, %bl
2752; X86-BMI2-NEXT:    je .LBB25_4
2753; X86-BMI2-NEXT:  # %bb.3:
2754; X86-BMI2-NEXT:    movl %ecx, %esi
2755; X86-BMI2-NEXT:    xorl %ecx, %ecx
2756; X86-BMI2-NEXT:  .LBB25_4:
2757; X86-BMI2-NEXT:    andnl %edx, %esi, %edx
2758; X86-BMI2-NEXT:    andnl %eax, %ecx, %eax
2759; X86-BMI2-NEXT:    popl %esi
2760; X86-BMI2-NEXT:    popl %ebx
2761; X86-BMI2-NEXT:    retl
2762;
2763; X64-NOBMI-LABEL: bextr64_b0:
2764; X64-NOBMI:       # %bb.0:
2765; X64-NOBMI-NEXT:    movq %rsi, %rcx
2766; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
2767; X64-NOBMI-NEXT:    shrq %cl, %rdi
2768; X64-NOBMI-NEXT:    movq $-1, %rax
2769; X64-NOBMI-NEXT:    movl %edx, %ecx
2770; X64-NOBMI-NEXT:    shlq %cl, %rax
2771; X64-NOBMI-NEXT:    notq %rax
2772; X64-NOBMI-NEXT:    andq %rdi, %rax
2773; X64-NOBMI-NEXT:    retq
2774;
2775; X64-BMI1-LABEL: bextr64_b0:
2776; X64-BMI1:       # %bb.0:
2777; X64-BMI1-NEXT:    shll $8, %edx
2778; X64-BMI1-NEXT:    movzbl %sil, %eax
2779; X64-BMI1-NEXT:    orl %edx, %eax
2780; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
2781; X64-BMI1-NEXT:    retq
2782;
2783; X64-BMI2-LABEL: bextr64_b0:
2784; X64-BMI2:       # %bb.0:
2785; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2786; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2787; X64-BMI2-NEXT:    retq
2788  %shifted = lshr i64 %val, %numskipbits
2789  %notmask = shl i64 -1, %numlowbits
2790  %mask = xor i64 %notmask, -1
2791  %masked = and i64 %mask, %shifted
2792  ret i64 %masked
2793}
2794
2795define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
2796; X86-NOBMI-LABEL: bextr64_b1_indexzext:
2797; X86-NOBMI:       # %bb.0:
2798; X86-NOBMI-NEXT:    pushl %ebx
2799; X86-NOBMI-NEXT:    pushl %edi
2800; X86-NOBMI-NEXT:    pushl %esi
2801; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2802; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2803; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
2804; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2805; X86-NOBMI-NEXT:    movl %eax, %edi
2806; X86-NOBMI-NEXT:    shrl %cl, %edi
2807; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2808; X86-NOBMI-NEXT:    xorl %eax, %eax
2809; X86-NOBMI-NEXT:    testb $32, %cl
2810; X86-NOBMI-NEXT:    je .LBB26_2
2811; X86-NOBMI-NEXT:  # %bb.1:
2812; X86-NOBMI-NEXT:    movl %edi, %esi
2813; X86-NOBMI-NEXT:    xorl %edi, %edi
2814; X86-NOBMI-NEXT:  .LBB26_2:
2815; X86-NOBMI-NEXT:    movl $-1, %edx
2816; X86-NOBMI-NEXT:    movl $-1, %ebx
2817; X86-NOBMI-NEXT:    movb %ch, %cl
2818; X86-NOBMI-NEXT:    shll %cl, %ebx
2819; X86-NOBMI-NEXT:    testb $32, %ch
2820; X86-NOBMI-NEXT:    jne .LBB26_3
2821; X86-NOBMI-NEXT:  # %bb.4:
2822; X86-NOBMI-NEXT:    movl %ebx, %eax
2823; X86-NOBMI-NEXT:    jmp .LBB26_5
2824; X86-NOBMI-NEXT:  .LBB26_3:
2825; X86-NOBMI-NEXT:    movl %ebx, %edx
2826; X86-NOBMI-NEXT:  .LBB26_5:
2827; X86-NOBMI-NEXT:    notl %edx
2828; X86-NOBMI-NEXT:    andl %edi, %edx
2829; X86-NOBMI-NEXT:    notl %eax
2830; X86-NOBMI-NEXT:    andl %esi, %eax
2831; X86-NOBMI-NEXT:    popl %esi
2832; X86-NOBMI-NEXT:    popl %edi
2833; X86-NOBMI-NEXT:    popl %ebx
2834; X86-NOBMI-NEXT:    retl
2835;
2836; X86-BMI1-LABEL: bextr64_b1_indexzext:
2837; X86-BMI1:       # %bb.0:
2838; X86-BMI1-NEXT:    pushl %ebx
2839; X86-BMI1-NEXT:    pushl %edi
2840; X86-BMI1-NEXT:    pushl %esi
2841; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2842; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2843; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
2844; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
2845; X86-BMI1-NEXT:    movl %edi, %edx
2846; X86-BMI1-NEXT:    shrl %cl, %edx
2847; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
2848; X86-BMI1-NEXT:    testb $32, %cl
2849; X86-BMI1-NEXT:    je .LBB26_2
2850; X86-BMI1-NEXT:  # %bb.1:
2851; X86-BMI1-NEXT:    movl %edx, %esi
2852; X86-BMI1-NEXT:    xorl %edx, %edx
2853; X86-BMI1-NEXT:  .LBB26_2:
2854; X86-BMI1-NEXT:    movl $-1, %edi
2855; X86-BMI1-NEXT:    movl $-1, %ebx
2856; X86-BMI1-NEXT:    movl %eax, %ecx
2857; X86-BMI1-NEXT:    shll %cl, %ebx
2858; X86-BMI1-NEXT:    testb $32, %al
2859; X86-BMI1-NEXT:    je .LBB26_4
2860; X86-BMI1-NEXT:  # %bb.3:
2861; X86-BMI1-NEXT:    movl %ebx, %edi
2862; X86-BMI1-NEXT:    xorl %ebx, %ebx
2863; X86-BMI1-NEXT:  .LBB26_4:
2864; X86-BMI1-NEXT:    andnl %edx, %edi, %edx
2865; X86-BMI1-NEXT:    andnl %esi, %ebx, %eax
2866; X86-BMI1-NEXT:    popl %esi
2867; X86-BMI1-NEXT:    popl %edi
2868; X86-BMI1-NEXT:    popl %ebx
2869; X86-BMI1-NEXT:    retl
2870;
2871; X86-BMI2-LABEL: bextr64_b1_indexzext:
2872; X86-BMI2:       # %bb.0:
2873; X86-BMI2-NEXT:    pushl %ebx
2874; X86-BMI2-NEXT:    pushl %esi
2875; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
2876; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2877; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
2878; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
2879; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
2880; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
2881; X86-BMI2-NEXT:    testb $32, %cl
2882; X86-BMI2-NEXT:    je .LBB26_2
2883; X86-BMI2-NEXT:  # %bb.1:
2884; X86-BMI2-NEXT:    movl %edx, %eax
2885; X86-BMI2-NEXT:    xorl %edx, %edx
2886; X86-BMI2-NEXT:  .LBB26_2:
2887; X86-BMI2-NEXT:    movl $-1, %esi
2888; X86-BMI2-NEXT:    shlxl %ebx, %esi, %ecx
2889; X86-BMI2-NEXT:    testb $32, %bl
2890; X86-BMI2-NEXT:    je .LBB26_4
2891; X86-BMI2-NEXT:  # %bb.3:
2892; X86-BMI2-NEXT:    movl %ecx, %esi
2893; X86-BMI2-NEXT:    xorl %ecx, %ecx
2894; X86-BMI2-NEXT:  .LBB26_4:
2895; X86-BMI2-NEXT:    andnl %edx, %esi, %edx
2896; X86-BMI2-NEXT:    andnl %eax, %ecx, %eax
2897; X86-BMI2-NEXT:    popl %esi
2898; X86-BMI2-NEXT:    popl %ebx
2899; X86-BMI2-NEXT:    retl
2900;
2901; X64-NOBMI-LABEL: bextr64_b1_indexzext:
2902; X64-NOBMI:       # %bb.0:
2903; X64-NOBMI-NEXT:    movl %esi, %ecx
2904; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
2905; X64-NOBMI-NEXT:    shrq %cl, %rdi
2906; X64-NOBMI-NEXT:    movq $-1, %rax
2907; X64-NOBMI-NEXT:    movl %edx, %ecx
2908; X64-NOBMI-NEXT:    shlq %cl, %rax
2909; X64-NOBMI-NEXT:    notq %rax
2910; X64-NOBMI-NEXT:    andq %rdi, %rax
2911; X64-NOBMI-NEXT:    retq
2912;
2913; X64-BMI1-LABEL: bextr64_b1_indexzext:
2914; X64-BMI1:       # %bb.0:
2915; X64-BMI1-NEXT:    # kill: def $edx killed $edx def $rdx
2916; X64-BMI1-NEXT:    shll $8, %edx
2917; X64-BMI1-NEXT:    orl %esi, %edx
2918; X64-BMI1-NEXT:    bextrq %rdx, %rdi, %rax
2919; X64-BMI1-NEXT:    retq
2920;
2921; X64-BMI2-LABEL: bextr64_b1_indexzext:
2922; X64-BMI2:       # %bb.0:
2923; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
2924; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
2925; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
2926; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
2927; X64-BMI2-NEXT:    retq
2928  %skip = zext i8 %numskipbits to i64
2929  %shifted = lshr i64 %val, %skip
2930  %conv = zext i8 %numlowbits to i64
2931  %notmask = shl i64 -1, %conv
2932  %mask = xor i64 %notmask, -1
2933  %masked = and i64 %mask, %shifted
2934  ret i64 %masked
2935}
2936
2937define i64 @bextr64_b2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {
2938; X86-NOBMI-LABEL: bextr64_b2_load:
2939; X86-NOBMI:       # %bb.0:
2940; X86-NOBMI-NEXT:    pushl %ebx
2941; X86-NOBMI-NEXT:    pushl %edi
2942; X86-NOBMI-NEXT:    pushl %esi
2943; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
2944; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
2945; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
2946; X86-NOBMI-NEXT:    movl (%eax), %esi
2947; X86-NOBMI-NEXT:    movl 4(%eax), %eax
2948; X86-NOBMI-NEXT:    movl %eax, %edi
2949; X86-NOBMI-NEXT:    shrl %cl, %edi
2950; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
2951; X86-NOBMI-NEXT:    xorl %eax, %eax
2952; X86-NOBMI-NEXT:    testb $32, %cl
2953; X86-NOBMI-NEXT:    je .LBB27_2
2954; X86-NOBMI-NEXT:  # %bb.1:
2955; X86-NOBMI-NEXT:    movl %edi, %esi
2956; X86-NOBMI-NEXT:    xorl %edi, %edi
2957; X86-NOBMI-NEXT:  .LBB27_2:
2958; X86-NOBMI-NEXT:    movl $-1, %edx
2959; X86-NOBMI-NEXT:    movl $-1, %ebx
2960; X86-NOBMI-NEXT:    movb %ch, %cl
2961; X86-NOBMI-NEXT:    shll %cl, %ebx
2962; X86-NOBMI-NEXT:    testb $32, %ch
2963; X86-NOBMI-NEXT:    jne .LBB27_3
2964; X86-NOBMI-NEXT:  # %bb.4:
2965; X86-NOBMI-NEXT:    movl %ebx, %eax
2966; X86-NOBMI-NEXT:    jmp .LBB27_5
2967; X86-NOBMI-NEXT:  .LBB27_3:
2968; X86-NOBMI-NEXT:    movl %ebx, %edx
2969; X86-NOBMI-NEXT:  .LBB27_5:
2970; X86-NOBMI-NEXT:    notl %edx
2971; X86-NOBMI-NEXT:    andl %edi, %edx
2972; X86-NOBMI-NEXT:    notl %eax
2973; X86-NOBMI-NEXT:    andl %esi, %eax
2974; X86-NOBMI-NEXT:    popl %esi
2975; X86-NOBMI-NEXT:    popl %edi
2976; X86-NOBMI-NEXT:    popl %ebx
2977; X86-NOBMI-NEXT:    retl
2978;
2979; X86-BMI1-LABEL: bextr64_b2_load:
2980; X86-BMI1:       # %bb.0:
2981; X86-BMI1-NEXT:    pushl %ebx
2982; X86-BMI1-NEXT:    pushl %edi
2983; X86-BMI1-NEXT:    pushl %esi
2984; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
2985; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2986; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
2987; X86-BMI1-NEXT:    movl (%edx), %esi
2988; X86-BMI1-NEXT:    movl 4(%edx), %edi
2989; X86-BMI1-NEXT:    movl %edi, %edx
2990; X86-BMI1-NEXT:    shrl %cl, %edx
2991; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
2992; X86-BMI1-NEXT:    testb $32, %cl
2993; X86-BMI1-NEXT:    je .LBB27_2
2994; X86-BMI1-NEXT:  # %bb.1:
2995; X86-BMI1-NEXT:    movl %edx, %esi
2996; X86-BMI1-NEXT:    xorl %edx, %edx
2997; X86-BMI1-NEXT:  .LBB27_2:
2998; X86-BMI1-NEXT:    movl $-1, %edi
2999; X86-BMI1-NEXT:    movl $-1, %ebx
3000; X86-BMI1-NEXT:    movl %eax, %ecx
3001; X86-BMI1-NEXT:    shll %cl, %ebx
3002; X86-BMI1-NEXT:    testb $32, %al
3003; X86-BMI1-NEXT:    je .LBB27_4
3004; X86-BMI1-NEXT:  # %bb.3:
3005; X86-BMI1-NEXT:    movl %ebx, %edi
3006; X86-BMI1-NEXT:    xorl %ebx, %ebx
3007; X86-BMI1-NEXT:  .LBB27_4:
3008; X86-BMI1-NEXT:    andnl %edx, %edi, %edx
3009; X86-BMI1-NEXT:    andnl %esi, %ebx, %eax
3010; X86-BMI1-NEXT:    popl %esi
3011; X86-BMI1-NEXT:    popl %edi
3012; X86-BMI1-NEXT:    popl %ebx
3013; X86-BMI1-NEXT:    retl
3014;
3015; X86-BMI2-LABEL: bextr64_b2_load:
3016; X86-BMI2:       # %bb.0:
3017; X86-BMI2-NEXT:    pushl %ebx
3018; X86-BMI2-NEXT:    pushl %esi
3019; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
3020; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3021; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3022; X86-BMI2-NEXT:    movl (%edx), %eax
3023; X86-BMI2-NEXT:    movl 4(%edx), %esi
3024; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3025; X86-BMI2-NEXT:    shrdl %cl, %esi, %eax
3026; X86-BMI2-NEXT:    testb $32, %cl
3027; X86-BMI2-NEXT:    je .LBB27_2
3028; X86-BMI2-NEXT:  # %bb.1:
3029; X86-BMI2-NEXT:    movl %edx, %eax
3030; X86-BMI2-NEXT:    xorl %edx, %edx
3031; X86-BMI2-NEXT:  .LBB27_2:
3032; X86-BMI2-NEXT:    movl $-1, %esi
3033; X86-BMI2-NEXT:    shlxl %ebx, %esi, %ecx
3034; X86-BMI2-NEXT:    testb $32, %bl
3035; X86-BMI2-NEXT:    je .LBB27_4
3036; X86-BMI2-NEXT:  # %bb.3:
3037; X86-BMI2-NEXT:    movl %ecx, %esi
3038; X86-BMI2-NEXT:    xorl %ecx, %ecx
3039; X86-BMI2-NEXT:  .LBB27_4:
3040; X86-BMI2-NEXT:    andnl %edx, %esi, %edx
3041; X86-BMI2-NEXT:    andnl %eax, %ecx, %eax
3042; X86-BMI2-NEXT:    popl %esi
3043; X86-BMI2-NEXT:    popl %ebx
3044; X86-BMI2-NEXT:    retl
3045;
3046; X64-NOBMI-LABEL: bextr64_b2_load:
3047; X64-NOBMI:       # %bb.0:
3048; X64-NOBMI-NEXT:    movq %rsi, %rcx
3049; X64-NOBMI-NEXT:    movq (%rdi), %rsi
3050; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3051; X64-NOBMI-NEXT:    shrq %cl, %rsi
3052; X64-NOBMI-NEXT:    movq $-1, %rax
3053; X64-NOBMI-NEXT:    movl %edx, %ecx
3054; X64-NOBMI-NEXT:    shlq %cl, %rax
3055; X64-NOBMI-NEXT:    notq %rax
3056; X64-NOBMI-NEXT:    andq %rsi, %rax
3057; X64-NOBMI-NEXT:    retq
3058;
3059; X64-BMI1-LABEL: bextr64_b2_load:
3060; X64-BMI1:       # %bb.0:
3061; X64-BMI1-NEXT:    shll $8, %edx
3062; X64-BMI1-NEXT:    movzbl %sil, %eax
3063; X64-BMI1-NEXT:    orl %edx, %eax
3064; X64-BMI1-NEXT:    bextrq %rax, (%rdi), %rax
3065; X64-BMI1-NEXT:    retq
3066;
3067; X64-BMI2-LABEL: bextr64_b2_load:
3068; X64-BMI2:       # %bb.0:
3069; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
3070; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
3071; X64-BMI2-NEXT:    retq
3072  %val = load i64, ptr %w
3073  %shifted = lshr i64 %val, %numskipbits
3074  %notmask = shl i64 -1, %numlowbits
3075  %mask = xor i64 %notmask, -1
3076  %masked = and i64 %mask, %shifted
3077  ret i64 %masked
3078}
3079
3080define i64 @bextr64_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
3081; X86-NOBMI-LABEL: bextr64_b3_load_indexzext:
3082; X86-NOBMI:       # %bb.0:
3083; X86-NOBMI-NEXT:    pushl %ebx
3084; X86-NOBMI-NEXT:    pushl %edi
3085; X86-NOBMI-NEXT:    pushl %esi
3086; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
3087; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3088; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3089; X86-NOBMI-NEXT:    movl (%eax), %esi
3090; X86-NOBMI-NEXT:    movl 4(%eax), %eax
3091; X86-NOBMI-NEXT:    movl %eax, %edi
3092; X86-NOBMI-NEXT:    shrl %cl, %edi
3093; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
3094; X86-NOBMI-NEXT:    xorl %eax, %eax
3095; X86-NOBMI-NEXT:    testb $32, %cl
3096; X86-NOBMI-NEXT:    je .LBB28_2
3097; X86-NOBMI-NEXT:  # %bb.1:
3098; X86-NOBMI-NEXT:    movl %edi, %esi
3099; X86-NOBMI-NEXT:    xorl %edi, %edi
3100; X86-NOBMI-NEXT:  .LBB28_2:
3101; X86-NOBMI-NEXT:    movl $-1, %edx
3102; X86-NOBMI-NEXT:    movl $-1, %ebx
3103; X86-NOBMI-NEXT:    movb %ch, %cl
3104; X86-NOBMI-NEXT:    shll %cl, %ebx
3105; X86-NOBMI-NEXT:    testb $32, %ch
3106; X86-NOBMI-NEXT:    jne .LBB28_3
3107; X86-NOBMI-NEXT:  # %bb.4:
3108; X86-NOBMI-NEXT:    movl %ebx, %eax
3109; X86-NOBMI-NEXT:    jmp .LBB28_5
3110; X86-NOBMI-NEXT:  .LBB28_3:
3111; X86-NOBMI-NEXT:    movl %ebx, %edx
3112; X86-NOBMI-NEXT:  .LBB28_5:
3113; X86-NOBMI-NEXT:    notl %edx
3114; X86-NOBMI-NEXT:    andl %edi, %edx
3115; X86-NOBMI-NEXT:    notl %eax
3116; X86-NOBMI-NEXT:    andl %esi, %eax
3117; X86-NOBMI-NEXT:    popl %esi
3118; X86-NOBMI-NEXT:    popl %edi
3119; X86-NOBMI-NEXT:    popl %ebx
3120; X86-NOBMI-NEXT:    retl
3121;
3122; X86-BMI1-LABEL: bextr64_b3_load_indexzext:
3123; X86-BMI1:       # %bb.0:
3124; X86-BMI1-NEXT:    pushl %ebx
3125; X86-BMI1-NEXT:    pushl %edi
3126; X86-BMI1-NEXT:    pushl %esi
3127; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3128; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3129; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
3130; X86-BMI1-NEXT:    movl (%edx), %esi
3131; X86-BMI1-NEXT:    movl 4(%edx), %edi
3132; X86-BMI1-NEXT:    movl %edi, %edx
3133; X86-BMI1-NEXT:    shrl %cl, %edx
3134; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3135; X86-BMI1-NEXT:    testb $32, %cl
3136; X86-BMI1-NEXT:    je .LBB28_2
3137; X86-BMI1-NEXT:  # %bb.1:
3138; X86-BMI1-NEXT:    movl %edx, %esi
3139; X86-BMI1-NEXT:    xorl %edx, %edx
3140; X86-BMI1-NEXT:  .LBB28_2:
3141; X86-BMI1-NEXT:    movl $-1, %edi
3142; X86-BMI1-NEXT:    movl $-1, %ebx
3143; X86-BMI1-NEXT:    movl %eax, %ecx
3144; X86-BMI1-NEXT:    shll %cl, %ebx
3145; X86-BMI1-NEXT:    testb $32, %al
3146; X86-BMI1-NEXT:    je .LBB28_4
3147; X86-BMI1-NEXT:  # %bb.3:
3148; X86-BMI1-NEXT:    movl %ebx, %edi
3149; X86-BMI1-NEXT:    xorl %ebx, %ebx
3150; X86-BMI1-NEXT:  .LBB28_4:
3151; X86-BMI1-NEXT:    andnl %edx, %edi, %edx
3152; X86-BMI1-NEXT:    andnl %esi, %ebx, %eax
3153; X86-BMI1-NEXT:    popl %esi
3154; X86-BMI1-NEXT:    popl %edi
3155; X86-BMI1-NEXT:    popl %ebx
3156; X86-BMI1-NEXT:    retl
3157;
3158; X86-BMI2-LABEL: bextr64_b3_load_indexzext:
3159; X86-BMI2:       # %bb.0:
3160; X86-BMI2-NEXT:    pushl %ebx
3161; X86-BMI2-NEXT:    pushl %esi
3162; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
3163; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3164; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3165; X86-BMI2-NEXT:    movl (%edx), %eax
3166; X86-BMI2-NEXT:    movl 4(%edx), %esi
3167; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3168; X86-BMI2-NEXT:    shrdl %cl, %esi, %eax
3169; X86-BMI2-NEXT:    testb $32, %cl
3170; X86-BMI2-NEXT:    je .LBB28_2
3171; X86-BMI2-NEXT:  # %bb.1:
3172; X86-BMI2-NEXT:    movl %edx, %eax
3173; X86-BMI2-NEXT:    xorl %edx, %edx
3174; X86-BMI2-NEXT:  .LBB28_2:
3175; X86-BMI2-NEXT:    movl $-1, %esi
3176; X86-BMI2-NEXT:    shlxl %ebx, %esi, %ecx
3177; X86-BMI2-NEXT:    testb $32, %bl
3178; X86-BMI2-NEXT:    je .LBB28_4
3179; X86-BMI2-NEXT:  # %bb.3:
3180; X86-BMI2-NEXT:    movl %ecx, %esi
3181; X86-BMI2-NEXT:    xorl %ecx, %ecx
3182; X86-BMI2-NEXT:  .LBB28_4:
3183; X86-BMI2-NEXT:    andnl %edx, %esi, %edx
3184; X86-BMI2-NEXT:    andnl %eax, %ecx, %eax
3185; X86-BMI2-NEXT:    popl %esi
3186; X86-BMI2-NEXT:    popl %ebx
3187; X86-BMI2-NEXT:    retl
3188;
3189; X64-NOBMI-LABEL: bextr64_b3_load_indexzext:
3190; X64-NOBMI:       # %bb.0:
3191; X64-NOBMI-NEXT:    movl %esi, %ecx
3192; X64-NOBMI-NEXT:    movq (%rdi), %rsi
3193; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
3194; X64-NOBMI-NEXT:    shrq %cl, %rsi
3195; X64-NOBMI-NEXT:    movq $-1, %rax
3196; X64-NOBMI-NEXT:    movl %edx, %ecx
3197; X64-NOBMI-NEXT:    shlq %cl, %rax
3198; X64-NOBMI-NEXT:    notq %rax
3199; X64-NOBMI-NEXT:    andq %rsi, %rax
3200; X64-NOBMI-NEXT:    retq
3201;
3202; X64-BMI1-LABEL: bextr64_b3_load_indexzext:
3203; X64-BMI1:       # %bb.0:
3204; X64-BMI1-NEXT:    # kill: def $edx killed $edx def $rdx
3205; X64-BMI1-NEXT:    shll $8, %edx
3206; X64-BMI1-NEXT:    orl %esi, %edx
3207; X64-BMI1-NEXT:    bextrq %rdx, (%rdi), %rax
3208; X64-BMI1-NEXT:    retq
3209;
3210; X64-BMI2-LABEL: bextr64_b3_load_indexzext:
3211; X64-BMI2:       # %bb.0:
3212; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
3213; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
3214; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
3215; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
3216; X64-BMI2-NEXT:    retq
3217  %val = load i64, ptr %w
3218  %skip = zext i8 %numskipbits to i64
3219  %shifted = lshr i64 %val, %skip
3220  %conv = zext i8 %numlowbits to i64
3221  %notmask = shl i64 -1, %conv
3222  %mask = xor i64 %notmask, -1
3223  %masked = and i64 %mask, %shifted
3224  ret i64 %masked
3225}
3226
3227define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
3228; X86-NOBMI-LABEL: bextr64_b4_commutative:
3229; X86-NOBMI:       # %bb.0:
3230; X86-NOBMI-NEXT:    pushl %ebx
3231; X86-NOBMI-NEXT:    pushl %edi
3232; X86-NOBMI-NEXT:    pushl %esi
3233; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
3234; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
3235; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3236; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3237; X86-NOBMI-NEXT:    movl %esi, %edx
3238; X86-NOBMI-NEXT:    shrl %cl, %edx
3239; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
3240; X86-NOBMI-NEXT:    xorl %esi, %esi
3241; X86-NOBMI-NEXT:    testb $32, %cl
3242; X86-NOBMI-NEXT:    je .LBB29_2
3243; X86-NOBMI-NEXT:  # %bb.1:
3244; X86-NOBMI-NEXT:    movl %edx, %eax
3245; X86-NOBMI-NEXT:    xorl %edx, %edx
3246; X86-NOBMI-NEXT:  .LBB29_2:
3247; X86-NOBMI-NEXT:    movl $-1, %edi
3248; X86-NOBMI-NEXT:    movl $-1, %ebx
3249; X86-NOBMI-NEXT:    movb %ch, %cl
3250; X86-NOBMI-NEXT:    shll %cl, %ebx
3251; X86-NOBMI-NEXT:    testb $32, %ch
3252; X86-NOBMI-NEXT:    jne .LBB29_3
3253; X86-NOBMI-NEXT:  # %bb.4:
3254; X86-NOBMI-NEXT:    movl %ebx, %esi
3255; X86-NOBMI-NEXT:    jmp .LBB29_5
3256; X86-NOBMI-NEXT:  .LBB29_3:
3257; X86-NOBMI-NEXT:    movl %ebx, %edi
3258; X86-NOBMI-NEXT:  .LBB29_5:
3259; X86-NOBMI-NEXT:    notl %edi
3260; X86-NOBMI-NEXT:    andl %edi, %edx
3261; X86-NOBMI-NEXT:    notl %esi
3262; X86-NOBMI-NEXT:    andl %esi, %eax
3263; X86-NOBMI-NEXT:    popl %esi
3264; X86-NOBMI-NEXT:    popl %edi
3265; X86-NOBMI-NEXT:    popl %ebx
3266; X86-NOBMI-NEXT:    retl
3267;
3268; X86-BMI1-LABEL: bextr64_b4_commutative:
3269; X86-BMI1:       # %bb.0:
3270; X86-BMI1-NEXT:    pushl %ebx
3271; X86-BMI1-NEXT:    pushl %edi
3272; X86-BMI1-NEXT:    pushl %esi
3273; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3274; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3275; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
3276; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3277; X86-BMI1-NEXT:    movl %edi, %edx
3278; X86-BMI1-NEXT:    shrl %cl, %edx
3279; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3280; X86-BMI1-NEXT:    testb $32, %cl
3281; X86-BMI1-NEXT:    je .LBB29_2
3282; X86-BMI1-NEXT:  # %bb.1:
3283; X86-BMI1-NEXT:    movl %edx, %esi
3284; X86-BMI1-NEXT:    xorl %edx, %edx
3285; X86-BMI1-NEXT:  .LBB29_2:
3286; X86-BMI1-NEXT:    movl $-1, %edi
3287; X86-BMI1-NEXT:    movl $-1, %ebx
3288; X86-BMI1-NEXT:    movl %eax, %ecx
3289; X86-BMI1-NEXT:    shll %cl, %ebx
3290; X86-BMI1-NEXT:    testb $32, %al
3291; X86-BMI1-NEXT:    je .LBB29_4
3292; X86-BMI1-NEXT:  # %bb.3:
3293; X86-BMI1-NEXT:    movl %ebx, %edi
3294; X86-BMI1-NEXT:    xorl %ebx, %ebx
3295; X86-BMI1-NEXT:  .LBB29_4:
3296; X86-BMI1-NEXT:    andnl %edx, %edi, %edx
3297; X86-BMI1-NEXT:    andnl %esi, %ebx, %eax
3298; X86-BMI1-NEXT:    popl %esi
3299; X86-BMI1-NEXT:    popl %edi
3300; X86-BMI1-NEXT:    popl %ebx
3301; X86-BMI1-NEXT:    retl
3302;
3303; X86-BMI2-LABEL: bextr64_b4_commutative:
3304; X86-BMI2:       # %bb.0:
3305; X86-BMI2-NEXT:    pushl %ebx
3306; X86-BMI2-NEXT:    pushl %esi
3307; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
3308; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3309; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3310; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3311; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
3312; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
3313; X86-BMI2-NEXT:    testb $32, %cl
3314; X86-BMI2-NEXT:    je .LBB29_2
3315; X86-BMI2-NEXT:  # %bb.1:
3316; X86-BMI2-NEXT:    movl %edx, %eax
3317; X86-BMI2-NEXT:    xorl %edx, %edx
3318; X86-BMI2-NEXT:  .LBB29_2:
3319; X86-BMI2-NEXT:    movl $-1, %esi
3320; X86-BMI2-NEXT:    shlxl %ebx, %esi, %ecx
3321; X86-BMI2-NEXT:    testb $32, %bl
3322; X86-BMI2-NEXT:    je .LBB29_4
3323; X86-BMI2-NEXT:  # %bb.3:
3324; X86-BMI2-NEXT:    movl %ecx, %esi
3325; X86-BMI2-NEXT:    xorl %ecx, %ecx
3326; X86-BMI2-NEXT:  .LBB29_4:
3327; X86-BMI2-NEXT:    andnl %edx, %esi, %edx
3328; X86-BMI2-NEXT:    andnl %eax, %ecx, %eax
3329; X86-BMI2-NEXT:    popl %esi
3330; X86-BMI2-NEXT:    popl %ebx
3331; X86-BMI2-NEXT:    retl
3332;
3333; X64-NOBMI-LABEL: bextr64_b4_commutative:
3334; X64-NOBMI:       # %bb.0:
3335; X64-NOBMI-NEXT:    movq %rsi, %rcx
3336; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3337; X64-NOBMI-NEXT:    shrq %cl, %rdi
3338; X64-NOBMI-NEXT:    movq $-1, %rax
3339; X64-NOBMI-NEXT:    movl %edx, %ecx
3340; X64-NOBMI-NEXT:    shlq %cl, %rax
3341; X64-NOBMI-NEXT:    notq %rax
3342; X64-NOBMI-NEXT:    andq %rdi, %rax
3343; X64-NOBMI-NEXT:    retq
3344;
3345; X64-BMI1-LABEL: bextr64_b4_commutative:
3346; X64-BMI1:       # %bb.0:
3347; X64-BMI1-NEXT:    shll $8, %edx
3348; X64-BMI1-NEXT:    movzbl %sil, %eax
3349; X64-BMI1-NEXT:    orl %edx, %eax
3350; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
3351; X64-BMI1-NEXT:    retq
3352;
3353; X64-BMI2-LABEL: bextr64_b4_commutative:
3354; X64-BMI2:       # %bb.0:
3355; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3356; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
3357; X64-BMI2-NEXT:    retq
3358  %shifted = lshr i64 %val, %numskipbits
3359  %notmask = shl i64 -1, %numlowbits
3360  %mask = xor i64 %notmask, -1
3361  %masked = and i64 %shifted, %mask ; swapped order
3362  ret i64 %masked
3363}
3364
3365define i64 @bextr64_b5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
3366; X86-NOBMI-LABEL: bextr64_b5_skipextrauses:
3367; X86-NOBMI:       # %bb.0:
3368; X86-NOBMI-NEXT:    pushl %ebp
3369; X86-NOBMI-NEXT:    pushl %ebx
3370; X86-NOBMI-NEXT:    pushl %edi
3371; X86-NOBMI-NEXT:    pushl %esi
3372; X86-NOBMI-NEXT:    subl $12, %esp
3373; X86-NOBMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
3374; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
3375; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3376; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3377; X86-NOBMI-NEXT:    movl %esi, %ebp
3378; X86-NOBMI-NEXT:    movb %al, %cl
3379; X86-NOBMI-NEXT:    shrl %cl, %ebp
3380; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
3381; X86-NOBMI-NEXT:    xorl %ebx, %ebx
3382; X86-NOBMI-NEXT:    testb $32, %al
3383; X86-NOBMI-NEXT:    je .LBB30_2
3384; X86-NOBMI-NEXT:  # %bb.1:
3385; X86-NOBMI-NEXT:    movl %ebp, %edx
3386; X86-NOBMI-NEXT:    xorl %ebp, %ebp
3387; X86-NOBMI-NEXT:  .LBB30_2:
3388; X86-NOBMI-NEXT:    movl $-1, %edi
3389; X86-NOBMI-NEXT:    movl $-1, %esi
3390; X86-NOBMI-NEXT:    movb %ch, %cl
3391; X86-NOBMI-NEXT:    shll %cl, %esi
3392; X86-NOBMI-NEXT:    testb $32, %ch
3393; X86-NOBMI-NEXT:    jne .LBB30_3
3394; X86-NOBMI-NEXT:  # %bb.4:
3395; X86-NOBMI-NEXT:    movl %esi, %ebx
3396; X86-NOBMI-NEXT:    jmp .LBB30_5
3397; X86-NOBMI-NEXT:  .LBB30_3:
3398; X86-NOBMI-NEXT:    movl %esi, %edi
3399; X86-NOBMI-NEXT:  .LBB30_5:
3400; X86-NOBMI-NEXT:    notl %edi
3401; X86-NOBMI-NEXT:    andl %ebp, %edi
3402; X86-NOBMI-NEXT:    notl %ebx
3403; X86-NOBMI-NEXT:    andl %edx, %ebx
3404; X86-NOBMI-NEXT:    subl $8, %esp
3405; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
3406; X86-NOBMI-NEXT:    pushl %eax
3407; X86-NOBMI-NEXT:    calll use64@PLT
3408; X86-NOBMI-NEXT:    addl $16, %esp
3409; X86-NOBMI-NEXT:    movl %ebx, %eax
3410; X86-NOBMI-NEXT:    movl %edi, %edx
3411; X86-NOBMI-NEXT:    addl $12, %esp
3412; X86-NOBMI-NEXT:    popl %esi
3413; X86-NOBMI-NEXT:    popl %edi
3414; X86-NOBMI-NEXT:    popl %ebx
3415; X86-NOBMI-NEXT:    popl %ebp
3416; X86-NOBMI-NEXT:    retl
3417;
3418; X86-BMI1-LABEL: bextr64_b5_skipextrauses:
3419; X86-BMI1:       # %bb.0:
3420; X86-BMI1-NEXT:    pushl %ebp
3421; X86-BMI1-NEXT:    pushl %ebx
3422; X86-BMI1-NEXT:    pushl %edi
3423; X86-BMI1-NEXT:    pushl %esi
3424; X86-BMI1-NEXT:    subl $12, %esp
3425; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
3426; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3427; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ebx
3428; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
3429; X86-BMI1-NEXT:    movl %ebx, %esi
3430; X86-BMI1-NEXT:    movl %eax, %ecx
3431; X86-BMI1-NEXT:    shrl %cl, %esi
3432; X86-BMI1-NEXT:    shrdl %cl, %ebx, %edi
3433; X86-BMI1-NEXT:    testb $32, %al
3434; X86-BMI1-NEXT:    je .LBB30_2
3435; X86-BMI1-NEXT:  # %bb.1:
3436; X86-BMI1-NEXT:    movl %esi, %edi
3437; X86-BMI1-NEXT:    xorl %esi, %esi
3438; X86-BMI1-NEXT:  .LBB30_2:
3439; X86-BMI1-NEXT:    movl $-1, %ebx
3440; X86-BMI1-NEXT:    movl $-1, %ebp
3441; X86-BMI1-NEXT:    movl %edx, %ecx
3442; X86-BMI1-NEXT:    shll %cl, %ebp
3443; X86-BMI1-NEXT:    testb $32, %dl
3444; X86-BMI1-NEXT:    je .LBB30_4
3445; X86-BMI1-NEXT:  # %bb.3:
3446; X86-BMI1-NEXT:    movl %ebp, %ebx
3447; X86-BMI1-NEXT:    xorl %ebp, %ebp
3448; X86-BMI1-NEXT:  .LBB30_4:
3449; X86-BMI1-NEXT:    andnl %esi, %ebx, %esi
3450; X86-BMI1-NEXT:    andnl %edi, %ebp, %edi
3451; X86-BMI1-NEXT:    subl $8, %esp
3452; X86-BMI1-NEXT:    pushl {{[0-9]+}}(%esp)
3453; X86-BMI1-NEXT:    pushl %eax
3454; X86-BMI1-NEXT:    calll use64@PLT
3455; X86-BMI1-NEXT:    addl $16, %esp
3456; X86-BMI1-NEXT:    movl %edi, %eax
3457; X86-BMI1-NEXT:    movl %esi, %edx
3458; X86-BMI1-NEXT:    addl $12, %esp
3459; X86-BMI1-NEXT:    popl %esi
3460; X86-BMI1-NEXT:    popl %edi
3461; X86-BMI1-NEXT:    popl %ebx
3462; X86-BMI1-NEXT:    popl %ebp
3463; X86-BMI1-NEXT:    retl
3464;
3465; X86-BMI2-LABEL: bextr64_b5_skipextrauses:
3466; X86-BMI2:       # %bb.0:
3467; X86-BMI2-NEXT:    pushl %ebp
3468; X86-BMI2-NEXT:    pushl %ebx
3469; X86-BMI2-NEXT:    pushl %edi
3470; X86-BMI2-NEXT:    pushl %esi
3471; X86-BMI2-NEXT:    subl $12, %esp
3472; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
3473; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
3474; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3475; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3476; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
3477; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
3478; X86-BMI2-NEXT:    testb $32, %cl
3479; X86-BMI2-NEXT:    je .LBB30_2
3480; X86-BMI2-NEXT:  # %bb.1:
3481; X86-BMI2-NEXT:    movl %edx, %eax
3482; X86-BMI2-NEXT:    xorl %edx, %edx
3483; X86-BMI2-NEXT:  .LBB30_2:
3484; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ebp
3485; X86-BMI2-NEXT:    movl $-1, %esi
3486; X86-BMI2-NEXT:    shlxl %ebx, %esi, %edi
3487; X86-BMI2-NEXT:    testb $32, %bl
3488; X86-BMI2-NEXT:    je .LBB30_4
3489; X86-BMI2-NEXT:  # %bb.3:
3490; X86-BMI2-NEXT:    movl %edi, %esi
3491; X86-BMI2-NEXT:    xorl %edi, %edi
3492; X86-BMI2-NEXT:  .LBB30_4:
3493; X86-BMI2-NEXT:    andnl %edx, %esi, %esi
3494; X86-BMI2-NEXT:    andnl %eax, %edi, %edi
3495; X86-BMI2-NEXT:    subl $8, %esp
3496; X86-BMI2-NEXT:    pushl %ebp
3497; X86-BMI2-NEXT:    pushl %ecx
3498; X86-BMI2-NEXT:    calll use64@PLT
3499; X86-BMI2-NEXT:    addl $16, %esp
3500; X86-BMI2-NEXT:    movl %edi, %eax
3501; X86-BMI2-NEXT:    movl %esi, %edx
3502; X86-BMI2-NEXT:    addl $12, %esp
3503; X86-BMI2-NEXT:    popl %esi
3504; X86-BMI2-NEXT:    popl %edi
3505; X86-BMI2-NEXT:    popl %ebx
3506; X86-BMI2-NEXT:    popl %ebp
3507; X86-BMI2-NEXT:    retl
3508;
3509; X64-NOBMI-LABEL: bextr64_b5_skipextrauses:
3510; X64-NOBMI:       # %bb.0:
3511; X64-NOBMI-NEXT:    pushq %rbx
3512; X64-NOBMI-NEXT:    movl %esi, %ecx
3513; X64-NOBMI-NEXT:    shrq %cl, %rdi
3514; X64-NOBMI-NEXT:    movq $-1, %rbx
3515; X64-NOBMI-NEXT:    movl %edx, %ecx
3516; X64-NOBMI-NEXT:    shlq %cl, %rbx
3517; X64-NOBMI-NEXT:    notq %rbx
3518; X64-NOBMI-NEXT:    andq %rdi, %rbx
3519; X64-NOBMI-NEXT:    movq %rsi, %rdi
3520; X64-NOBMI-NEXT:    callq use64@PLT
3521; X64-NOBMI-NEXT:    movq %rbx, %rax
3522; X64-NOBMI-NEXT:    popq %rbx
3523; X64-NOBMI-NEXT:    retq
3524;
3525; X64-BMI1-LABEL: bextr64_b5_skipextrauses:
3526; X64-BMI1:       # %bb.0:
3527; X64-BMI1-NEXT:    pushq %rbx
3528; X64-BMI1-NEXT:    shll $8, %edx
3529; X64-BMI1-NEXT:    movzbl %sil, %eax
3530; X64-BMI1-NEXT:    orl %edx, %eax
3531; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rbx
3532; X64-BMI1-NEXT:    movq %rsi, %rdi
3533; X64-BMI1-NEXT:    callq use64@PLT
3534; X64-BMI1-NEXT:    movq %rbx, %rax
3535; X64-BMI1-NEXT:    popq %rbx
3536; X64-BMI1-NEXT:    retq
3537;
3538; X64-BMI2-LABEL: bextr64_b5_skipextrauses:
3539; X64-BMI2:       # %bb.0:
3540; X64-BMI2-NEXT:    pushq %rbx
3541; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3542; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
3543; X64-BMI2-NEXT:    movq %rsi, %rdi
3544; X64-BMI2-NEXT:    callq use64@PLT
3545; X64-BMI2-NEXT:    movq %rbx, %rax
3546; X64-BMI2-NEXT:    popq %rbx
3547; X64-BMI2-NEXT:    retq
3548  %shifted = lshr i64 %val, %numskipbits
3549  %notmask = shl i64 -1, %numlowbits
3550  %mask = xor i64 %notmask, -1
3551  %masked = and i64 %mask, %shifted
3552  call void @use64(i64 %numskipbits)
3553  ret i64 %masked
3554}
3555
3556; 64-bit, but with 32-bit output
3557
3558; Everything done in 64-bit, truncation happens last.
3559define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3560; X86-NOBMI-LABEL: bextr64_32_b0:
3561; X86-NOBMI:       # %bb.0:
3562; X86-NOBMI-NEXT:    pushl %edi
3563; X86-NOBMI-NEXT:    pushl %esi
3564; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
3565; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3566; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3567; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3568; X86-NOBMI-NEXT:    movl %edi, %eax
3569; X86-NOBMI-NEXT:    shrl %cl, %eax
3570; X86-NOBMI-NEXT:    shrdl %cl, %edi, %esi
3571; X86-NOBMI-NEXT:    testb $32, %cl
3572; X86-NOBMI-NEXT:    jne .LBB31_2
3573; X86-NOBMI-NEXT:  # %bb.1:
3574; X86-NOBMI-NEXT:    movl %esi, %eax
3575; X86-NOBMI-NEXT:  .LBB31_2:
3576; X86-NOBMI-NEXT:    movl $-1, %esi
3577; X86-NOBMI-NEXT:    movl %edx, %ecx
3578; X86-NOBMI-NEXT:    shll %cl, %esi
3579; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3580; X86-NOBMI-NEXT:    testb $32, %dl
3581; X86-NOBMI-NEXT:    jne .LBB31_4
3582; X86-NOBMI-NEXT:  # %bb.3:
3583; X86-NOBMI-NEXT:    movl %esi, %ecx
3584; X86-NOBMI-NEXT:  .LBB31_4:
3585; X86-NOBMI-NEXT:    notl %ecx
3586; X86-NOBMI-NEXT:    andl %ecx, %eax
3587; X86-NOBMI-NEXT:    popl %esi
3588; X86-NOBMI-NEXT:    popl %edi
3589; X86-NOBMI-NEXT:    retl
3590;
3591; X86-BMI1-LABEL: bextr64_32_b0:
3592; X86-BMI1:       # %bb.0:
3593; X86-BMI1-NEXT:    pushl %edi
3594; X86-BMI1-NEXT:    pushl %esi
3595; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3596; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3597; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
3598; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3599; X86-BMI1-NEXT:    movl %edi, %edx
3600; X86-BMI1-NEXT:    shrl %cl, %edx
3601; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3602; X86-BMI1-NEXT:    testb $32, %cl
3603; X86-BMI1-NEXT:    jne .LBB31_2
3604; X86-BMI1-NEXT:  # %bb.1:
3605; X86-BMI1-NEXT:    movl %esi, %edx
3606; X86-BMI1-NEXT:  .LBB31_2:
3607; X86-BMI1-NEXT:    movl $-1, %esi
3608; X86-BMI1-NEXT:    movl %eax, %ecx
3609; X86-BMI1-NEXT:    shll %cl, %esi
3610; X86-BMI1-NEXT:    xorl %ecx, %ecx
3611; X86-BMI1-NEXT:    testb $32, %al
3612; X86-BMI1-NEXT:    jne .LBB31_4
3613; X86-BMI1-NEXT:  # %bb.3:
3614; X86-BMI1-NEXT:    movl %esi, %ecx
3615; X86-BMI1-NEXT:  .LBB31_4:
3616; X86-BMI1-NEXT:    andnl %edx, %ecx, %eax
3617; X86-BMI1-NEXT:    popl %esi
3618; X86-BMI1-NEXT:    popl %edi
3619; X86-BMI1-NEXT:    retl
3620;
3621; X86-BMI2-LABEL: bextr64_32_b0:
3622; X86-BMI2:       # %bb.0:
3623; X86-BMI2-NEXT:    pushl %esi
3624; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3625; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3626; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3627; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3628; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
3629; X86-BMI2-NEXT:    testb $32, %cl
3630; X86-BMI2-NEXT:    je .LBB31_2
3631; X86-BMI2-NEXT:  # %bb.1:
3632; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3633; X86-BMI2-NEXT:  .LBB31_2:
3634; X86-BMI2-NEXT:    xorl %ecx, %ecx
3635; X86-BMI2-NEXT:    testb $32, %al
3636; X86-BMI2-NEXT:    jne .LBB31_4
3637; X86-BMI2-NEXT:  # %bb.3:
3638; X86-BMI2-NEXT:    movl $-1, %ecx
3639; X86-BMI2-NEXT:    shlxl %eax, %ecx, %ecx
3640; X86-BMI2-NEXT:  .LBB31_4:
3641; X86-BMI2-NEXT:    andnl %edx, %ecx, %eax
3642; X86-BMI2-NEXT:    popl %esi
3643; X86-BMI2-NEXT:    retl
3644;
3645; X64-NOBMI-LABEL: bextr64_32_b0:
3646; X64-NOBMI:       # %bb.0:
3647; X64-NOBMI-NEXT:    movq %rsi, %rcx
3648; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3649; X64-NOBMI-NEXT:    shrq %cl, %rdi
3650; X64-NOBMI-NEXT:    movq $-1, %rax
3651; X64-NOBMI-NEXT:    movl %edx, %ecx
3652; X64-NOBMI-NEXT:    shlq %cl, %rax
3653; X64-NOBMI-NEXT:    notl %eax
3654; X64-NOBMI-NEXT:    andl %edi, %eax
3655; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
3656; X64-NOBMI-NEXT:    retq
3657;
3658; X64-BMI1-LABEL: bextr64_32_b0:
3659; X64-BMI1:       # %bb.0:
3660; X64-BMI1-NEXT:    shll $8, %edx
3661; X64-BMI1-NEXT:    movzbl %sil, %eax
3662; X64-BMI1-NEXT:    orl %edx, %eax
3663; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
3664; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
3665; X64-BMI1-NEXT:    retq
3666;
3667; X64-BMI2-LABEL: bextr64_32_b0:
3668; X64-BMI2:       # %bb.0:
3669; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3670; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
3671; X64-BMI2-NEXT:    retq
3672  %shiftedval = lshr i64 %val, %numskipbits
3673  %widenumlowbits = zext i8 %numlowbits to i64
3674  %notmask = shl nsw i64 -1, %widenumlowbits
3675  %mask = xor i64 %notmask, -1
3676  %wideres = and i64 %shiftedval, %mask
3677  %res = trunc i64 %wideres to i32
3678  ret i32 %res
3679}
3680
3681; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
3682define i32 @bextr64_32_b1(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3683; X86-NOBMI-LABEL: bextr64_32_b1:
3684; X86-NOBMI:       # %bb.0:
3685; X86-NOBMI-NEXT:    pushl %edi
3686; X86-NOBMI-NEXT:    pushl %esi
3687; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
3688; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3689; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3690; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3691; X86-NOBMI-NEXT:    movl %edi, %esi
3692; X86-NOBMI-NEXT:    shrl %cl, %esi
3693; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
3694; X86-NOBMI-NEXT:    testb $32, %cl
3695; X86-NOBMI-NEXT:    jne .LBB32_2
3696; X86-NOBMI-NEXT:  # %bb.1:
3697; X86-NOBMI-NEXT:    movl %eax, %esi
3698; X86-NOBMI-NEXT:  .LBB32_2:
3699; X86-NOBMI-NEXT:    movl $-1, %eax
3700; X86-NOBMI-NEXT:    movl %edx, %ecx
3701; X86-NOBMI-NEXT:    shll %cl, %eax
3702; X86-NOBMI-NEXT:    notl %eax
3703; X86-NOBMI-NEXT:    andl %esi, %eax
3704; X86-NOBMI-NEXT:    popl %esi
3705; X86-NOBMI-NEXT:    popl %edi
3706; X86-NOBMI-NEXT:    retl
3707;
3708; X86-BMI1-LABEL: bextr64_32_b1:
3709; X86-BMI1:       # %bb.0:
3710; X86-BMI1-NEXT:    pushl %edi
3711; X86-BMI1-NEXT:    pushl %esi
3712; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3713; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3714; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
3715; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3716; X86-BMI1-NEXT:    movl %edi, %edx
3717; X86-BMI1-NEXT:    shrl %cl, %edx
3718; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3719; X86-BMI1-NEXT:    testb $32, %cl
3720; X86-BMI1-NEXT:    jne .LBB32_2
3721; X86-BMI1-NEXT:  # %bb.1:
3722; X86-BMI1-NEXT:    movl %esi, %edx
3723; X86-BMI1-NEXT:  .LBB32_2:
3724; X86-BMI1-NEXT:    shll $8, %eax
3725; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
3726; X86-BMI1-NEXT:    popl %esi
3727; X86-BMI1-NEXT:    popl %edi
3728; X86-BMI1-NEXT:    retl
3729;
3730; X86-BMI2-LABEL: bextr64_32_b1:
3731; X86-BMI2:       # %bb.0:
3732; X86-BMI2-NEXT:    pushl %esi
3733; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3734; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3735; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3736; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3737; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
3738; X86-BMI2-NEXT:    testb $32, %cl
3739; X86-BMI2-NEXT:    je .LBB32_2
3740; X86-BMI2-NEXT:  # %bb.1:
3741; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3742; X86-BMI2-NEXT:  .LBB32_2:
3743; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
3744; X86-BMI2-NEXT:    popl %esi
3745; X86-BMI2-NEXT:    retl
3746;
3747; X64-NOBMI-LABEL: bextr64_32_b1:
3748; X64-NOBMI:       # %bb.0:
3749; X64-NOBMI-NEXT:    movq %rsi, %rcx
3750; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3751; X64-NOBMI-NEXT:    shrq %cl, %rdi
3752; X64-NOBMI-NEXT:    movl $-1, %eax
3753; X64-NOBMI-NEXT:    movl %edx, %ecx
3754; X64-NOBMI-NEXT:    shll %cl, %eax
3755; X64-NOBMI-NEXT:    notl %eax
3756; X64-NOBMI-NEXT:    andl %edi, %eax
3757; X64-NOBMI-NEXT:    retq
3758;
3759; X64-BMI1-LABEL: bextr64_32_b1:
3760; X64-BMI1:       # %bb.0:
3761; X64-BMI1-NEXT:    shll $8, %edx
3762; X64-BMI1-NEXT:    movzbl %sil, %eax
3763; X64-BMI1-NEXT:    orl %edx, %eax
3764; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
3765; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
3766; X64-BMI1-NEXT:    retq
3767;
3768; X64-BMI2-LABEL: bextr64_32_b1:
3769; X64-BMI2:       # %bb.0:
3770; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3771; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
3772; X64-BMI2-NEXT:    retq
3773  %shiftedval = lshr i64 %val, %numskipbits
3774  %truncshiftedval = trunc i64 %shiftedval to i32
3775  %widenumlowbits = zext i8 %numlowbits to i32
3776  %notmask = shl nsw i32 -1, %widenumlowbits
3777  %mask = xor i32 %notmask, -1
3778  %res = and i32 %truncshiftedval, %mask
3779  ret i32 %res
3780}
3781
3782; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
3783; Masking is 64-bit. Then truncation.
3784define i32 @bextr64_32_b2(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3785; X86-NOBMI-LABEL: bextr64_32_b2:
3786; X86-NOBMI:       # %bb.0:
3787; X86-NOBMI-NEXT:    pushl %edi
3788; X86-NOBMI-NEXT:    pushl %esi
3789; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
3790; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3791; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
3792; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3793; X86-NOBMI-NEXT:    movl %edi, %esi
3794; X86-NOBMI-NEXT:    shrl %cl, %esi
3795; X86-NOBMI-NEXT:    shrdl %cl, %edi, %eax
3796; X86-NOBMI-NEXT:    testb $32, %cl
3797; X86-NOBMI-NEXT:    jne .LBB33_2
3798; X86-NOBMI-NEXT:  # %bb.1:
3799; X86-NOBMI-NEXT:    movl %eax, %esi
3800; X86-NOBMI-NEXT:  .LBB33_2:
3801; X86-NOBMI-NEXT:    movl $-1, %eax
3802; X86-NOBMI-NEXT:    movl %edx, %ecx
3803; X86-NOBMI-NEXT:    shll %cl, %eax
3804; X86-NOBMI-NEXT:    notl %eax
3805; X86-NOBMI-NEXT:    andl %esi, %eax
3806; X86-NOBMI-NEXT:    popl %esi
3807; X86-NOBMI-NEXT:    popl %edi
3808; X86-NOBMI-NEXT:    retl
3809;
3810; X86-BMI1-LABEL: bextr64_32_b2:
3811; X86-BMI1:       # %bb.0:
3812; X86-BMI1-NEXT:    pushl %edi
3813; X86-BMI1-NEXT:    pushl %esi
3814; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3815; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3816; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
3817; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3818; X86-BMI1-NEXT:    movl %edi, %edx
3819; X86-BMI1-NEXT:    shrl %cl, %edx
3820; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3821; X86-BMI1-NEXT:    testb $32, %cl
3822; X86-BMI1-NEXT:    jne .LBB33_2
3823; X86-BMI1-NEXT:  # %bb.1:
3824; X86-BMI1-NEXT:    movl %esi, %edx
3825; X86-BMI1-NEXT:  .LBB33_2:
3826; X86-BMI1-NEXT:    shll $8, %eax
3827; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
3828; X86-BMI1-NEXT:    popl %esi
3829; X86-BMI1-NEXT:    popl %edi
3830; X86-BMI1-NEXT:    retl
3831;
3832; X86-BMI2-LABEL: bextr64_32_b2:
3833; X86-BMI2:       # %bb.0:
3834; X86-BMI2-NEXT:    pushl %esi
3835; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3836; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3837; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3838; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3839; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
3840; X86-BMI2-NEXT:    testb $32, %cl
3841; X86-BMI2-NEXT:    je .LBB33_2
3842; X86-BMI2-NEXT:  # %bb.1:
3843; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3844; X86-BMI2-NEXT:  .LBB33_2:
3845; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
3846; X86-BMI2-NEXT:    popl %esi
3847; X86-BMI2-NEXT:    retl
3848;
3849; X64-NOBMI-LABEL: bextr64_32_b2:
3850; X64-NOBMI:       # %bb.0:
3851; X64-NOBMI-NEXT:    movq %rsi, %rcx
3852; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3853; X64-NOBMI-NEXT:    shrq %cl, %rdi
3854; X64-NOBMI-NEXT:    movl $-1, %eax
3855; X64-NOBMI-NEXT:    movl %edx, %ecx
3856; X64-NOBMI-NEXT:    shll %cl, %eax
3857; X64-NOBMI-NEXT:    notl %eax
3858; X64-NOBMI-NEXT:    andl %edi, %eax
3859; X64-NOBMI-NEXT:    retq
3860;
3861; X64-BMI1-LABEL: bextr64_32_b2:
3862; X64-BMI1:       # %bb.0:
3863; X64-BMI1-NEXT:    shll $8, %edx
3864; X64-BMI1-NEXT:    movzbl %sil, %eax
3865; X64-BMI1-NEXT:    orl %edx, %eax
3866; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
3867; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
3868; X64-BMI1-NEXT:    retq
3869;
3870; X64-BMI2-LABEL: bextr64_32_b2:
3871; X64-BMI2:       # %bb.0:
3872; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3873; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
3874; X64-BMI2-NEXT:    retq
3875  %shiftedval = lshr i64 %val, %numskipbits
3876  %widenumlowbits = zext i8 %numlowbits to i32
3877  %notmask = shl nsw i32 -1, %widenumlowbits
3878  %mask = xor i32 %notmask, -1
3879  %zextmask = zext i32 %mask to i64
3880  %wideres = and i64 %shiftedval, %zextmask
3881  %res = trunc i64 %wideres to i32
3882  ret i32 %res
3883}
3884
3885; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit.
3886; Masking is 64-bit. Then truncation.
3887define i32 @bextr64_32_b3(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
3888; X86-NOBMI-LABEL: bextr64_32_b3:
3889; X86-NOBMI:       # %bb.0:
3890; X86-NOBMI-NEXT:    pushl %edi
3891; X86-NOBMI-NEXT:    pushl %esi
3892; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
3893; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3894; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
3895; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
3896; X86-NOBMI-NEXT:    movl %edi, %eax
3897; X86-NOBMI-NEXT:    shrl %cl, %eax
3898; X86-NOBMI-NEXT:    shrdl %cl, %edi, %esi
3899; X86-NOBMI-NEXT:    testb $32, %cl
3900; X86-NOBMI-NEXT:    jne .LBB34_2
3901; X86-NOBMI-NEXT:  # %bb.1:
3902; X86-NOBMI-NEXT:    movl %esi, %eax
3903; X86-NOBMI-NEXT:  .LBB34_2:
3904; X86-NOBMI-NEXT:    movl $-1, %esi
3905; X86-NOBMI-NEXT:    movl %edx, %ecx
3906; X86-NOBMI-NEXT:    shll %cl, %esi
3907; X86-NOBMI-NEXT:    xorl %ecx, %ecx
3908; X86-NOBMI-NEXT:    testb $32, %dl
3909; X86-NOBMI-NEXT:    jne .LBB34_4
3910; X86-NOBMI-NEXT:  # %bb.3:
3911; X86-NOBMI-NEXT:    movl %esi, %ecx
3912; X86-NOBMI-NEXT:  .LBB34_4:
3913; X86-NOBMI-NEXT:    notl %ecx
3914; X86-NOBMI-NEXT:    andl %ecx, %eax
3915; X86-NOBMI-NEXT:    popl %esi
3916; X86-NOBMI-NEXT:    popl %edi
3917; X86-NOBMI-NEXT:    retl
3918;
3919; X86-BMI1-LABEL: bextr64_32_b3:
3920; X86-BMI1:       # %bb.0:
3921; X86-BMI1-NEXT:    pushl %edi
3922; X86-BMI1-NEXT:    pushl %esi
3923; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3924; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3925; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
3926; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
3927; X86-BMI1-NEXT:    movl %edi, %edx
3928; X86-BMI1-NEXT:    shrl %cl, %edx
3929; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
3930; X86-BMI1-NEXT:    testb $32, %cl
3931; X86-BMI1-NEXT:    jne .LBB34_2
3932; X86-BMI1-NEXT:  # %bb.1:
3933; X86-BMI1-NEXT:    movl %esi, %edx
3934; X86-BMI1-NEXT:  .LBB34_2:
3935; X86-BMI1-NEXT:    movl $-1, %esi
3936; X86-BMI1-NEXT:    movl %eax, %ecx
3937; X86-BMI1-NEXT:    shll %cl, %esi
3938; X86-BMI1-NEXT:    xorl %ecx, %ecx
3939; X86-BMI1-NEXT:    testb $32, %al
3940; X86-BMI1-NEXT:    jne .LBB34_4
3941; X86-BMI1-NEXT:  # %bb.3:
3942; X86-BMI1-NEXT:    movl %esi, %ecx
3943; X86-BMI1-NEXT:  .LBB34_4:
3944; X86-BMI1-NEXT:    andnl %edx, %ecx, %eax
3945; X86-BMI1-NEXT:    popl %esi
3946; X86-BMI1-NEXT:    popl %edi
3947; X86-BMI1-NEXT:    retl
3948;
3949; X86-BMI2-LABEL: bextr64_32_b3:
3950; X86-BMI2:       # %bb.0:
3951; X86-BMI2-NEXT:    pushl %esi
3952; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
3953; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
3954; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
3955; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
3956; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
3957; X86-BMI2-NEXT:    testb $32, %cl
3958; X86-BMI2-NEXT:    je .LBB34_2
3959; X86-BMI2-NEXT:  # %bb.1:
3960; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
3961; X86-BMI2-NEXT:  .LBB34_2:
3962; X86-BMI2-NEXT:    xorl %ecx, %ecx
3963; X86-BMI2-NEXT:    testb $32, %al
3964; X86-BMI2-NEXT:    jne .LBB34_4
3965; X86-BMI2-NEXT:  # %bb.3:
3966; X86-BMI2-NEXT:    movl $-1, %ecx
3967; X86-BMI2-NEXT:    shlxl %eax, %ecx, %ecx
3968; X86-BMI2-NEXT:  .LBB34_4:
3969; X86-BMI2-NEXT:    andnl %edx, %ecx, %eax
3970; X86-BMI2-NEXT:    popl %esi
3971; X86-BMI2-NEXT:    retl
3972;
3973; X64-NOBMI-LABEL: bextr64_32_b3:
3974; X64-NOBMI:       # %bb.0:
3975; X64-NOBMI-NEXT:    movq %rsi, %rcx
3976; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
3977; X64-NOBMI-NEXT:    shrq %cl, %rdi
3978; X64-NOBMI-NEXT:    movl $4294967295, %eax # imm = 0xFFFFFFFF
3979; X64-NOBMI-NEXT:    movl $4294967295, %esi # imm = 0xFFFFFFFF
3980; X64-NOBMI-NEXT:    movl %edx, %ecx
3981; X64-NOBMI-NEXT:    shlq %cl, %rsi
3982; X64-NOBMI-NEXT:    xorl %esi, %eax
3983; X64-NOBMI-NEXT:    andl %edi, %eax
3984; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
3985; X64-NOBMI-NEXT:    retq
3986;
3987; X64-BMI1-LABEL: bextr64_32_b3:
3988; X64-BMI1:       # %bb.0:
3989; X64-BMI1-NEXT:    shll $8, %edx
3990; X64-BMI1-NEXT:    movzbl %sil, %eax
3991; X64-BMI1-NEXT:    orl %edx, %eax
3992; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
3993; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
3994; X64-BMI1-NEXT:    retq
3995;
3996; X64-BMI2-LABEL: bextr64_32_b3:
3997; X64-BMI2:       # %bb.0:
3998; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
3999; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
4000; X64-BMI2-NEXT:    retq
4001  %shiftedval = lshr i64 %val, %numskipbits
4002  %widenumlowbits = zext i8 %numlowbits to i64
4003  %notmask = shl nsw i64 4294967295, %widenumlowbits
4004  %mask = xor i64 %notmask, 4294967295
4005  %wideres = and i64 %shiftedval, %mask
4006  %res = trunc i64 %wideres to i32
4007  ret i32 %res
4008}
4009
4010; ---------------------------------------------------------------------------- ;
4011; Pattern c. 32-bit
4012; ---------------------------------------------------------------------------- ;
4013
4014define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
4015; X86-NOBMI-LABEL: bextr32_c0:
4016; X86-NOBMI:       # %bb.0:
4017; X86-NOBMI-NEXT:    pushl %edi
4018; X86-NOBMI-NEXT:    pushl %esi
4019; X86-NOBMI-NEXT:    pushl %eax
4020; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4021; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4022; X86-NOBMI-NEXT:    shrl %cl, %edi
4023; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4024; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4025; X86-NOBMI-NEXT:    movl $-1, %esi
4026; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4027; X86-NOBMI-NEXT:    shrl %cl, %esi
4028; X86-NOBMI-NEXT:    movl %esi, (%esp)
4029; X86-NOBMI-NEXT:    calll use32@PLT
4030; X86-NOBMI-NEXT:    andl %edi, %esi
4031; X86-NOBMI-NEXT:    movl %esi, %eax
4032; X86-NOBMI-NEXT:    addl $4, %esp
4033; X86-NOBMI-NEXT:    popl %esi
4034; X86-NOBMI-NEXT:    popl %edi
4035; X86-NOBMI-NEXT:    retl
4036;
4037; X86-BMI1-LABEL: bextr32_c0:
4038; X86-BMI1:       # %bb.0:
4039; X86-BMI1-NEXT:    pushl %edi
4040; X86-BMI1-NEXT:    pushl %esi
4041; X86-BMI1-NEXT:    pushl %eax
4042; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4043; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
4044; X86-BMI1-NEXT:    shrl %cl, %edi
4045; X86-BMI1-NEXT:    xorl %ecx, %ecx
4046; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4047; X86-BMI1-NEXT:    movl $-1, %esi
4048; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4049; X86-BMI1-NEXT:    shrl %cl, %esi
4050; X86-BMI1-NEXT:    movl %esi, (%esp)
4051; X86-BMI1-NEXT:    calll use32@PLT
4052; X86-BMI1-NEXT:    andl %edi, %esi
4053; X86-BMI1-NEXT:    movl %esi, %eax
4054; X86-BMI1-NEXT:    addl $4, %esp
4055; X86-BMI1-NEXT:    popl %esi
4056; X86-BMI1-NEXT:    popl %edi
4057; X86-BMI1-NEXT:    retl
4058;
4059; X86-BMI2-LABEL: bextr32_c0:
4060; X86-BMI2:       # %bb.0:
4061; X86-BMI2-NEXT:    pushl %ebx
4062; X86-BMI2-NEXT:    pushl %esi
4063; X86-BMI2-NEXT:    pushl %eax
4064; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4065; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
4066; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
4067; X86-BMI2-NEXT:    movl $-1, %eax
4068; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4069; X86-BMI2-NEXT:    movl %eax, (%esp)
4070; X86-BMI2-NEXT:    calll use32@PLT
4071; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
4072; X86-BMI2-NEXT:    addl $4, %esp
4073; X86-BMI2-NEXT:    popl %esi
4074; X86-BMI2-NEXT:    popl %ebx
4075; X86-BMI2-NEXT:    retl
4076;
4077; X64-NOBMI-LABEL: bextr32_c0:
4078; X64-NOBMI:       # %bb.0:
4079; X64-NOBMI-NEXT:    pushq %rbp
4080; X64-NOBMI-NEXT:    pushq %rbx
4081; X64-NOBMI-NEXT:    pushq %rax
4082; X64-NOBMI-NEXT:    movl %esi, %ecx
4083; X64-NOBMI-NEXT:    movl %edi, %ebx
4084; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4085; X64-NOBMI-NEXT:    shrl %cl, %ebx
4086; X64-NOBMI-NEXT:    negb %dl
4087; X64-NOBMI-NEXT:    movl $-1, %ebp
4088; X64-NOBMI-NEXT:    movl %edx, %ecx
4089; X64-NOBMI-NEXT:    shrl %cl, %ebp
4090; X64-NOBMI-NEXT:    movl %ebp, %edi
4091; X64-NOBMI-NEXT:    callq use32@PLT
4092; X64-NOBMI-NEXT:    andl %ebx, %ebp
4093; X64-NOBMI-NEXT:    movl %ebp, %eax
4094; X64-NOBMI-NEXT:    addq $8, %rsp
4095; X64-NOBMI-NEXT:    popq %rbx
4096; X64-NOBMI-NEXT:    popq %rbp
4097; X64-NOBMI-NEXT:    retq
4098;
4099; X64-BMI1-LABEL: bextr32_c0:
4100; X64-BMI1:       # %bb.0:
4101; X64-BMI1-NEXT:    pushq %rbp
4102; X64-BMI1-NEXT:    pushq %rbx
4103; X64-BMI1-NEXT:    pushq %rax
4104; X64-BMI1-NEXT:    movl %esi, %ecx
4105; X64-BMI1-NEXT:    movl %edi, %ebx
4106; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4107; X64-BMI1-NEXT:    shrl %cl, %ebx
4108; X64-BMI1-NEXT:    negb %dl
4109; X64-BMI1-NEXT:    movl $-1, %ebp
4110; X64-BMI1-NEXT:    movl %edx, %ecx
4111; X64-BMI1-NEXT:    shrl %cl, %ebp
4112; X64-BMI1-NEXT:    movl %ebp, %edi
4113; X64-BMI1-NEXT:    callq use32@PLT
4114; X64-BMI1-NEXT:    andl %ebx, %ebp
4115; X64-BMI1-NEXT:    movl %ebp, %eax
4116; X64-BMI1-NEXT:    addq $8, %rsp
4117; X64-BMI1-NEXT:    popq %rbx
4118; X64-BMI1-NEXT:    popq %rbp
4119; X64-BMI1-NEXT:    retq
4120;
4121; X64-BMI2-LABEL: bextr32_c0:
4122; X64-BMI2:       # %bb.0:
4123; X64-BMI2-NEXT:    pushq %rbp
4124; X64-BMI2-NEXT:    pushq %rbx
4125; X64-BMI2-NEXT:    pushq %rax
4126; X64-BMI2-NEXT:    movl %edx, %ebx
4127; X64-BMI2-NEXT:    shrxl %esi, %edi, %ebp
4128; X64-BMI2-NEXT:    movl $-1, %eax
4129; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4130; X64-BMI2-NEXT:    callq use32@PLT
4131; X64-BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4132; X64-BMI2-NEXT:    addq $8, %rsp
4133; X64-BMI2-NEXT:    popq %rbx
4134; X64-BMI2-NEXT:    popq %rbp
4135; X64-BMI2-NEXT:    retq
4136  %shifted = lshr i32 %val, %numskipbits
4137  %numhighbits = sub i32 32, %numlowbits
4138  %mask = lshr i32 -1, %numhighbits
4139  call void @use32(i32 %mask)
4140  %masked = and i32 %mask, %shifted
4141  ret i32 %masked
4142}
4143
4144define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
4145; X86-NOBMI-LABEL: bextr32_c1_indexzext:
4146; X86-NOBMI:       # %bb.0:
4147; X86-NOBMI-NEXT:    pushl %edi
4148; X86-NOBMI-NEXT:    pushl %esi
4149; X86-NOBMI-NEXT:    pushl %eax
4150; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4151; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4152; X86-NOBMI-NEXT:    shrl %cl, %edi
4153; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4154; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4155; X86-NOBMI-NEXT:    movl $-1, %esi
4156; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4157; X86-NOBMI-NEXT:    shrl %cl, %esi
4158; X86-NOBMI-NEXT:    movl %esi, (%esp)
4159; X86-NOBMI-NEXT:    calll use32@PLT
4160; X86-NOBMI-NEXT:    andl %edi, %esi
4161; X86-NOBMI-NEXT:    movl %esi, %eax
4162; X86-NOBMI-NEXT:    addl $4, %esp
4163; X86-NOBMI-NEXT:    popl %esi
4164; X86-NOBMI-NEXT:    popl %edi
4165; X86-NOBMI-NEXT:    retl
4166;
4167; X86-BMI1-LABEL: bextr32_c1_indexzext:
4168; X86-BMI1:       # %bb.0:
4169; X86-BMI1-NEXT:    pushl %edi
4170; X86-BMI1-NEXT:    pushl %esi
4171; X86-BMI1-NEXT:    pushl %eax
4172; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4173; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
4174; X86-BMI1-NEXT:    shrl %cl, %edi
4175; X86-BMI1-NEXT:    xorl %ecx, %ecx
4176; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4177; X86-BMI1-NEXT:    movl $-1, %esi
4178; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4179; X86-BMI1-NEXT:    shrl %cl, %esi
4180; X86-BMI1-NEXT:    movl %esi, (%esp)
4181; X86-BMI1-NEXT:    calll use32@PLT
4182; X86-BMI1-NEXT:    andl %edi, %esi
4183; X86-BMI1-NEXT:    movl %esi, %eax
4184; X86-BMI1-NEXT:    addl $4, %esp
4185; X86-BMI1-NEXT:    popl %esi
4186; X86-BMI1-NEXT:    popl %edi
4187; X86-BMI1-NEXT:    retl
4188;
4189; X86-BMI2-LABEL: bextr32_c1_indexzext:
4190; X86-BMI2:       # %bb.0:
4191; X86-BMI2-NEXT:    pushl %ebx
4192; X86-BMI2-NEXT:    pushl %esi
4193; X86-BMI2-NEXT:    pushl %eax
4194; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4195; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
4196; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
4197; X86-BMI2-NEXT:    movl $-1, %eax
4198; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4199; X86-BMI2-NEXT:    movl %eax, (%esp)
4200; X86-BMI2-NEXT:    calll use32@PLT
4201; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
4202; X86-BMI2-NEXT:    addl $4, %esp
4203; X86-BMI2-NEXT:    popl %esi
4204; X86-BMI2-NEXT:    popl %ebx
4205; X86-BMI2-NEXT:    retl
4206;
4207; X64-NOBMI-LABEL: bextr32_c1_indexzext:
4208; X64-NOBMI:       # %bb.0:
4209; X64-NOBMI-NEXT:    pushq %rbp
4210; X64-NOBMI-NEXT:    pushq %rbx
4211; X64-NOBMI-NEXT:    pushq %rax
4212; X64-NOBMI-NEXT:    movl %esi, %ecx
4213; X64-NOBMI-NEXT:    movl %edi, %ebx
4214; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4215; X64-NOBMI-NEXT:    shrl %cl, %ebx
4216; X64-NOBMI-NEXT:    negb %dl
4217; X64-NOBMI-NEXT:    movl $-1, %ebp
4218; X64-NOBMI-NEXT:    movl %edx, %ecx
4219; X64-NOBMI-NEXT:    shrl %cl, %ebp
4220; X64-NOBMI-NEXT:    movl %ebp, %edi
4221; X64-NOBMI-NEXT:    callq use32@PLT
4222; X64-NOBMI-NEXT:    andl %ebx, %ebp
4223; X64-NOBMI-NEXT:    movl %ebp, %eax
4224; X64-NOBMI-NEXT:    addq $8, %rsp
4225; X64-NOBMI-NEXT:    popq %rbx
4226; X64-NOBMI-NEXT:    popq %rbp
4227; X64-NOBMI-NEXT:    retq
4228;
4229; X64-BMI1-LABEL: bextr32_c1_indexzext:
4230; X64-BMI1:       # %bb.0:
4231; X64-BMI1-NEXT:    pushq %rbp
4232; X64-BMI1-NEXT:    pushq %rbx
4233; X64-BMI1-NEXT:    pushq %rax
4234; X64-BMI1-NEXT:    movl %esi, %ecx
4235; X64-BMI1-NEXT:    movl %edi, %ebx
4236; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4237; X64-BMI1-NEXT:    shrl %cl, %ebx
4238; X64-BMI1-NEXT:    negb %dl
4239; X64-BMI1-NEXT:    movl $-1, %ebp
4240; X64-BMI1-NEXT:    movl %edx, %ecx
4241; X64-BMI1-NEXT:    shrl %cl, %ebp
4242; X64-BMI1-NEXT:    movl %ebp, %edi
4243; X64-BMI1-NEXT:    callq use32@PLT
4244; X64-BMI1-NEXT:    andl %ebx, %ebp
4245; X64-BMI1-NEXT:    movl %ebp, %eax
4246; X64-BMI1-NEXT:    addq $8, %rsp
4247; X64-BMI1-NEXT:    popq %rbx
4248; X64-BMI1-NEXT:    popq %rbp
4249; X64-BMI1-NEXT:    retq
4250;
4251; X64-BMI2-LABEL: bextr32_c1_indexzext:
4252; X64-BMI2:       # %bb.0:
4253; X64-BMI2-NEXT:    pushq %rbp
4254; X64-BMI2-NEXT:    pushq %rbx
4255; X64-BMI2-NEXT:    pushq %rax
4256; X64-BMI2-NEXT:    movl %edx, %ebx
4257; X64-BMI2-NEXT:    shrxl %esi, %edi, %ebp
4258; X64-BMI2-NEXT:    movl $-1, %eax
4259; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4260; X64-BMI2-NEXT:    callq use32@PLT
4261; X64-BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4262; X64-BMI2-NEXT:    addq $8, %rsp
4263; X64-BMI2-NEXT:    popq %rbx
4264; X64-BMI2-NEXT:    popq %rbp
4265; X64-BMI2-NEXT:    retq
4266  %skip = zext i8 %numskipbits to i32
4267  %shifted = lshr i32 %val, %skip
4268  %numhighbits = sub i8 32, %numlowbits
4269  %sh_prom = zext i8 %numhighbits to i32
4270  %mask = lshr i32 -1, %sh_prom
4271  call void @use32(i32 %mask)
4272  %masked = and i32 %mask, %shifted
4273  ret i32 %masked
4274}
4275
4276define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {
4277; X86-NOBMI-LABEL: bextr32_c2_load:
4278; X86-NOBMI:       # %bb.0:
4279; X86-NOBMI-NEXT:    pushl %edi
4280; X86-NOBMI-NEXT:    pushl %esi
4281; X86-NOBMI-NEXT:    pushl %eax
4282; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4283; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4284; X86-NOBMI-NEXT:    movl (%eax), %edi
4285; X86-NOBMI-NEXT:    shrl %cl, %edi
4286; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4287; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4288; X86-NOBMI-NEXT:    movl $-1, %esi
4289; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4290; X86-NOBMI-NEXT:    shrl %cl, %esi
4291; X86-NOBMI-NEXT:    movl %esi, (%esp)
4292; X86-NOBMI-NEXT:    calll use32@PLT
4293; X86-NOBMI-NEXT:    andl %edi, %esi
4294; X86-NOBMI-NEXT:    movl %esi, %eax
4295; X86-NOBMI-NEXT:    addl $4, %esp
4296; X86-NOBMI-NEXT:    popl %esi
4297; X86-NOBMI-NEXT:    popl %edi
4298; X86-NOBMI-NEXT:    retl
4299;
4300; X86-BMI1-LABEL: bextr32_c2_load:
4301; X86-BMI1:       # %bb.0:
4302; X86-BMI1-NEXT:    pushl %edi
4303; X86-BMI1-NEXT:    pushl %esi
4304; X86-BMI1-NEXT:    pushl %eax
4305; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4306; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
4307; X86-BMI1-NEXT:    movl (%eax), %edi
4308; X86-BMI1-NEXT:    shrl %cl, %edi
4309; X86-BMI1-NEXT:    xorl %ecx, %ecx
4310; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4311; X86-BMI1-NEXT:    movl $-1, %esi
4312; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4313; X86-BMI1-NEXT:    shrl %cl, %esi
4314; X86-BMI1-NEXT:    movl %esi, (%esp)
4315; X86-BMI1-NEXT:    calll use32@PLT
4316; X86-BMI1-NEXT:    andl %edi, %esi
4317; X86-BMI1-NEXT:    movl %esi, %eax
4318; X86-BMI1-NEXT:    addl $4, %esp
4319; X86-BMI1-NEXT:    popl %esi
4320; X86-BMI1-NEXT:    popl %edi
4321; X86-BMI1-NEXT:    retl
4322;
4323; X86-BMI2-LABEL: bextr32_c2_load:
4324; X86-BMI2:       # %bb.0:
4325; X86-BMI2-NEXT:    pushl %ebx
4326; X86-BMI2-NEXT:    pushl %esi
4327; X86-BMI2-NEXT:    pushl %eax
4328; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4329; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4330; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4331; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %esi
4332; X86-BMI2-NEXT:    movl $-1, %eax
4333; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4334; X86-BMI2-NEXT:    movl %eax, (%esp)
4335; X86-BMI2-NEXT:    calll use32@PLT
4336; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
4337; X86-BMI2-NEXT:    addl $4, %esp
4338; X86-BMI2-NEXT:    popl %esi
4339; X86-BMI2-NEXT:    popl %ebx
4340; X86-BMI2-NEXT:    retl
4341;
4342; X64-NOBMI-LABEL: bextr32_c2_load:
4343; X64-NOBMI:       # %bb.0:
4344; X64-NOBMI-NEXT:    pushq %rbp
4345; X64-NOBMI-NEXT:    pushq %rbx
4346; X64-NOBMI-NEXT:    pushq %rax
4347; X64-NOBMI-NEXT:    movl %esi, %ecx
4348; X64-NOBMI-NEXT:    movl (%rdi), %ebp
4349; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4350; X64-NOBMI-NEXT:    shrl %cl, %ebp
4351; X64-NOBMI-NEXT:    negb %dl
4352; X64-NOBMI-NEXT:    movl $-1, %ebx
4353; X64-NOBMI-NEXT:    movl %edx, %ecx
4354; X64-NOBMI-NEXT:    shrl %cl, %ebx
4355; X64-NOBMI-NEXT:    movl %ebx, %edi
4356; X64-NOBMI-NEXT:    callq use32@PLT
4357; X64-NOBMI-NEXT:    andl %ebp, %ebx
4358; X64-NOBMI-NEXT:    movl %ebx, %eax
4359; X64-NOBMI-NEXT:    addq $8, %rsp
4360; X64-NOBMI-NEXT:    popq %rbx
4361; X64-NOBMI-NEXT:    popq %rbp
4362; X64-NOBMI-NEXT:    retq
4363;
4364; X64-BMI1-LABEL: bextr32_c2_load:
4365; X64-BMI1:       # %bb.0:
4366; X64-BMI1-NEXT:    pushq %rbp
4367; X64-BMI1-NEXT:    pushq %rbx
4368; X64-BMI1-NEXT:    pushq %rax
4369; X64-BMI1-NEXT:    movl %esi, %ecx
4370; X64-BMI1-NEXT:    movl (%rdi), %ebp
4371; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4372; X64-BMI1-NEXT:    shrl %cl, %ebp
4373; X64-BMI1-NEXT:    negb %dl
4374; X64-BMI1-NEXT:    movl $-1, %ebx
4375; X64-BMI1-NEXT:    movl %edx, %ecx
4376; X64-BMI1-NEXT:    shrl %cl, %ebx
4377; X64-BMI1-NEXT:    movl %ebx, %edi
4378; X64-BMI1-NEXT:    callq use32@PLT
4379; X64-BMI1-NEXT:    andl %ebp, %ebx
4380; X64-BMI1-NEXT:    movl %ebx, %eax
4381; X64-BMI1-NEXT:    addq $8, %rsp
4382; X64-BMI1-NEXT:    popq %rbx
4383; X64-BMI1-NEXT:    popq %rbp
4384; X64-BMI1-NEXT:    retq
4385;
4386; X64-BMI2-LABEL: bextr32_c2_load:
4387; X64-BMI2:       # %bb.0:
4388; X64-BMI2-NEXT:    pushq %rbp
4389; X64-BMI2-NEXT:    pushq %rbx
4390; X64-BMI2-NEXT:    pushq %rax
4391; X64-BMI2-NEXT:    movl %edx, %ebx
4392; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
4393; X64-BMI2-NEXT:    movl $-1, %eax
4394; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4395; X64-BMI2-NEXT:    callq use32@PLT
4396; X64-BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4397; X64-BMI2-NEXT:    addq $8, %rsp
4398; X64-BMI2-NEXT:    popq %rbx
4399; X64-BMI2-NEXT:    popq %rbp
4400; X64-BMI2-NEXT:    retq
4401  %val = load i32, ptr %w
4402  %shifted = lshr i32 %val, %numskipbits
4403  %numhighbits = sub i32 32, %numlowbits
4404  %mask = lshr i32 -1, %numhighbits
4405  call void @use32(i32 %mask)
4406  %masked = and i32 %mask, %shifted
4407  ret i32 %masked
4408}
4409
4410define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {
4411; X86-NOBMI-LABEL: bextr32_c3_load_indexzext:
4412; X86-NOBMI:       # %bb.0:
4413; X86-NOBMI-NEXT:    pushl %edi
4414; X86-NOBMI-NEXT:    pushl %esi
4415; X86-NOBMI-NEXT:    pushl %eax
4416; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4417; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4418; X86-NOBMI-NEXT:    movl (%eax), %edi
4419; X86-NOBMI-NEXT:    shrl %cl, %edi
4420; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4421; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4422; X86-NOBMI-NEXT:    movl $-1, %esi
4423; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4424; X86-NOBMI-NEXT:    shrl %cl, %esi
4425; X86-NOBMI-NEXT:    movl %esi, (%esp)
4426; X86-NOBMI-NEXT:    calll use32@PLT
4427; X86-NOBMI-NEXT:    andl %edi, %esi
4428; X86-NOBMI-NEXT:    movl %esi, %eax
4429; X86-NOBMI-NEXT:    addl $4, %esp
4430; X86-NOBMI-NEXT:    popl %esi
4431; X86-NOBMI-NEXT:    popl %edi
4432; X86-NOBMI-NEXT:    retl
4433;
4434; X86-BMI1-LABEL: bextr32_c3_load_indexzext:
4435; X86-BMI1:       # %bb.0:
4436; X86-BMI1-NEXT:    pushl %edi
4437; X86-BMI1-NEXT:    pushl %esi
4438; X86-BMI1-NEXT:    pushl %eax
4439; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4440; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
4441; X86-BMI1-NEXT:    movl (%eax), %edi
4442; X86-BMI1-NEXT:    shrl %cl, %edi
4443; X86-BMI1-NEXT:    xorl %ecx, %ecx
4444; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4445; X86-BMI1-NEXT:    movl $-1, %esi
4446; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4447; X86-BMI1-NEXT:    shrl %cl, %esi
4448; X86-BMI1-NEXT:    movl %esi, (%esp)
4449; X86-BMI1-NEXT:    calll use32@PLT
4450; X86-BMI1-NEXT:    andl %edi, %esi
4451; X86-BMI1-NEXT:    movl %esi, %eax
4452; X86-BMI1-NEXT:    addl $4, %esp
4453; X86-BMI1-NEXT:    popl %esi
4454; X86-BMI1-NEXT:    popl %edi
4455; X86-BMI1-NEXT:    retl
4456;
4457; X86-BMI2-LABEL: bextr32_c3_load_indexzext:
4458; X86-BMI2:       # %bb.0:
4459; X86-BMI2-NEXT:    pushl %ebx
4460; X86-BMI2-NEXT:    pushl %esi
4461; X86-BMI2-NEXT:    pushl %eax
4462; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4463; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4464; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4465; X86-BMI2-NEXT:    shrxl %ecx, (%eax), %esi
4466; X86-BMI2-NEXT:    movl $-1, %eax
4467; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4468; X86-BMI2-NEXT:    movl %eax, (%esp)
4469; X86-BMI2-NEXT:    calll use32@PLT
4470; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
4471; X86-BMI2-NEXT:    addl $4, %esp
4472; X86-BMI2-NEXT:    popl %esi
4473; X86-BMI2-NEXT:    popl %ebx
4474; X86-BMI2-NEXT:    retl
4475;
4476; X64-NOBMI-LABEL: bextr32_c3_load_indexzext:
4477; X64-NOBMI:       # %bb.0:
4478; X64-NOBMI-NEXT:    pushq %rbp
4479; X64-NOBMI-NEXT:    pushq %rbx
4480; X64-NOBMI-NEXT:    pushq %rax
4481; X64-NOBMI-NEXT:    movl %esi, %ecx
4482; X64-NOBMI-NEXT:    movl (%rdi), %ebp
4483; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4484; X64-NOBMI-NEXT:    shrl %cl, %ebp
4485; X64-NOBMI-NEXT:    negb %dl
4486; X64-NOBMI-NEXT:    movl $-1, %ebx
4487; X64-NOBMI-NEXT:    movl %edx, %ecx
4488; X64-NOBMI-NEXT:    shrl %cl, %ebx
4489; X64-NOBMI-NEXT:    movl %ebx, %edi
4490; X64-NOBMI-NEXT:    callq use32@PLT
4491; X64-NOBMI-NEXT:    andl %ebp, %ebx
4492; X64-NOBMI-NEXT:    movl %ebx, %eax
4493; X64-NOBMI-NEXT:    addq $8, %rsp
4494; X64-NOBMI-NEXT:    popq %rbx
4495; X64-NOBMI-NEXT:    popq %rbp
4496; X64-NOBMI-NEXT:    retq
4497;
4498; X64-BMI1-LABEL: bextr32_c3_load_indexzext:
4499; X64-BMI1:       # %bb.0:
4500; X64-BMI1-NEXT:    pushq %rbp
4501; X64-BMI1-NEXT:    pushq %rbx
4502; X64-BMI1-NEXT:    pushq %rax
4503; X64-BMI1-NEXT:    movl %esi, %ecx
4504; X64-BMI1-NEXT:    movl (%rdi), %ebp
4505; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4506; X64-BMI1-NEXT:    shrl %cl, %ebp
4507; X64-BMI1-NEXT:    negb %dl
4508; X64-BMI1-NEXT:    movl $-1, %ebx
4509; X64-BMI1-NEXT:    movl %edx, %ecx
4510; X64-BMI1-NEXT:    shrl %cl, %ebx
4511; X64-BMI1-NEXT:    movl %ebx, %edi
4512; X64-BMI1-NEXT:    callq use32@PLT
4513; X64-BMI1-NEXT:    andl %ebp, %ebx
4514; X64-BMI1-NEXT:    movl %ebx, %eax
4515; X64-BMI1-NEXT:    addq $8, %rsp
4516; X64-BMI1-NEXT:    popq %rbx
4517; X64-BMI1-NEXT:    popq %rbp
4518; X64-BMI1-NEXT:    retq
4519;
4520; X64-BMI2-LABEL: bextr32_c3_load_indexzext:
4521; X64-BMI2:       # %bb.0:
4522; X64-BMI2-NEXT:    pushq %rbp
4523; X64-BMI2-NEXT:    pushq %rbx
4524; X64-BMI2-NEXT:    pushq %rax
4525; X64-BMI2-NEXT:    movl %edx, %ebx
4526; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %ebp
4527; X64-BMI2-NEXT:    movl $-1, %eax
4528; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4529; X64-BMI2-NEXT:    callq use32@PLT
4530; X64-BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4531; X64-BMI2-NEXT:    addq $8, %rsp
4532; X64-BMI2-NEXT:    popq %rbx
4533; X64-BMI2-NEXT:    popq %rbp
4534; X64-BMI2-NEXT:    retq
4535  %val = load i32, ptr %w
4536  %skip = zext i8 %numskipbits to i32
4537  %shifted = lshr i32 %val, %skip
4538  %numhighbits = sub i8 32, %numlowbits
4539  %sh_prom = zext i8 %numhighbits to i32
4540  %mask = lshr i32 -1, %sh_prom
4541  call void @use32(i32 %mask)
4542  %masked = and i32 %mask, %shifted
4543  ret i32 %masked
4544}
4545
4546define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
4547; X86-NOBMI-LABEL: bextr32_c4_commutative:
4548; X86-NOBMI:       # %bb.0:
4549; X86-NOBMI-NEXT:    pushl %edi
4550; X86-NOBMI-NEXT:    pushl %esi
4551; X86-NOBMI-NEXT:    pushl %eax
4552; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4553; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4554; X86-NOBMI-NEXT:    shrl %cl, %edi
4555; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4556; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4557; X86-NOBMI-NEXT:    movl $-1, %esi
4558; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4559; X86-NOBMI-NEXT:    shrl %cl, %esi
4560; X86-NOBMI-NEXT:    movl %esi, (%esp)
4561; X86-NOBMI-NEXT:    calll use32@PLT
4562; X86-NOBMI-NEXT:    andl %edi, %esi
4563; X86-NOBMI-NEXT:    movl %esi, %eax
4564; X86-NOBMI-NEXT:    addl $4, %esp
4565; X86-NOBMI-NEXT:    popl %esi
4566; X86-NOBMI-NEXT:    popl %edi
4567; X86-NOBMI-NEXT:    retl
4568;
4569; X86-BMI1-LABEL: bextr32_c4_commutative:
4570; X86-BMI1:       # %bb.0:
4571; X86-BMI1-NEXT:    pushl %edi
4572; X86-BMI1-NEXT:    pushl %esi
4573; X86-BMI1-NEXT:    pushl %eax
4574; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4575; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
4576; X86-BMI1-NEXT:    shrl %cl, %edi
4577; X86-BMI1-NEXT:    xorl %ecx, %ecx
4578; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4579; X86-BMI1-NEXT:    movl $-1, %esi
4580; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4581; X86-BMI1-NEXT:    shrl %cl, %esi
4582; X86-BMI1-NEXT:    movl %esi, (%esp)
4583; X86-BMI1-NEXT:    calll use32@PLT
4584; X86-BMI1-NEXT:    andl %edi, %esi
4585; X86-BMI1-NEXT:    movl %esi, %eax
4586; X86-BMI1-NEXT:    addl $4, %esp
4587; X86-BMI1-NEXT:    popl %esi
4588; X86-BMI1-NEXT:    popl %edi
4589; X86-BMI1-NEXT:    retl
4590;
4591; X86-BMI2-LABEL: bextr32_c4_commutative:
4592; X86-BMI2:       # %bb.0:
4593; X86-BMI2-NEXT:    pushl %ebx
4594; X86-BMI2-NEXT:    pushl %esi
4595; X86-BMI2-NEXT:    pushl %eax
4596; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4597; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
4598; X86-BMI2-NEXT:    shrxl %eax, {{[0-9]+}}(%esp), %esi
4599; X86-BMI2-NEXT:    movl $-1, %eax
4600; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4601; X86-BMI2-NEXT:    movl %eax, (%esp)
4602; X86-BMI2-NEXT:    calll use32@PLT
4603; X86-BMI2-NEXT:    bzhil %ebx, %esi, %eax
4604; X86-BMI2-NEXT:    addl $4, %esp
4605; X86-BMI2-NEXT:    popl %esi
4606; X86-BMI2-NEXT:    popl %ebx
4607; X86-BMI2-NEXT:    retl
4608;
4609; X64-NOBMI-LABEL: bextr32_c4_commutative:
4610; X64-NOBMI:       # %bb.0:
4611; X64-NOBMI-NEXT:    pushq %rbp
4612; X64-NOBMI-NEXT:    pushq %rbx
4613; X64-NOBMI-NEXT:    pushq %rax
4614; X64-NOBMI-NEXT:    movl %esi, %ecx
4615; X64-NOBMI-NEXT:    movl %edi, %ebx
4616; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4617; X64-NOBMI-NEXT:    shrl %cl, %ebx
4618; X64-NOBMI-NEXT:    negb %dl
4619; X64-NOBMI-NEXT:    movl $-1, %ebp
4620; X64-NOBMI-NEXT:    movl %edx, %ecx
4621; X64-NOBMI-NEXT:    shrl %cl, %ebp
4622; X64-NOBMI-NEXT:    movl %ebp, %edi
4623; X64-NOBMI-NEXT:    callq use32@PLT
4624; X64-NOBMI-NEXT:    andl %ebx, %ebp
4625; X64-NOBMI-NEXT:    movl %ebp, %eax
4626; X64-NOBMI-NEXT:    addq $8, %rsp
4627; X64-NOBMI-NEXT:    popq %rbx
4628; X64-NOBMI-NEXT:    popq %rbp
4629; X64-NOBMI-NEXT:    retq
4630;
4631; X64-BMI1-LABEL: bextr32_c4_commutative:
4632; X64-BMI1:       # %bb.0:
4633; X64-BMI1-NEXT:    pushq %rbp
4634; X64-BMI1-NEXT:    pushq %rbx
4635; X64-BMI1-NEXT:    pushq %rax
4636; X64-BMI1-NEXT:    movl %esi, %ecx
4637; X64-BMI1-NEXT:    movl %edi, %ebx
4638; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4639; X64-BMI1-NEXT:    shrl %cl, %ebx
4640; X64-BMI1-NEXT:    negb %dl
4641; X64-BMI1-NEXT:    movl $-1, %ebp
4642; X64-BMI1-NEXT:    movl %edx, %ecx
4643; X64-BMI1-NEXT:    shrl %cl, %ebp
4644; X64-BMI1-NEXT:    movl %ebp, %edi
4645; X64-BMI1-NEXT:    callq use32@PLT
4646; X64-BMI1-NEXT:    andl %ebx, %ebp
4647; X64-BMI1-NEXT:    movl %ebp, %eax
4648; X64-BMI1-NEXT:    addq $8, %rsp
4649; X64-BMI1-NEXT:    popq %rbx
4650; X64-BMI1-NEXT:    popq %rbp
4651; X64-BMI1-NEXT:    retq
4652;
4653; X64-BMI2-LABEL: bextr32_c4_commutative:
4654; X64-BMI2:       # %bb.0:
4655; X64-BMI2-NEXT:    pushq %rbp
4656; X64-BMI2-NEXT:    pushq %rbx
4657; X64-BMI2-NEXT:    pushq %rax
4658; X64-BMI2-NEXT:    movl %edx, %ebx
4659; X64-BMI2-NEXT:    shrxl %esi, %edi, %ebp
4660; X64-BMI2-NEXT:    movl $-1, %eax
4661; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4662; X64-BMI2-NEXT:    callq use32@PLT
4663; X64-BMI2-NEXT:    bzhil %ebx, %ebp, %eax
4664; X64-BMI2-NEXT:    addq $8, %rsp
4665; X64-BMI2-NEXT:    popq %rbx
4666; X64-BMI2-NEXT:    popq %rbp
4667; X64-BMI2-NEXT:    retq
4668  %shifted = lshr i32 %val, %numskipbits
4669  %numhighbits = sub i32 32, %numlowbits
4670  %mask = lshr i32 -1, %numhighbits
4671  call void @use32(i32 %mask)
4672  %masked = and i32 %shifted, %mask ; swapped order
4673  ret i32 %masked
4674}
4675
4676define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
4677; X86-NOBMI-LABEL: bextr32_c5_skipextrauses:
4678; X86-NOBMI:       # %bb.0:
4679; X86-NOBMI-NEXT:    pushl %ebx
4680; X86-NOBMI-NEXT:    pushl %edi
4681; X86-NOBMI-NEXT:    pushl %esi
4682; X86-NOBMI-NEXT:    subl $16, %esp
4683; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
4684; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
4685; X86-NOBMI-NEXT:    movl %ebx, %ecx
4686; X86-NOBMI-NEXT:    shrl %cl, %edi
4687; X86-NOBMI-NEXT:    xorl %ecx, %ecx
4688; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4689; X86-NOBMI-NEXT:    movl $-1, %esi
4690; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
4691; X86-NOBMI-NEXT:    shrl %cl, %esi
4692; X86-NOBMI-NEXT:    movl %esi, (%esp)
4693; X86-NOBMI-NEXT:    calll use32@PLT
4694; X86-NOBMI-NEXT:    andl %edi, %esi
4695; X86-NOBMI-NEXT:    movl %ebx, (%esp)
4696; X86-NOBMI-NEXT:    calll use32@PLT
4697; X86-NOBMI-NEXT:    movl %esi, %eax
4698; X86-NOBMI-NEXT:    addl $16, %esp
4699; X86-NOBMI-NEXT:    popl %esi
4700; X86-NOBMI-NEXT:    popl %edi
4701; X86-NOBMI-NEXT:    popl %ebx
4702; X86-NOBMI-NEXT:    retl
4703;
4704; X86-BMI1-LABEL: bextr32_c5_skipextrauses:
4705; X86-BMI1:       # %bb.0:
4706; X86-BMI1-NEXT:    pushl %ebx
4707; X86-BMI1-NEXT:    pushl %edi
4708; X86-BMI1-NEXT:    pushl %esi
4709; X86-BMI1-NEXT:    subl $16, %esp
4710; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
4711; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ebx
4712; X86-BMI1-NEXT:    movl %ebx, %ecx
4713; X86-BMI1-NEXT:    shrl %cl, %edi
4714; X86-BMI1-NEXT:    xorl %ecx, %ecx
4715; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4716; X86-BMI1-NEXT:    movl $-1, %esi
4717; X86-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
4718; X86-BMI1-NEXT:    shrl %cl, %esi
4719; X86-BMI1-NEXT:    movl %esi, (%esp)
4720; X86-BMI1-NEXT:    calll use32@PLT
4721; X86-BMI1-NEXT:    andl %edi, %esi
4722; X86-BMI1-NEXT:    movl %ebx, (%esp)
4723; X86-BMI1-NEXT:    calll use32@PLT
4724; X86-BMI1-NEXT:    movl %esi, %eax
4725; X86-BMI1-NEXT:    addl $16, %esp
4726; X86-BMI1-NEXT:    popl %esi
4727; X86-BMI1-NEXT:    popl %edi
4728; X86-BMI1-NEXT:    popl %ebx
4729; X86-BMI1-NEXT:    retl
4730;
4731; X86-BMI2-LABEL: bextr32_c5_skipextrauses:
4732; X86-BMI2:       # %bb.0:
4733; X86-BMI2-NEXT:    pushl %ebx
4734; X86-BMI2-NEXT:    pushl %edi
4735; X86-BMI2-NEXT:    pushl %esi
4736; X86-BMI2-NEXT:    subl $16, %esp
4737; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
4738; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
4739; X86-BMI2-NEXT:    shrxl %edi, {{[0-9]+}}(%esp), %esi
4740; X86-BMI2-NEXT:    movl $-1, %eax
4741; X86-BMI2-NEXT:    bzhil %ebx, %eax, %eax
4742; X86-BMI2-NEXT:    movl %eax, (%esp)
4743; X86-BMI2-NEXT:    calll use32@PLT
4744; X86-BMI2-NEXT:    bzhil %ebx, %esi, %esi
4745; X86-BMI2-NEXT:    movl %edi, (%esp)
4746; X86-BMI2-NEXT:    calll use32@PLT
4747; X86-BMI2-NEXT:    movl %esi, %eax
4748; X86-BMI2-NEXT:    addl $16, %esp
4749; X86-BMI2-NEXT:    popl %esi
4750; X86-BMI2-NEXT:    popl %edi
4751; X86-BMI2-NEXT:    popl %ebx
4752; X86-BMI2-NEXT:    retl
4753;
4754; X64-NOBMI-LABEL: bextr32_c5_skipextrauses:
4755; X64-NOBMI:       # %bb.0:
4756; X64-NOBMI-NEXT:    pushq %rbp
4757; X64-NOBMI-NEXT:    pushq %r14
4758; X64-NOBMI-NEXT:    pushq %rbx
4759; X64-NOBMI-NEXT:    movl %esi, %ebx
4760; X64-NOBMI-NEXT:    movl %edi, %ebp
4761; X64-NOBMI-NEXT:    movl %ebx, %ecx
4762; X64-NOBMI-NEXT:    shrl %cl, %ebp
4763; X64-NOBMI-NEXT:    negb %dl
4764; X64-NOBMI-NEXT:    movl $-1, %r14d
4765; X64-NOBMI-NEXT:    movl %edx, %ecx
4766; X64-NOBMI-NEXT:    shrl %cl, %r14d
4767; X64-NOBMI-NEXT:    movl %r14d, %edi
4768; X64-NOBMI-NEXT:    callq use32@PLT
4769; X64-NOBMI-NEXT:    andl %ebp, %r14d
4770; X64-NOBMI-NEXT:    movl %ebx, %edi
4771; X64-NOBMI-NEXT:    callq use32@PLT
4772; X64-NOBMI-NEXT:    movl %r14d, %eax
4773; X64-NOBMI-NEXT:    popq %rbx
4774; X64-NOBMI-NEXT:    popq %r14
4775; X64-NOBMI-NEXT:    popq %rbp
4776; X64-NOBMI-NEXT:    retq
4777;
4778; X64-BMI1-LABEL: bextr32_c5_skipextrauses:
4779; X64-BMI1:       # %bb.0:
4780; X64-BMI1-NEXT:    pushq %rbp
4781; X64-BMI1-NEXT:    pushq %r14
4782; X64-BMI1-NEXT:    pushq %rbx
4783; X64-BMI1-NEXT:    movl %esi, %ebx
4784; X64-BMI1-NEXT:    movl %edi, %ebp
4785; X64-BMI1-NEXT:    movl %ebx, %ecx
4786; X64-BMI1-NEXT:    shrl %cl, %ebp
4787; X64-BMI1-NEXT:    negb %dl
4788; X64-BMI1-NEXT:    movl $-1, %r14d
4789; X64-BMI1-NEXT:    movl %edx, %ecx
4790; X64-BMI1-NEXT:    shrl %cl, %r14d
4791; X64-BMI1-NEXT:    movl %r14d, %edi
4792; X64-BMI1-NEXT:    callq use32@PLT
4793; X64-BMI1-NEXT:    andl %ebp, %r14d
4794; X64-BMI1-NEXT:    movl %ebx, %edi
4795; X64-BMI1-NEXT:    callq use32@PLT
4796; X64-BMI1-NEXT:    movl %r14d, %eax
4797; X64-BMI1-NEXT:    popq %rbx
4798; X64-BMI1-NEXT:    popq %r14
4799; X64-BMI1-NEXT:    popq %rbp
4800; X64-BMI1-NEXT:    retq
4801;
4802; X64-BMI2-LABEL: bextr32_c5_skipextrauses:
4803; X64-BMI2:       # %bb.0:
4804; X64-BMI2-NEXT:    pushq %rbp
4805; X64-BMI2-NEXT:    pushq %r14
4806; X64-BMI2-NEXT:    pushq %rbx
4807; X64-BMI2-NEXT:    movl %edx, %ebx
4808; X64-BMI2-NEXT:    movl %esi, %ebp
4809; X64-BMI2-NEXT:    shrxl %esi, %edi, %r14d
4810; X64-BMI2-NEXT:    movl $-1, %eax
4811; X64-BMI2-NEXT:    bzhil %edx, %eax, %edi
4812; X64-BMI2-NEXT:    callq use32@PLT
4813; X64-BMI2-NEXT:    bzhil %ebx, %r14d, %ebx
4814; X64-BMI2-NEXT:    movl %ebp, %edi
4815; X64-BMI2-NEXT:    callq use32@PLT
4816; X64-BMI2-NEXT:    movl %ebx, %eax
4817; X64-BMI2-NEXT:    popq %rbx
4818; X64-BMI2-NEXT:    popq %r14
4819; X64-BMI2-NEXT:    popq %rbp
4820; X64-BMI2-NEXT:    retq
4821  %shifted = lshr i32 %val, %numskipbits
4822  %numhighbits = sub i32 32, %numlowbits
4823  %mask = lshr i32 -1, %numhighbits
4824  call void @use32(i32 %mask)
4825  %masked = and i32 %mask, %shifted
4826  call void @use32(i32 %numskipbits)
4827  ret i32 %masked
4828}
4829
4830; 64-bit
4831
4832define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
4833; X86-NOBMI-LABEL: bextr64_c0:
4834; X86-NOBMI:       # %bb.0:
4835; X86-NOBMI-NEXT:    pushl %ebp
4836; X86-NOBMI-NEXT:    pushl %ebx
4837; X86-NOBMI-NEXT:    pushl %edi
4838; X86-NOBMI-NEXT:    pushl %esi
4839; X86-NOBMI-NEXT:    subl $12, %esp
4840; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4841; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
4842; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
4843; X86-NOBMI-NEXT:    movl %eax, %edi
4844; X86-NOBMI-NEXT:    shrl %cl, %edi
4845; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
4846; X86-NOBMI-NEXT:    testb $32, %cl
4847; X86-NOBMI-NEXT:    je .LBB41_2
4848; X86-NOBMI-NEXT:  # %bb.1:
4849; X86-NOBMI-NEXT:    movl %edi, %esi
4850; X86-NOBMI-NEXT:    xorl %edi, %edi
4851; X86-NOBMI-NEXT:  .LBB41_2:
4852; X86-NOBMI-NEXT:    movb $64, %cl
4853; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
4854; X86-NOBMI-NEXT:    movl $-1, %ebp
4855; X86-NOBMI-NEXT:    movl $-1, %ebx
4856; X86-NOBMI-NEXT:    shrl %cl, %ebx
4857; X86-NOBMI-NEXT:    testb $32, %cl
4858; X86-NOBMI-NEXT:    je .LBB41_4
4859; X86-NOBMI-NEXT:  # %bb.3:
4860; X86-NOBMI-NEXT:    movl %ebx, %ebp
4861; X86-NOBMI-NEXT:    xorl %ebx, %ebx
4862; X86-NOBMI-NEXT:  .LBB41_4:
4863; X86-NOBMI-NEXT:    subl $8, %esp
4864; X86-NOBMI-NEXT:    pushl %ebx
4865; X86-NOBMI-NEXT:    pushl %ebp
4866; X86-NOBMI-NEXT:    calll use64@PLT
4867; X86-NOBMI-NEXT:    addl $16, %esp
4868; X86-NOBMI-NEXT:    andl %ebp, %esi
4869; X86-NOBMI-NEXT:    andl %ebx, %edi
4870; X86-NOBMI-NEXT:    movl %esi, %eax
4871; X86-NOBMI-NEXT:    movl %edi, %edx
4872; X86-NOBMI-NEXT:    addl $12, %esp
4873; X86-NOBMI-NEXT:    popl %esi
4874; X86-NOBMI-NEXT:    popl %edi
4875; X86-NOBMI-NEXT:    popl %ebx
4876; X86-NOBMI-NEXT:    popl %ebp
4877; X86-NOBMI-NEXT:    retl
4878;
4879; X86-BMI1-LABEL: bextr64_c0:
4880; X86-BMI1:       # %bb.0:
4881; X86-BMI1-NEXT:    pushl %ebp
4882; X86-BMI1-NEXT:    pushl %ebx
4883; X86-BMI1-NEXT:    pushl %edi
4884; X86-BMI1-NEXT:    pushl %esi
4885; X86-BMI1-NEXT:    subl $12, %esp
4886; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4887; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
4888; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
4889; X86-BMI1-NEXT:    movl %eax, %edi
4890; X86-BMI1-NEXT:    shrl %cl, %edi
4891; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
4892; X86-BMI1-NEXT:    testb $32, %cl
4893; X86-BMI1-NEXT:    je .LBB41_2
4894; X86-BMI1-NEXT:  # %bb.1:
4895; X86-BMI1-NEXT:    movl %edi, %esi
4896; X86-BMI1-NEXT:    xorl %edi, %edi
4897; X86-BMI1-NEXT:  .LBB41_2:
4898; X86-BMI1-NEXT:    movb $64, %cl
4899; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
4900; X86-BMI1-NEXT:    movl $-1, %ebp
4901; X86-BMI1-NEXT:    movl $-1, %ebx
4902; X86-BMI1-NEXT:    shrl %cl, %ebx
4903; X86-BMI1-NEXT:    testb $32, %cl
4904; X86-BMI1-NEXT:    je .LBB41_4
4905; X86-BMI1-NEXT:  # %bb.3:
4906; X86-BMI1-NEXT:    movl %ebx, %ebp
4907; X86-BMI1-NEXT:    xorl %ebx, %ebx
4908; X86-BMI1-NEXT:  .LBB41_4:
4909; X86-BMI1-NEXT:    subl $8, %esp
4910; X86-BMI1-NEXT:    pushl %ebx
4911; X86-BMI1-NEXT:    pushl %ebp
4912; X86-BMI1-NEXT:    calll use64@PLT
4913; X86-BMI1-NEXT:    addl $16, %esp
4914; X86-BMI1-NEXT:    andl %ebp, %esi
4915; X86-BMI1-NEXT:    andl %ebx, %edi
4916; X86-BMI1-NEXT:    movl %esi, %eax
4917; X86-BMI1-NEXT:    movl %edi, %edx
4918; X86-BMI1-NEXT:    addl $12, %esp
4919; X86-BMI1-NEXT:    popl %esi
4920; X86-BMI1-NEXT:    popl %edi
4921; X86-BMI1-NEXT:    popl %ebx
4922; X86-BMI1-NEXT:    popl %ebp
4923; X86-BMI1-NEXT:    retl
4924;
4925; X86-BMI2-LABEL: bextr64_c0:
4926; X86-BMI2:       # %bb.0:
4927; X86-BMI2-NEXT:    pushl %ebp
4928; X86-BMI2-NEXT:    pushl %ebx
4929; X86-BMI2-NEXT:    pushl %edi
4930; X86-BMI2-NEXT:    pushl %esi
4931; X86-BMI2-NEXT:    subl $12, %esp
4932; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
4933; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
4934; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
4935; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
4936; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
4937; X86-BMI2-NEXT:    testb $32, %cl
4938; X86-BMI2-NEXT:    je .LBB41_2
4939; X86-BMI2-NEXT:  # %bb.1:
4940; X86-BMI2-NEXT:    movl %edi, %esi
4941; X86-BMI2-NEXT:    xorl %edi, %edi
4942; X86-BMI2-NEXT:  .LBB41_2:
4943; X86-BMI2-NEXT:    movb $64, %al
4944; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
4945; X86-BMI2-NEXT:    movl $-1, %ebp
4946; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
4947; X86-BMI2-NEXT:    testb $32, %al
4948; X86-BMI2-NEXT:    je .LBB41_4
4949; X86-BMI2-NEXT:  # %bb.3:
4950; X86-BMI2-NEXT:    movl %ebx, %ebp
4951; X86-BMI2-NEXT:    xorl %ebx, %ebx
4952; X86-BMI2-NEXT:  .LBB41_4:
4953; X86-BMI2-NEXT:    subl $8, %esp
4954; X86-BMI2-NEXT:    pushl %ebx
4955; X86-BMI2-NEXT:    pushl %ebp
4956; X86-BMI2-NEXT:    calll use64@PLT
4957; X86-BMI2-NEXT:    addl $16, %esp
4958; X86-BMI2-NEXT:    andl %ebp, %esi
4959; X86-BMI2-NEXT:    andl %ebx, %edi
4960; X86-BMI2-NEXT:    movl %esi, %eax
4961; X86-BMI2-NEXT:    movl %edi, %edx
4962; X86-BMI2-NEXT:    addl $12, %esp
4963; X86-BMI2-NEXT:    popl %esi
4964; X86-BMI2-NEXT:    popl %edi
4965; X86-BMI2-NEXT:    popl %ebx
4966; X86-BMI2-NEXT:    popl %ebp
4967; X86-BMI2-NEXT:    retl
4968;
4969; X64-NOBMI-LABEL: bextr64_c0:
4970; X64-NOBMI:       # %bb.0:
4971; X64-NOBMI-NEXT:    pushq %r14
4972; X64-NOBMI-NEXT:    pushq %rbx
4973; X64-NOBMI-NEXT:    pushq %rax
4974; X64-NOBMI-NEXT:    movq %rsi, %rcx
4975; X64-NOBMI-NEXT:    movq %rdi, %rbx
4976; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
4977; X64-NOBMI-NEXT:    shrq %cl, %rbx
4978; X64-NOBMI-NEXT:    negb %dl
4979; X64-NOBMI-NEXT:    movq $-1, %r14
4980; X64-NOBMI-NEXT:    movl %edx, %ecx
4981; X64-NOBMI-NEXT:    shrq %cl, %r14
4982; X64-NOBMI-NEXT:    movq %r14, %rdi
4983; X64-NOBMI-NEXT:    callq use64@PLT
4984; X64-NOBMI-NEXT:    andq %rbx, %r14
4985; X64-NOBMI-NEXT:    movq %r14, %rax
4986; X64-NOBMI-NEXT:    addq $8, %rsp
4987; X64-NOBMI-NEXT:    popq %rbx
4988; X64-NOBMI-NEXT:    popq %r14
4989; X64-NOBMI-NEXT:    retq
4990;
4991; X64-BMI1-LABEL: bextr64_c0:
4992; X64-BMI1:       # %bb.0:
4993; X64-BMI1-NEXT:    pushq %r14
4994; X64-BMI1-NEXT:    pushq %rbx
4995; X64-BMI1-NEXT:    pushq %rax
4996; X64-BMI1-NEXT:    movq %rsi, %rcx
4997; X64-BMI1-NEXT:    movq %rdi, %rbx
4998; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
4999; X64-BMI1-NEXT:    shrq %cl, %rbx
5000; X64-BMI1-NEXT:    negb %dl
5001; X64-BMI1-NEXT:    movq $-1, %r14
5002; X64-BMI1-NEXT:    movl %edx, %ecx
5003; X64-BMI1-NEXT:    shrq %cl, %r14
5004; X64-BMI1-NEXT:    movq %r14, %rdi
5005; X64-BMI1-NEXT:    callq use64@PLT
5006; X64-BMI1-NEXT:    andq %rbx, %r14
5007; X64-BMI1-NEXT:    movq %r14, %rax
5008; X64-BMI1-NEXT:    addq $8, %rsp
5009; X64-BMI1-NEXT:    popq %rbx
5010; X64-BMI1-NEXT:    popq %r14
5011; X64-BMI1-NEXT:    retq
5012;
5013; X64-BMI2-LABEL: bextr64_c0:
5014; X64-BMI2:       # %bb.0:
5015; X64-BMI2-NEXT:    pushq %r14
5016; X64-BMI2-NEXT:    pushq %rbx
5017; X64-BMI2-NEXT:    pushq %rax
5018; X64-BMI2-NEXT:    movq %rdx, %rbx
5019; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %r14
5020; X64-BMI2-NEXT:    movq $-1, %rax
5021; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rdi
5022; X64-BMI2-NEXT:    callq use64@PLT
5023; X64-BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5024; X64-BMI2-NEXT:    addq $8, %rsp
5025; X64-BMI2-NEXT:    popq %rbx
5026; X64-BMI2-NEXT:    popq %r14
5027; X64-BMI2-NEXT:    retq
5028  %shifted = lshr i64 %val, %numskipbits
5029  %numhighbits = sub i64 64, %numlowbits
5030  %mask = lshr i64 -1, %numhighbits
5031  call void @use64(i64 %mask)
5032  %masked = and i64 %mask, %shifted
5033  ret i64 %masked
5034}
5035
5036define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
5037; X86-NOBMI-LABEL: bextr64_c1_indexzext:
5038; X86-NOBMI:       # %bb.0:
5039; X86-NOBMI-NEXT:    pushl %ebp
5040; X86-NOBMI-NEXT:    pushl %ebx
5041; X86-NOBMI-NEXT:    pushl %edi
5042; X86-NOBMI-NEXT:    pushl %esi
5043; X86-NOBMI-NEXT:    subl $12, %esp
5044; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5045; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5046; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5047; X86-NOBMI-NEXT:    movl %eax, %edi
5048; X86-NOBMI-NEXT:    shrl %cl, %edi
5049; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5050; X86-NOBMI-NEXT:    testb $32, %cl
5051; X86-NOBMI-NEXT:    je .LBB42_2
5052; X86-NOBMI-NEXT:  # %bb.1:
5053; X86-NOBMI-NEXT:    movl %edi, %esi
5054; X86-NOBMI-NEXT:    xorl %edi, %edi
5055; X86-NOBMI-NEXT:  .LBB42_2:
5056; X86-NOBMI-NEXT:    movb $64, %cl
5057; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5058; X86-NOBMI-NEXT:    movl $-1, %ebp
5059; X86-NOBMI-NEXT:    movl $-1, %ebx
5060; X86-NOBMI-NEXT:    shrl %cl, %ebx
5061; X86-NOBMI-NEXT:    testb $32, %cl
5062; X86-NOBMI-NEXT:    je .LBB42_4
5063; X86-NOBMI-NEXT:  # %bb.3:
5064; X86-NOBMI-NEXT:    movl %ebx, %ebp
5065; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5066; X86-NOBMI-NEXT:  .LBB42_4:
5067; X86-NOBMI-NEXT:    subl $8, %esp
5068; X86-NOBMI-NEXT:    pushl %ebx
5069; X86-NOBMI-NEXT:    pushl %ebp
5070; X86-NOBMI-NEXT:    calll use64@PLT
5071; X86-NOBMI-NEXT:    addl $16, %esp
5072; X86-NOBMI-NEXT:    andl %ebp, %esi
5073; X86-NOBMI-NEXT:    andl %ebx, %edi
5074; X86-NOBMI-NEXT:    movl %esi, %eax
5075; X86-NOBMI-NEXT:    movl %edi, %edx
5076; X86-NOBMI-NEXT:    addl $12, %esp
5077; X86-NOBMI-NEXT:    popl %esi
5078; X86-NOBMI-NEXT:    popl %edi
5079; X86-NOBMI-NEXT:    popl %ebx
5080; X86-NOBMI-NEXT:    popl %ebp
5081; X86-NOBMI-NEXT:    retl
5082;
5083; X86-BMI1-LABEL: bextr64_c1_indexzext:
5084; X86-BMI1:       # %bb.0:
5085; X86-BMI1-NEXT:    pushl %ebp
5086; X86-BMI1-NEXT:    pushl %ebx
5087; X86-BMI1-NEXT:    pushl %edi
5088; X86-BMI1-NEXT:    pushl %esi
5089; X86-BMI1-NEXT:    subl $12, %esp
5090; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5091; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
5092; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
5093; X86-BMI1-NEXT:    movl %eax, %edi
5094; X86-BMI1-NEXT:    shrl %cl, %edi
5095; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
5096; X86-BMI1-NEXT:    testb $32, %cl
5097; X86-BMI1-NEXT:    je .LBB42_2
5098; X86-BMI1-NEXT:  # %bb.1:
5099; X86-BMI1-NEXT:    movl %edi, %esi
5100; X86-BMI1-NEXT:    xorl %edi, %edi
5101; X86-BMI1-NEXT:  .LBB42_2:
5102; X86-BMI1-NEXT:    movb $64, %cl
5103; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
5104; X86-BMI1-NEXT:    movl $-1, %ebp
5105; X86-BMI1-NEXT:    movl $-1, %ebx
5106; X86-BMI1-NEXT:    shrl %cl, %ebx
5107; X86-BMI1-NEXT:    testb $32, %cl
5108; X86-BMI1-NEXT:    je .LBB42_4
5109; X86-BMI1-NEXT:  # %bb.3:
5110; X86-BMI1-NEXT:    movl %ebx, %ebp
5111; X86-BMI1-NEXT:    xorl %ebx, %ebx
5112; X86-BMI1-NEXT:  .LBB42_4:
5113; X86-BMI1-NEXT:    subl $8, %esp
5114; X86-BMI1-NEXT:    pushl %ebx
5115; X86-BMI1-NEXT:    pushl %ebp
5116; X86-BMI1-NEXT:    calll use64@PLT
5117; X86-BMI1-NEXT:    addl $16, %esp
5118; X86-BMI1-NEXT:    andl %ebp, %esi
5119; X86-BMI1-NEXT:    andl %ebx, %edi
5120; X86-BMI1-NEXT:    movl %esi, %eax
5121; X86-BMI1-NEXT:    movl %edi, %edx
5122; X86-BMI1-NEXT:    addl $12, %esp
5123; X86-BMI1-NEXT:    popl %esi
5124; X86-BMI1-NEXT:    popl %edi
5125; X86-BMI1-NEXT:    popl %ebx
5126; X86-BMI1-NEXT:    popl %ebp
5127; X86-BMI1-NEXT:    retl
5128;
5129; X86-BMI2-LABEL: bextr64_c1_indexzext:
5130; X86-BMI2:       # %bb.0:
5131; X86-BMI2-NEXT:    pushl %ebp
5132; X86-BMI2-NEXT:    pushl %ebx
5133; X86-BMI2-NEXT:    pushl %edi
5134; X86-BMI2-NEXT:    pushl %esi
5135; X86-BMI2-NEXT:    subl $12, %esp
5136; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5137; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5138; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5139; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
5140; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
5141; X86-BMI2-NEXT:    testb $32, %cl
5142; X86-BMI2-NEXT:    je .LBB42_2
5143; X86-BMI2-NEXT:  # %bb.1:
5144; X86-BMI2-NEXT:    movl %edi, %esi
5145; X86-BMI2-NEXT:    xorl %edi, %edi
5146; X86-BMI2-NEXT:  .LBB42_2:
5147; X86-BMI2-NEXT:    movb $64, %al
5148; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
5149; X86-BMI2-NEXT:    movl $-1, %ebp
5150; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
5151; X86-BMI2-NEXT:    testb $32, %al
5152; X86-BMI2-NEXT:    je .LBB42_4
5153; X86-BMI2-NEXT:  # %bb.3:
5154; X86-BMI2-NEXT:    movl %ebx, %ebp
5155; X86-BMI2-NEXT:    xorl %ebx, %ebx
5156; X86-BMI2-NEXT:  .LBB42_4:
5157; X86-BMI2-NEXT:    subl $8, %esp
5158; X86-BMI2-NEXT:    pushl %ebx
5159; X86-BMI2-NEXT:    pushl %ebp
5160; X86-BMI2-NEXT:    calll use64@PLT
5161; X86-BMI2-NEXT:    addl $16, %esp
5162; X86-BMI2-NEXT:    andl %ebp, %esi
5163; X86-BMI2-NEXT:    andl %ebx, %edi
5164; X86-BMI2-NEXT:    movl %esi, %eax
5165; X86-BMI2-NEXT:    movl %edi, %edx
5166; X86-BMI2-NEXT:    addl $12, %esp
5167; X86-BMI2-NEXT:    popl %esi
5168; X86-BMI2-NEXT:    popl %edi
5169; X86-BMI2-NEXT:    popl %ebx
5170; X86-BMI2-NEXT:    popl %ebp
5171; X86-BMI2-NEXT:    retl
5172;
5173; X64-NOBMI-LABEL: bextr64_c1_indexzext:
5174; X64-NOBMI:       # %bb.0:
5175; X64-NOBMI-NEXT:    pushq %r14
5176; X64-NOBMI-NEXT:    pushq %rbx
5177; X64-NOBMI-NEXT:    pushq %rax
5178; X64-NOBMI-NEXT:    movl %esi, %ecx
5179; X64-NOBMI-NEXT:    movq %rdi, %rbx
5180; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5181; X64-NOBMI-NEXT:    shrq %cl, %rbx
5182; X64-NOBMI-NEXT:    negb %dl
5183; X64-NOBMI-NEXT:    movq $-1, %r14
5184; X64-NOBMI-NEXT:    movl %edx, %ecx
5185; X64-NOBMI-NEXT:    shrq %cl, %r14
5186; X64-NOBMI-NEXT:    movq %r14, %rdi
5187; X64-NOBMI-NEXT:    callq use64@PLT
5188; X64-NOBMI-NEXT:    andq %rbx, %r14
5189; X64-NOBMI-NEXT:    movq %r14, %rax
5190; X64-NOBMI-NEXT:    addq $8, %rsp
5191; X64-NOBMI-NEXT:    popq %rbx
5192; X64-NOBMI-NEXT:    popq %r14
5193; X64-NOBMI-NEXT:    retq
5194;
5195; X64-BMI1-LABEL: bextr64_c1_indexzext:
5196; X64-BMI1:       # %bb.0:
5197; X64-BMI1-NEXT:    pushq %r14
5198; X64-BMI1-NEXT:    pushq %rbx
5199; X64-BMI1-NEXT:    pushq %rax
5200; X64-BMI1-NEXT:    movl %esi, %ecx
5201; X64-BMI1-NEXT:    movq %rdi, %rbx
5202; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
5203; X64-BMI1-NEXT:    shrq %cl, %rbx
5204; X64-BMI1-NEXT:    negb %dl
5205; X64-BMI1-NEXT:    movq $-1, %r14
5206; X64-BMI1-NEXT:    movl %edx, %ecx
5207; X64-BMI1-NEXT:    shrq %cl, %r14
5208; X64-BMI1-NEXT:    movq %r14, %rdi
5209; X64-BMI1-NEXT:    callq use64@PLT
5210; X64-BMI1-NEXT:    andq %rbx, %r14
5211; X64-BMI1-NEXT:    movq %r14, %rax
5212; X64-BMI1-NEXT:    addq $8, %rsp
5213; X64-BMI1-NEXT:    popq %rbx
5214; X64-BMI1-NEXT:    popq %r14
5215; X64-BMI1-NEXT:    retq
5216;
5217; X64-BMI2-LABEL: bextr64_c1_indexzext:
5218; X64-BMI2:       # %bb.0:
5219; X64-BMI2-NEXT:    pushq %r14
5220; X64-BMI2-NEXT:    pushq %rbx
5221; X64-BMI2-NEXT:    pushq %rax
5222; X64-BMI2-NEXT:    movl %edx, %ebx
5223; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
5224; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %r14
5225; X64-BMI2-NEXT:    movq $-1, %rax
5226; X64-BMI2-NEXT:    bzhiq %rbx, %rax, %rdi
5227; X64-BMI2-NEXT:    callq use64@PLT
5228; X64-BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5229; X64-BMI2-NEXT:    addq $8, %rsp
5230; X64-BMI2-NEXT:    popq %rbx
5231; X64-BMI2-NEXT:    popq %r14
5232; X64-BMI2-NEXT:    retq
5233  %skip = zext i8 %numskipbits to i64
5234  %shifted = lshr i64 %val, %skip
5235  %numhighbits = sub i8 64, %numlowbits
5236  %sh_prom = zext i8 %numhighbits to i64
5237  %mask = lshr i64 -1, %sh_prom
5238  call void @use64(i64 %mask)
5239  %masked = and i64 %mask, %shifted
5240  ret i64 %masked
5241}
5242
5243define i64 @bextr64_c2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {
5244; X86-NOBMI-LABEL: bextr64_c2_load:
5245; X86-NOBMI:       # %bb.0:
5246; X86-NOBMI-NEXT:    pushl %ebp
5247; X86-NOBMI-NEXT:    pushl %ebx
5248; X86-NOBMI-NEXT:    pushl %edi
5249; X86-NOBMI-NEXT:    pushl %esi
5250; X86-NOBMI-NEXT:    subl $12, %esp
5251; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5252; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5253; X86-NOBMI-NEXT:    movl (%eax), %esi
5254; X86-NOBMI-NEXT:    movl 4(%eax), %eax
5255; X86-NOBMI-NEXT:    movl %eax, %edi
5256; X86-NOBMI-NEXT:    shrl %cl, %edi
5257; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5258; X86-NOBMI-NEXT:    testb $32, %cl
5259; X86-NOBMI-NEXT:    je .LBB43_2
5260; X86-NOBMI-NEXT:  # %bb.1:
5261; X86-NOBMI-NEXT:    movl %edi, %esi
5262; X86-NOBMI-NEXT:    xorl %edi, %edi
5263; X86-NOBMI-NEXT:  .LBB43_2:
5264; X86-NOBMI-NEXT:    movb $64, %cl
5265; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5266; X86-NOBMI-NEXT:    movl $-1, %ebp
5267; X86-NOBMI-NEXT:    movl $-1, %ebx
5268; X86-NOBMI-NEXT:    shrl %cl, %ebx
5269; X86-NOBMI-NEXT:    testb $32, %cl
5270; X86-NOBMI-NEXT:    je .LBB43_4
5271; X86-NOBMI-NEXT:  # %bb.3:
5272; X86-NOBMI-NEXT:    movl %ebx, %ebp
5273; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5274; X86-NOBMI-NEXT:  .LBB43_4:
5275; X86-NOBMI-NEXT:    subl $8, %esp
5276; X86-NOBMI-NEXT:    pushl %ebx
5277; X86-NOBMI-NEXT:    pushl %ebp
5278; X86-NOBMI-NEXT:    calll use64@PLT
5279; X86-NOBMI-NEXT:    addl $16, %esp
5280; X86-NOBMI-NEXT:    andl %ebp, %esi
5281; X86-NOBMI-NEXT:    andl %ebx, %edi
5282; X86-NOBMI-NEXT:    movl %esi, %eax
5283; X86-NOBMI-NEXT:    movl %edi, %edx
5284; X86-NOBMI-NEXT:    addl $12, %esp
5285; X86-NOBMI-NEXT:    popl %esi
5286; X86-NOBMI-NEXT:    popl %edi
5287; X86-NOBMI-NEXT:    popl %ebx
5288; X86-NOBMI-NEXT:    popl %ebp
5289; X86-NOBMI-NEXT:    retl
5290;
5291; X86-BMI1-LABEL: bextr64_c2_load:
5292; X86-BMI1:       # %bb.0:
5293; X86-BMI1-NEXT:    pushl %ebp
5294; X86-BMI1-NEXT:    pushl %ebx
5295; X86-BMI1-NEXT:    pushl %edi
5296; X86-BMI1-NEXT:    pushl %esi
5297; X86-BMI1-NEXT:    subl $12, %esp
5298; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5299; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
5300; X86-BMI1-NEXT:    movl (%eax), %esi
5301; X86-BMI1-NEXT:    movl 4(%eax), %eax
5302; X86-BMI1-NEXT:    movl %eax, %edi
5303; X86-BMI1-NEXT:    shrl %cl, %edi
5304; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
5305; X86-BMI1-NEXT:    testb $32, %cl
5306; X86-BMI1-NEXT:    je .LBB43_2
5307; X86-BMI1-NEXT:  # %bb.1:
5308; X86-BMI1-NEXT:    movl %edi, %esi
5309; X86-BMI1-NEXT:    xorl %edi, %edi
5310; X86-BMI1-NEXT:  .LBB43_2:
5311; X86-BMI1-NEXT:    movb $64, %cl
5312; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
5313; X86-BMI1-NEXT:    movl $-1, %ebp
5314; X86-BMI1-NEXT:    movl $-1, %ebx
5315; X86-BMI1-NEXT:    shrl %cl, %ebx
5316; X86-BMI1-NEXT:    testb $32, %cl
5317; X86-BMI1-NEXT:    je .LBB43_4
5318; X86-BMI1-NEXT:  # %bb.3:
5319; X86-BMI1-NEXT:    movl %ebx, %ebp
5320; X86-BMI1-NEXT:    xorl %ebx, %ebx
5321; X86-BMI1-NEXT:  .LBB43_4:
5322; X86-BMI1-NEXT:    subl $8, %esp
5323; X86-BMI1-NEXT:    pushl %ebx
5324; X86-BMI1-NEXT:    pushl %ebp
5325; X86-BMI1-NEXT:    calll use64@PLT
5326; X86-BMI1-NEXT:    addl $16, %esp
5327; X86-BMI1-NEXT:    andl %ebp, %esi
5328; X86-BMI1-NEXT:    andl %ebx, %edi
5329; X86-BMI1-NEXT:    movl %esi, %eax
5330; X86-BMI1-NEXT:    movl %edi, %edx
5331; X86-BMI1-NEXT:    addl $12, %esp
5332; X86-BMI1-NEXT:    popl %esi
5333; X86-BMI1-NEXT:    popl %edi
5334; X86-BMI1-NEXT:    popl %ebx
5335; X86-BMI1-NEXT:    popl %ebp
5336; X86-BMI1-NEXT:    retl
5337;
5338; X86-BMI2-LABEL: bextr64_c2_load:
5339; X86-BMI2:       # %bb.0:
5340; X86-BMI2-NEXT:    pushl %ebp
5341; X86-BMI2-NEXT:    pushl %ebx
5342; X86-BMI2-NEXT:    pushl %edi
5343; X86-BMI2-NEXT:    pushl %esi
5344; X86-BMI2-NEXT:    subl $12, %esp
5345; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5346; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5347; X86-BMI2-NEXT:    movl (%eax), %esi
5348; X86-BMI2-NEXT:    movl 4(%eax), %eax
5349; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
5350; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
5351; X86-BMI2-NEXT:    testb $32, %cl
5352; X86-BMI2-NEXT:    je .LBB43_2
5353; X86-BMI2-NEXT:  # %bb.1:
5354; X86-BMI2-NEXT:    movl %edi, %esi
5355; X86-BMI2-NEXT:    xorl %edi, %edi
5356; X86-BMI2-NEXT:  .LBB43_2:
5357; X86-BMI2-NEXT:    movb $64, %al
5358; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
5359; X86-BMI2-NEXT:    movl $-1, %ebp
5360; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
5361; X86-BMI2-NEXT:    testb $32, %al
5362; X86-BMI2-NEXT:    je .LBB43_4
5363; X86-BMI2-NEXT:  # %bb.3:
5364; X86-BMI2-NEXT:    movl %ebx, %ebp
5365; X86-BMI2-NEXT:    xorl %ebx, %ebx
5366; X86-BMI2-NEXT:  .LBB43_4:
5367; X86-BMI2-NEXT:    subl $8, %esp
5368; X86-BMI2-NEXT:    pushl %ebx
5369; X86-BMI2-NEXT:    pushl %ebp
5370; X86-BMI2-NEXT:    calll use64@PLT
5371; X86-BMI2-NEXT:    addl $16, %esp
5372; X86-BMI2-NEXT:    andl %ebp, %esi
5373; X86-BMI2-NEXT:    andl %ebx, %edi
5374; X86-BMI2-NEXT:    movl %esi, %eax
5375; X86-BMI2-NEXT:    movl %edi, %edx
5376; X86-BMI2-NEXT:    addl $12, %esp
5377; X86-BMI2-NEXT:    popl %esi
5378; X86-BMI2-NEXT:    popl %edi
5379; X86-BMI2-NEXT:    popl %ebx
5380; X86-BMI2-NEXT:    popl %ebp
5381; X86-BMI2-NEXT:    retl
5382;
5383; X64-NOBMI-LABEL: bextr64_c2_load:
5384; X64-NOBMI:       # %bb.0:
5385; X64-NOBMI-NEXT:    pushq %r14
5386; X64-NOBMI-NEXT:    pushq %rbx
5387; X64-NOBMI-NEXT:    pushq %rax
5388; X64-NOBMI-NEXT:    movq %rsi, %rcx
5389; X64-NOBMI-NEXT:    movq (%rdi), %r14
5390; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5391; X64-NOBMI-NEXT:    shrq %cl, %r14
5392; X64-NOBMI-NEXT:    negb %dl
5393; X64-NOBMI-NEXT:    movq $-1, %rbx
5394; X64-NOBMI-NEXT:    movl %edx, %ecx
5395; X64-NOBMI-NEXT:    shrq %cl, %rbx
5396; X64-NOBMI-NEXT:    movq %rbx, %rdi
5397; X64-NOBMI-NEXT:    callq use64@PLT
5398; X64-NOBMI-NEXT:    andq %r14, %rbx
5399; X64-NOBMI-NEXT:    movq %rbx, %rax
5400; X64-NOBMI-NEXT:    addq $8, %rsp
5401; X64-NOBMI-NEXT:    popq %rbx
5402; X64-NOBMI-NEXT:    popq %r14
5403; X64-NOBMI-NEXT:    retq
5404;
5405; X64-BMI1-LABEL: bextr64_c2_load:
5406; X64-BMI1:       # %bb.0:
5407; X64-BMI1-NEXT:    pushq %r14
5408; X64-BMI1-NEXT:    pushq %rbx
5409; X64-BMI1-NEXT:    pushq %rax
5410; X64-BMI1-NEXT:    movq %rsi, %rcx
5411; X64-BMI1-NEXT:    movq (%rdi), %r14
5412; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
5413; X64-BMI1-NEXT:    shrq %cl, %r14
5414; X64-BMI1-NEXT:    negb %dl
5415; X64-BMI1-NEXT:    movq $-1, %rbx
5416; X64-BMI1-NEXT:    movl %edx, %ecx
5417; X64-BMI1-NEXT:    shrq %cl, %rbx
5418; X64-BMI1-NEXT:    movq %rbx, %rdi
5419; X64-BMI1-NEXT:    callq use64@PLT
5420; X64-BMI1-NEXT:    andq %r14, %rbx
5421; X64-BMI1-NEXT:    movq %rbx, %rax
5422; X64-BMI1-NEXT:    addq $8, %rsp
5423; X64-BMI1-NEXT:    popq %rbx
5424; X64-BMI1-NEXT:    popq %r14
5425; X64-BMI1-NEXT:    retq
5426;
5427; X64-BMI2-LABEL: bextr64_c2_load:
5428; X64-BMI2:       # %bb.0:
5429; X64-BMI2-NEXT:    pushq %r14
5430; X64-BMI2-NEXT:    pushq %rbx
5431; X64-BMI2-NEXT:    pushq %rax
5432; X64-BMI2-NEXT:    movq %rdx, %rbx
5433; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
5434; X64-BMI2-NEXT:    movq $-1, %rax
5435; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rdi
5436; X64-BMI2-NEXT:    callq use64@PLT
5437; X64-BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5438; X64-BMI2-NEXT:    addq $8, %rsp
5439; X64-BMI2-NEXT:    popq %rbx
5440; X64-BMI2-NEXT:    popq %r14
5441; X64-BMI2-NEXT:    retq
5442  %val = load i64, ptr %w
5443  %shifted = lshr i64 %val, %numskipbits
5444  %numhighbits = sub i64 64, %numlowbits
5445  %mask = lshr i64 -1, %numhighbits
5446  call void @use64(i64 %mask)
5447  %masked = and i64 %mask, %shifted
5448  ret i64 %masked
5449}
5450
5451define i64 @bextr64_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {
5452; X86-NOBMI-LABEL: bextr64_c3_load_indexzext:
5453; X86-NOBMI:       # %bb.0:
5454; X86-NOBMI-NEXT:    pushl %ebp
5455; X86-NOBMI-NEXT:    pushl %ebx
5456; X86-NOBMI-NEXT:    pushl %edi
5457; X86-NOBMI-NEXT:    pushl %esi
5458; X86-NOBMI-NEXT:    subl $12, %esp
5459; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5460; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5461; X86-NOBMI-NEXT:    movl (%eax), %esi
5462; X86-NOBMI-NEXT:    movl 4(%eax), %eax
5463; X86-NOBMI-NEXT:    movl %eax, %edi
5464; X86-NOBMI-NEXT:    shrl %cl, %edi
5465; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5466; X86-NOBMI-NEXT:    testb $32, %cl
5467; X86-NOBMI-NEXT:    je .LBB44_2
5468; X86-NOBMI-NEXT:  # %bb.1:
5469; X86-NOBMI-NEXT:    movl %edi, %esi
5470; X86-NOBMI-NEXT:    xorl %edi, %edi
5471; X86-NOBMI-NEXT:  .LBB44_2:
5472; X86-NOBMI-NEXT:    movb $64, %cl
5473; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5474; X86-NOBMI-NEXT:    movl $-1, %ebp
5475; X86-NOBMI-NEXT:    movl $-1, %ebx
5476; X86-NOBMI-NEXT:    shrl %cl, %ebx
5477; X86-NOBMI-NEXT:    testb $32, %cl
5478; X86-NOBMI-NEXT:    je .LBB44_4
5479; X86-NOBMI-NEXT:  # %bb.3:
5480; X86-NOBMI-NEXT:    movl %ebx, %ebp
5481; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5482; X86-NOBMI-NEXT:  .LBB44_4:
5483; X86-NOBMI-NEXT:    subl $8, %esp
5484; X86-NOBMI-NEXT:    pushl %ebx
5485; X86-NOBMI-NEXT:    pushl %ebp
5486; X86-NOBMI-NEXT:    calll use64@PLT
5487; X86-NOBMI-NEXT:    addl $16, %esp
5488; X86-NOBMI-NEXT:    andl %ebp, %esi
5489; X86-NOBMI-NEXT:    andl %ebx, %edi
5490; X86-NOBMI-NEXT:    movl %esi, %eax
5491; X86-NOBMI-NEXT:    movl %edi, %edx
5492; X86-NOBMI-NEXT:    addl $12, %esp
5493; X86-NOBMI-NEXT:    popl %esi
5494; X86-NOBMI-NEXT:    popl %edi
5495; X86-NOBMI-NEXT:    popl %ebx
5496; X86-NOBMI-NEXT:    popl %ebp
5497; X86-NOBMI-NEXT:    retl
5498;
5499; X86-BMI1-LABEL: bextr64_c3_load_indexzext:
5500; X86-BMI1:       # %bb.0:
5501; X86-BMI1-NEXT:    pushl %ebp
5502; X86-BMI1-NEXT:    pushl %ebx
5503; X86-BMI1-NEXT:    pushl %edi
5504; X86-BMI1-NEXT:    pushl %esi
5505; X86-BMI1-NEXT:    subl $12, %esp
5506; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5507; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
5508; X86-BMI1-NEXT:    movl (%eax), %esi
5509; X86-BMI1-NEXT:    movl 4(%eax), %eax
5510; X86-BMI1-NEXT:    movl %eax, %edi
5511; X86-BMI1-NEXT:    shrl %cl, %edi
5512; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
5513; X86-BMI1-NEXT:    testb $32, %cl
5514; X86-BMI1-NEXT:    je .LBB44_2
5515; X86-BMI1-NEXT:  # %bb.1:
5516; X86-BMI1-NEXT:    movl %edi, %esi
5517; X86-BMI1-NEXT:    xorl %edi, %edi
5518; X86-BMI1-NEXT:  .LBB44_2:
5519; X86-BMI1-NEXT:    movb $64, %cl
5520; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
5521; X86-BMI1-NEXT:    movl $-1, %ebp
5522; X86-BMI1-NEXT:    movl $-1, %ebx
5523; X86-BMI1-NEXT:    shrl %cl, %ebx
5524; X86-BMI1-NEXT:    testb $32, %cl
5525; X86-BMI1-NEXT:    je .LBB44_4
5526; X86-BMI1-NEXT:  # %bb.3:
5527; X86-BMI1-NEXT:    movl %ebx, %ebp
5528; X86-BMI1-NEXT:    xorl %ebx, %ebx
5529; X86-BMI1-NEXT:  .LBB44_4:
5530; X86-BMI1-NEXT:    subl $8, %esp
5531; X86-BMI1-NEXT:    pushl %ebx
5532; X86-BMI1-NEXT:    pushl %ebp
5533; X86-BMI1-NEXT:    calll use64@PLT
5534; X86-BMI1-NEXT:    addl $16, %esp
5535; X86-BMI1-NEXT:    andl %ebp, %esi
5536; X86-BMI1-NEXT:    andl %ebx, %edi
5537; X86-BMI1-NEXT:    movl %esi, %eax
5538; X86-BMI1-NEXT:    movl %edi, %edx
5539; X86-BMI1-NEXT:    addl $12, %esp
5540; X86-BMI1-NEXT:    popl %esi
5541; X86-BMI1-NEXT:    popl %edi
5542; X86-BMI1-NEXT:    popl %ebx
5543; X86-BMI1-NEXT:    popl %ebp
5544; X86-BMI1-NEXT:    retl
5545;
5546; X86-BMI2-LABEL: bextr64_c3_load_indexzext:
5547; X86-BMI2:       # %bb.0:
5548; X86-BMI2-NEXT:    pushl %ebp
5549; X86-BMI2-NEXT:    pushl %ebx
5550; X86-BMI2-NEXT:    pushl %edi
5551; X86-BMI2-NEXT:    pushl %esi
5552; X86-BMI2-NEXT:    subl $12, %esp
5553; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5554; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5555; X86-BMI2-NEXT:    movl (%eax), %esi
5556; X86-BMI2-NEXT:    movl 4(%eax), %eax
5557; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
5558; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
5559; X86-BMI2-NEXT:    testb $32, %cl
5560; X86-BMI2-NEXT:    je .LBB44_2
5561; X86-BMI2-NEXT:  # %bb.1:
5562; X86-BMI2-NEXT:    movl %edi, %esi
5563; X86-BMI2-NEXT:    xorl %edi, %edi
5564; X86-BMI2-NEXT:  .LBB44_2:
5565; X86-BMI2-NEXT:    movb $64, %al
5566; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
5567; X86-BMI2-NEXT:    movl $-1, %ebp
5568; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
5569; X86-BMI2-NEXT:    testb $32, %al
5570; X86-BMI2-NEXT:    je .LBB44_4
5571; X86-BMI2-NEXT:  # %bb.3:
5572; X86-BMI2-NEXT:    movl %ebx, %ebp
5573; X86-BMI2-NEXT:    xorl %ebx, %ebx
5574; X86-BMI2-NEXT:  .LBB44_4:
5575; X86-BMI2-NEXT:    subl $8, %esp
5576; X86-BMI2-NEXT:    pushl %ebx
5577; X86-BMI2-NEXT:    pushl %ebp
5578; X86-BMI2-NEXT:    calll use64@PLT
5579; X86-BMI2-NEXT:    addl $16, %esp
5580; X86-BMI2-NEXT:    andl %ebp, %esi
5581; X86-BMI2-NEXT:    andl %ebx, %edi
5582; X86-BMI2-NEXT:    movl %esi, %eax
5583; X86-BMI2-NEXT:    movl %edi, %edx
5584; X86-BMI2-NEXT:    addl $12, %esp
5585; X86-BMI2-NEXT:    popl %esi
5586; X86-BMI2-NEXT:    popl %edi
5587; X86-BMI2-NEXT:    popl %ebx
5588; X86-BMI2-NEXT:    popl %ebp
5589; X86-BMI2-NEXT:    retl
5590;
5591; X64-NOBMI-LABEL: bextr64_c3_load_indexzext:
5592; X64-NOBMI:       # %bb.0:
5593; X64-NOBMI-NEXT:    pushq %r14
5594; X64-NOBMI-NEXT:    pushq %rbx
5595; X64-NOBMI-NEXT:    pushq %rax
5596; X64-NOBMI-NEXT:    movl %esi, %ecx
5597; X64-NOBMI-NEXT:    movq (%rdi), %r14
5598; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
5599; X64-NOBMI-NEXT:    shrq %cl, %r14
5600; X64-NOBMI-NEXT:    negb %dl
5601; X64-NOBMI-NEXT:    movq $-1, %rbx
5602; X64-NOBMI-NEXT:    movl %edx, %ecx
5603; X64-NOBMI-NEXT:    shrq %cl, %rbx
5604; X64-NOBMI-NEXT:    movq %rbx, %rdi
5605; X64-NOBMI-NEXT:    callq use64@PLT
5606; X64-NOBMI-NEXT:    andq %r14, %rbx
5607; X64-NOBMI-NEXT:    movq %rbx, %rax
5608; X64-NOBMI-NEXT:    addq $8, %rsp
5609; X64-NOBMI-NEXT:    popq %rbx
5610; X64-NOBMI-NEXT:    popq %r14
5611; X64-NOBMI-NEXT:    retq
5612;
5613; X64-BMI1-LABEL: bextr64_c3_load_indexzext:
5614; X64-BMI1:       # %bb.0:
5615; X64-BMI1-NEXT:    pushq %r14
5616; X64-BMI1-NEXT:    pushq %rbx
5617; X64-BMI1-NEXT:    pushq %rax
5618; X64-BMI1-NEXT:    movl %esi, %ecx
5619; X64-BMI1-NEXT:    movq (%rdi), %r14
5620; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
5621; X64-BMI1-NEXT:    shrq %cl, %r14
5622; X64-BMI1-NEXT:    negb %dl
5623; X64-BMI1-NEXT:    movq $-1, %rbx
5624; X64-BMI1-NEXT:    movl %edx, %ecx
5625; X64-BMI1-NEXT:    shrq %cl, %rbx
5626; X64-BMI1-NEXT:    movq %rbx, %rdi
5627; X64-BMI1-NEXT:    callq use64@PLT
5628; X64-BMI1-NEXT:    andq %r14, %rbx
5629; X64-BMI1-NEXT:    movq %rbx, %rax
5630; X64-BMI1-NEXT:    addq $8, %rsp
5631; X64-BMI1-NEXT:    popq %rbx
5632; X64-BMI1-NEXT:    popq %r14
5633; X64-BMI1-NEXT:    retq
5634;
5635; X64-BMI2-LABEL: bextr64_c3_load_indexzext:
5636; X64-BMI2:       # %bb.0:
5637; X64-BMI2-NEXT:    pushq %r14
5638; X64-BMI2-NEXT:    pushq %rbx
5639; X64-BMI2-NEXT:    pushq %rax
5640; X64-BMI2-NEXT:    movl %edx, %ebx
5641; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
5642; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %r14
5643; X64-BMI2-NEXT:    movq $-1, %rax
5644; X64-BMI2-NEXT:    bzhiq %rbx, %rax, %rdi
5645; X64-BMI2-NEXT:    callq use64@PLT
5646; X64-BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5647; X64-BMI2-NEXT:    addq $8, %rsp
5648; X64-BMI2-NEXT:    popq %rbx
5649; X64-BMI2-NEXT:    popq %r14
5650; X64-BMI2-NEXT:    retq
5651  %val = load i64, ptr %w
5652  %skip = zext i8 %numskipbits to i64
5653  %shifted = lshr i64 %val, %skip
5654  %numhighbits = sub i8 64, %numlowbits
5655  %sh_prom = zext i8 %numhighbits to i64
5656  %mask = lshr i64 -1, %sh_prom
5657  call void @use64(i64 %mask)
5658  %masked = and i64 %mask, %shifted
5659  ret i64 %masked
5660}
5661
5662define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5663; X86-NOBMI-LABEL: bextr64_c4_commutative:
5664; X86-NOBMI:       # %bb.0:
5665; X86-NOBMI-NEXT:    pushl %ebp
5666; X86-NOBMI-NEXT:    pushl %ebx
5667; X86-NOBMI-NEXT:    pushl %edi
5668; X86-NOBMI-NEXT:    pushl %esi
5669; X86-NOBMI-NEXT:    subl $12, %esp
5670; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5671; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5672; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5673; X86-NOBMI-NEXT:    movl %eax, %edi
5674; X86-NOBMI-NEXT:    shrl %cl, %edi
5675; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5676; X86-NOBMI-NEXT:    testb $32, %cl
5677; X86-NOBMI-NEXT:    je .LBB45_2
5678; X86-NOBMI-NEXT:  # %bb.1:
5679; X86-NOBMI-NEXT:    movl %edi, %esi
5680; X86-NOBMI-NEXT:    xorl %edi, %edi
5681; X86-NOBMI-NEXT:  .LBB45_2:
5682; X86-NOBMI-NEXT:    movb $64, %cl
5683; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5684; X86-NOBMI-NEXT:    movl $-1, %ebp
5685; X86-NOBMI-NEXT:    movl $-1, %ebx
5686; X86-NOBMI-NEXT:    shrl %cl, %ebx
5687; X86-NOBMI-NEXT:    testb $32, %cl
5688; X86-NOBMI-NEXT:    je .LBB45_4
5689; X86-NOBMI-NEXT:  # %bb.3:
5690; X86-NOBMI-NEXT:    movl %ebx, %ebp
5691; X86-NOBMI-NEXT:    xorl %ebx, %ebx
5692; X86-NOBMI-NEXT:  .LBB45_4:
5693; X86-NOBMI-NEXT:    subl $8, %esp
5694; X86-NOBMI-NEXT:    pushl %ebx
5695; X86-NOBMI-NEXT:    pushl %ebp
5696; X86-NOBMI-NEXT:    calll use64@PLT
5697; X86-NOBMI-NEXT:    addl $16, %esp
5698; X86-NOBMI-NEXT:    andl %ebp, %esi
5699; X86-NOBMI-NEXT:    andl %ebx, %edi
5700; X86-NOBMI-NEXT:    movl %esi, %eax
5701; X86-NOBMI-NEXT:    movl %edi, %edx
5702; X86-NOBMI-NEXT:    addl $12, %esp
5703; X86-NOBMI-NEXT:    popl %esi
5704; X86-NOBMI-NEXT:    popl %edi
5705; X86-NOBMI-NEXT:    popl %ebx
5706; X86-NOBMI-NEXT:    popl %ebp
5707; X86-NOBMI-NEXT:    retl
5708;
5709; X86-BMI1-LABEL: bextr64_c4_commutative:
5710; X86-BMI1:       # %bb.0:
5711; X86-BMI1-NEXT:    pushl %ebp
5712; X86-BMI1-NEXT:    pushl %ebx
5713; X86-BMI1-NEXT:    pushl %edi
5714; X86-BMI1-NEXT:    pushl %esi
5715; X86-BMI1-NEXT:    subl $12, %esp
5716; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5717; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
5718; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
5719; X86-BMI1-NEXT:    movl %eax, %edi
5720; X86-BMI1-NEXT:    shrl %cl, %edi
5721; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
5722; X86-BMI1-NEXT:    testb $32, %cl
5723; X86-BMI1-NEXT:    je .LBB45_2
5724; X86-BMI1-NEXT:  # %bb.1:
5725; X86-BMI1-NEXT:    movl %edi, %esi
5726; X86-BMI1-NEXT:    xorl %edi, %edi
5727; X86-BMI1-NEXT:  .LBB45_2:
5728; X86-BMI1-NEXT:    movb $64, %cl
5729; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
5730; X86-BMI1-NEXT:    movl $-1, %ebp
5731; X86-BMI1-NEXT:    movl $-1, %ebx
5732; X86-BMI1-NEXT:    shrl %cl, %ebx
5733; X86-BMI1-NEXT:    testb $32, %cl
5734; X86-BMI1-NEXT:    je .LBB45_4
5735; X86-BMI1-NEXT:  # %bb.3:
5736; X86-BMI1-NEXT:    movl %ebx, %ebp
5737; X86-BMI1-NEXT:    xorl %ebx, %ebx
5738; X86-BMI1-NEXT:  .LBB45_4:
5739; X86-BMI1-NEXT:    subl $8, %esp
5740; X86-BMI1-NEXT:    pushl %ebx
5741; X86-BMI1-NEXT:    pushl %ebp
5742; X86-BMI1-NEXT:    calll use64@PLT
5743; X86-BMI1-NEXT:    addl $16, %esp
5744; X86-BMI1-NEXT:    andl %ebp, %esi
5745; X86-BMI1-NEXT:    andl %ebx, %edi
5746; X86-BMI1-NEXT:    movl %esi, %eax
5747; X86-BMI1-NEXT:    movl %edi, %edx
5748; X86-BMI1-NEXT:    addl $12, %esp
5749; X86-BMI1-NEXT:    popl %esi
5750; X86-BMI1-NEXT:    popl %edi
5751; X86-BMI1-NEXT:    popl %ebx
5752; X86-BMI1-NEXT:    popl %ebp
5753; X86-BMI1-NEXT:    retl
5754;
5755; X86-BMI2-LABEL: bextr64_c4_commutative:
5756; X86-BMI2:       # %bb.0:
5757; X86-BMI2-NEXT:    pushl %ebp
5758; X86-BMI2-NEXT:    pushl %ebx
5759; X86-BMI2-NEXT:    pushl %edi
5760; X86-BMI2-NEXT:    pushl %esi
5761; X86-BMI2-NEXT:    subl $12, %esp
5762; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
5763; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5764; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5765; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
5766; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
5767; X86-BMI2-NEXT:    testb $32, %cl
5768; X86-BMI2-NEXT:    je .LBB45_2
5769; X86-BMI2-NEXT:  # %bb.1:
5770; X86-BMI2-NEXT:    movl %edi, %esi
5771; X86-BMI2-NEXT:    xorl %edi, %edi
5772; X86-BMI2-NEXT:  .LBB45_2:
5773; X86-BMI2-NEXT:    movb $64, %al
5774; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
5775; X86-BMI2-NEXT:    movl $-1, %ebp
5776; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
5777; X86-BMI2-NEXT:    testb $32, %al
5778; X86-BMI2-NEXT:    je .LBB45_4
5779; X86-BMI2-NEXT:  # %bb.3:
5780; X86-BMI2-NEXT:    movl %ebx, %ebp
5781; X86-BMI2-NEXT:    xorl %ebx, %ebx
5782; X86-BMI2-NEXT:  .LBB45_4:
5783; X86-BMI2-NEXT:    subl $8, %esp
5784; X86-BMI2-NEXT:    pushl %ebx
5785; X86-BMI2-NEXT:    pushl %ebp
5786; X86-BMI2-NEXT:    calll use64@PLT
5787; X86-BMI2-NEXT:    addl $16, %esp
5788; X86-BMI2-NEXT:    andl %ebp, %esi
5789; X86-BMI2-NEXT:    andl %ebx, %edi
5790; X86-BMI2-NEXT:    movl %esi, %eax
5791; X86-BMI2-NEXT:    movl %edi, %edx
5792; X86-BMI2-NEXT:    addl $12, %esp
5793; X86-BMI2-NEXT:    popl %esi
5794; X86-BMI2-NEXT:    popl %edi
5795; X86-BMI2-NEXT:    popl %ebx
5796; X86-BMI2-NEXT:    popl %ebp
5797; X86-BMI2-NEXT:    retl
5798;
5799; X64-NOBMI-LABEL: bextr64_c4_commutative:
5800; X64-NOBMI:       # %bb.0:
5801; X64-NOBMI-NEXT:    pushq %r14
5802; X64-NOBMI-NEXT:    pushq %rbx
5803; X64-NOBMI-NEXT:    pushq %rax
5804; X64-NOBMI-NEXT:    movq %rsi, %rcx
5805; X64-NOBMI-NEXT:    movq %rdi, %rbx
5806; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
5807; X64-NOBMI-NEXT:    shrq %cl, %rbx
5808; X64-NOBMI-NEXT:    negb %dl
5809; X64-NOBMI-NEXT:    movq $-1, %r14
5810; X64-NOBMI-NEXT:    movl %edx, %ecx
5811; X64-NOBMI-NEXT:    shrq %cl, %r14
5812; X64-NOBMI-NEXT:    movq %r14, %rdi
5813; X64-NOBMI-NEXT:    callq use64@PLT
5814; X64-NOBMI-NEXT:    andq %rbx, %r14
5815; X64-NOBMI-NEXT:    movq %r14, %rax
5816; X64-NOBMI-NEXT:    addq $8, %rsp
5817; X64-NOBMI-NEXT:    popq %rbx
5818; X64-NOBMI-NEXT:    popq %r14
5819; X64-NOBMI-NEXT:    retq
5820;
5821; X64-BMI1-LABEL: bextr64_c4_commutative:
5822; X64-BMI1:       # %bb.0:
5823; X64-BMI1-NEXT:    pushq %r14
5824; X64-BMI1-NEXT:    pushq %rbx
5825; X64-BMI1-NEXT:    pushq %rax
5826; X64-BMI1-NEXT:    movq %rsi, %rcx
5827; X64-BMI1-NEXT:    movq %rdi, %rbx
5828; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
5829; X64-BMI1-NEXT:    shrq %cl, %rbx
5830; X64-BMI1-NEXT:    negb %dl
5831; X64-BMI1-NEXT:    movq $-1, %r14
5832; X64-BMI1-NEXT:    movl %edx, %ecx
5833; X64-BMI1-NEXT:    shrq %cl, %r14
5834; X64-BMI1-NEXT:    movq %r14, %rdi
5835; X64-BMI1-NEXT:    callq use64@PLT
5836; X64-BMI1-NEXT:    andq %rbx, %r14
5837; X64-BMI1-NEXT:    movq %r14, %rax
5838; X64-BMI1-NEXT:    addq $8, %rsp
5839; X64-BMI1-NEXT:    popq %rbx
5840; X64-BMI1-NEXT:    popq %r14
5841; X64-BMI1-NEXT:    retq
5842;
5843; X64-BMI2-LABEL: bextr64_c4_commutative:
5844; X64-BMI2:       # %bb.0:
5845; X64-BMI2-NEXT:    pushq %r14
5846; X64-BMI2-NEXT:    pushq %rbx
5847; X64-BMI2-NEXT:    pushq %rax
5848; X64-BMI2-NEXT:    movq %rdx, %rbx
5849; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %r14
5850; X64-BMI2-NEXT:    movq $-1, %rax
5851; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rdi
5852; X64-BMI2-NEXT:    callq use64@PLT
5853; X64-BMI2-NEXT:    bzhiq %rbx, %r14, %rax
5854; X64-BMI2-NEXT:    addq $8, %rsp
5855; X64-BMI2-NEXT:    popq %rbx
5856; X64-BMI2-NEXT:    popq %r14
5857; X64-BMI2-NEXT:    retq
5858  %shifted = lshr i64 %val, %numskipbits
5859  %numhighbits = sub i64 64, %numlowbits
5860  %mask = lshr i64 -1, %numhighbits
5861  call void @use64(i64 %mask)
5862  %masked = and i64 %shifted, %mask ; swapped order
5863  ret i64 %masked
5864}
5865
5866define i64 @bextr64_c5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
5867; X86-NOBMI-LABEL: bextr64_c5_skipextrauses:
5868; X86-NOBMI:       # %bb.0:
5869; X86-NOBMI-NEXT:    pushl %ebp
5870; X86-NOBMI-NEXT:    pushl %ebx
5871; X86-NOBMI-NEXT:    pushl %edi
5872; X86-NOBMI-NEXT:    pushl %esi
5873; X86-NOBMI-NEXT:    subl $12, %esp
5874; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
5875; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
5876; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5877; X86-NOBMI-NEXT:    movl %eax, %edi
5878; X86-NOBMI-NEXT:    shrl %cl, %edi
5879; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
5880; X86-NOBMI-NEXT:    testb $32, %cl
5881; X86-NOBMI-NEXT:    je .LBB46_2
5882; X86-NOBMI-NEXT:  # %bb.1:
5883; X86-NOBMI-NEXT:    movl %edi, %esi
5884; X86-NOBMI-NEXT:    xorl %edi, %edi
5885; X86-NOBMI-NEXT:  .LBB46_2:
5886; X86-NOBMI-NEXT:    movb $64, %cl
5887; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
5888; X86-NOBMI-NEXT:    movl $-1, %ebx
5889; X86-NOBMI-NEXT:    movl $-1, %ebp
5890; X86-NOBMI-NEXT:    shrl %cl, %ebp
5891; X86-NOBMI-NEXT:    testb $32, %cl
5892; X86-NOBMI-NEXT:    je .LBB46_4
5893; X86-NOBMI-NEXT:  # %bb.3:
5894; X86-NOBMI-NEXT:    movl %ebp, %ebx
5895; X86-NOBMI-NEXT:    xorl %ebp, %ebp
5896; X86-NOBMI-NEXT:  .LBB46_4:
5897; X86-NOBMI-NEXT:    subl $8, %esp
5898; X86-NOBMI-NEXT:    pushl %ebp
5899; X86-NOBMI-NEXT:    pushl %ebx
5900; X86-NOBMI-NEXT:    calll use64@PLT
5901; X86-NOBMI-NEXT:    addl $16, %esp
5902; X86-NOBMI-NEXT:    andl %ebx, %esi
5903; X86-NOBMI-NEXT:    andl %ebp, %edi
5904; X86-NOBMI-NEXT:    subl $8, %esp
5905; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
5906; X86-NOBMI-NEXT:    pushl {{[0-9]+}}(%esp)
5907; X86-NOBMI-NEXT:    calll use64@PLT
5908; X86-NOBMI-NEXT:    addl $16, %esp
5909; X86-NOBMI-NEXT:    movl %esi, %eax
5910; X86-NOBMI-NEXT:    movl %edi, %edx
5911; X86-NOBMI-NEXT:    addl $12, %esp
5912; X86-NOBMI-NEXT:    popl %esi
5913; X86-NOBMI-NEXT:    popl %edi
5914; X86-NOBMI-NEXT:    popl %ebx
5915; X86-NOBMI-NEXT:    popl %ebp
5916; X86-NOBMI-NEXT:    retl
5917;
5918; X86-BMI1-LABEL: bextr64_c5_skipextrauses:
5919; X86-BMI1:       # %bb.0:
5920; X86-BMI1-NEXT:    pushl %ebp
5921; X86-BMI1-NEXT:    pushl %ebx
5922; X86-BMI1-NEXT:    pushl %edi
5923; X86-BMI1-NEXT:    pushl %esi
5924; X86-BMI1-NEXT:    subl $12, %esp
5925; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
5926; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
5927; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5928; X86-BMI1-NEXT:    movl %eax, %edi
5929; X86-BMI1-NEXT:    shrl %cl, %edi
5930; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
5931; X86-BMI1-NEXT:    testb $32, %cl
5932; X86-BMI1-NEXT:    je .LBB46_2
5933; X86-BMI1-NEXT:  # %bb.1:
5934; X86-BMI1-NEXT:    movl %edi, %esi
5935; X86-BMI1-NEXT:    xorl %edi, %edi
5936; X86-BMI1-NEXT:  .LBB46_2:
5937; X86-BMI1-NEXT:    movb $64, %cl
5938; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
5939; X86-BMI1-NEXT:    movl $-1, %ebx
5940; X86-BMI1-NEXT:    movl $-1, %ebp
5941; X86-BMI1-NEXT:    shrl %cl, %ebp
5942; X86-BMI1-NEXT:    testb $32, %cl
5943; X86-BMI1-NEXT:    je .LBB46_4
5944; X86-BMI1-NEXT:  # %bb.3:
5945; X86-BMI1-NEXT:    movl %ebp, %ebx
5946; X86-BMI1-NEXT:    xorl %ebp, %ebp
5947; X86-BMI1-NEXT:  .LBB46_4:
5948; X86-BMI1-NEXT:    subl $8, %esp
5949; X86-BMI1-NEXT:    pushl %ebp
5950; X86-BMI1-NEXT:    pushl %ebx
5951; X86-BMI1-NEXT:    calll use64@PLT
5952; X86-BMI1-NEXT:    addl $16, %esp
5953; X86-BMI1-NEXT:    andl %ebx, %esi
5954; X86-BMI1-NEXT:    andl %ebp, %edi
5955; X86-BMI1-NEXT:    subl $8, %esp
5956; X86-BMI1-NEXT:    pushl {{[0-9]+}}(%esp)
5957; X86-BMI1-NEXT:    pushl {{[0-9]+}}(%esp)
5958; X86-BMI1-NEXT:    calll use64@PLT
5959; X86-BMI1-NEXT:    addl $16, %esp
5960; X86-BMI1-NEXT:    movl %esi, %eax
5961; X86-BMI1-NEXT:    movl %edi, %edx
5962; X86-BMI1-NEXT:    addl $12, %esp
5963; X86-BMI1-NEXT:    popl %esi
5964; X86-BMI1-NEXT:    popl %edi
5965; X86-BMI1-NEXT:    popl %ebx
5966; X86-BMI1-NEXT:    popl %ebp
5967; X86-BMI1-NEXT:    retl
5968;
5969; X86-BMI2-LABEL: bextr64_c5_skipextrauses:
5970; X86-BMI2:       # %bb.0:
5971; X86-BMI2-NEXT:    pushl %ebp
5972; X86-BMI2-NEXT:    pushl %ebx
5973; X86-BMI2-NEXT:    pushl %edi
5974; X86-BMI2-NEXT:    pushl %esi
5975; X86-BMI2-NEXT:    subl $12, %esp
5976; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
5977; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
5978; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5979; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
5980; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edi
5981; X86-BMI2-NEXT:    testb $32, %cl
5982; X86-BMI2-NEXT:    je .LBB46_2
5983; X86-BMI2-NEXT:  # %bb.1:
5984; X86-BMI2-NEXT:    movl %edi, %esi
5985; X86-BMI2-NEXT:    xorl %edi, %edi
5986; X86-BMI2-NEXT:  .LBB46_2:
5987; X86-BMI2-NEXT:    movb $64, %al
5988; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %al
5989; X86-BMI2-NEXT:    movl $-1, %ebp
5990; X86-BMI2-NEXT:    shrxl %eax, %ebp, %ebx
5991; X86-BMI2-NEXT:    testb $32, %al
5992; X86-BMI2-NEXT:    je .LBB46_4
5993; X86-BMI2-NEXT:  # %bb.3:
5994; X86-BMI2-NEXT:    movl %ebx, %ebp
5995; X86-BMI2-NEXT:    xorl %ebx, %ebx
5996; X86-BMI2-NEXT:  .LBB46_4:
5997; X86-BMI2-NEXT:    subl $8, %esp
5998; X86-BMI2-NEXT:    pushl %ebx
5999; X86-BMI2-NEXT:    pushl %ebp
6000; X86-BMI2-NEXT:    calll use64@PLT
6001; X86-BMI2-NEXT:    addl $16, %esp
6002; X86-BMI2-NEXT:    andl %ebp, %esi
6003; X86-BMI2-NEXT:    andl %ebx, %edi
6004; X86-BMI2-NEXT:    subl $8, %esp
6005; X86-BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
6006; X86-BMI2-NEXT:    pushl {{[0-9]+}}(%esp)
6007; X86-BMI2-NEXT:    calll use64@PLT
6008; X86-BMI2-NEXT:    addl $16, %esp
6009; X86-BMI2-NEXT:    movl %esi, %eax
6010; X86-BMI2-NEXT:    movl %edi, %edx
6011; X86-BMI2-NEXT:    addl $12, %esp
6012; X86-BMI2-NEXT:    popl %esi
6013; X86-BMI2-NEXT:    popl %edi
6014; X86-BMI2-NEXT:    popl %ebx
6015; X86-BMI2-NEXT:    popl %ebp
6016; X86-BMI2-NEXT:    retl
6017;
6018; X64-NOBMI-LABEL: bextr64_c5_skipextrauses:
6019; X64-NOBMI:       # %bb.0:
6020; X64-NOBMI-NEXT:    pushq %r15
6021; X64-NOBMI-NEXT:    pushq %r14
6022; X64-NOBMI-NEXT:    pushq %rbx
6023; X64-NOBMI-NEXT:    movq %rsi, %rbx
6024; X64-NOBMI-NEXT:    movq %rdi, %r14
6025; X64-NOBMI-NEXT:    movl %ebx, %ecx
6026; X64-NOBMI-NEXT:    shrq %cl, %r14
6027; X64-NOBMI-NEXT:    negb %dl
6028; X64-NOBMI-NEXT:    movq $-1, %r15
6029; X64-NOBMI-NEXT:    movl %edx, %ecx
6030; X64-NOBMI-NEXT:    shrq %cl, %r15
6031; X64-NOBMI-NEXT:    movq %r15, %rdi
6032; X64-NOBMI-NEXT:    callq use64@PLT
6033; X64-NOBMI-NEXT:    andq %r14, %r15
6034; X64-NOBMI-NEXT:    movq %rbx, %rdi
6035; X64-NOBMI-NEXT:    callq use64@PLT
6036; X64-NOBMI-NEXT:    movq %r15, %rax
6037; X64-NOBMI-NEXT:    popq %rbx
6038; X64-NOBMI-NEXT:    popq %r14
6039; X64-NOBMI-NEXT:    popq %r15
6040; X64-NOBMI-NEXT:    retq
6041;
6042; X64-BMI1-LABEL: bextr64_c5_skipextrauses:
6043; X64-BMI1:       # %bb.0:
6044; X64-BMI1-NEXT:    pushq %r15
6045; X64-BMI1-NEXT:    pushq %r14
6046; X64-BMI1-NEXT:    pushq %rbx
6047; X64-BMI1-NEXT:    movq %rsi, %rbx
6048; X64-BMI1-NEXT:    movq %rdi, %r14
6049; X64-BMI1-NEXT:    movl %ebx, %ecx
6050; X64-BMI1-NEXT:    shrq %cl, %r14
6051; X64-BMI1-NEXT:    negb %dl
6052; X64-BMI1-NEXT:    movq $-1, %r15
6053; X64-BMI1-NEXT:    movl %edx, %ecx
6054; X64-BMI1-NEXT:    shrq %cl, %r15
6055; X64-BMI1-NEXT:    movq %r15, %rdi
6056; X64-BMI1-NEXT:    callq use64@PLT
6057; X64-BMI1-NEXT:    andq %r14, %r15
6058; X64-BMI1-NEXT:    movq %rbx, %rdi
6059; X64-BMI1-NEXT:    callq use64@PLT
6060; X64-BMI1-NEXT:    movq %r15, %rax
6061; X64-BMI1-NEXT:    popq %rbx
6062; X64-BMI1-NEXT:    popq %r14
6063; X64-BMI1-NEXT:    popq %r15
6064; X64-BMI1-NEXT:    retq
6065;
6066; X64-BMI2-LABEL: bextr64_c5_skipextrauses:
6067; X64-BMI2:       # %bb.0:
6068; X64-BMI2-NEXT:    pushq %r15
6069; X64-BMI2-NEXT:    pushq %r14
6070; X64-BMI2-NEXT:    pushq %rbx
6071; X64-BMI2-NEXT:    movq %rdx, %rbx
6072; X64-BMI2-NEXT:    movq %rsi, %r14
6073; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %r15
6074; X64-BMI2-NEXT:    movq $-1, %rax
6075; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rdi
6076; X64-BMI2-NEXT:    callq use64@PLT
6077; X64-BMI2-NEXT:    bzhiq %rbx, %r15, %rbx
6078; X64-BMI2-NEXT:    movq %r14, %rdi
6079; X64-BMI2-NEXT:    callq use64@PLT
6080; X64-BMI2-NEXT:    movq %rbx, %rax
6081; X64-BMI2-NEXT:    popq %rbx
6082; X64-BMI2-NEXT:    popq %r14
6083; X64-BMI2-NEXT:    popq %r15
6084; X64-BMI2-NEXT:    retq
6085  %shifted = lshr i64 %val, %numskipbits
6086  %numhighbits = sub i64 64, %numlowbits
6087  %mask = lshr i64 -1, %numhighbits
6088  call void @use64(i64 %mask)
6089  %masked = and i64 %mask, %shifted
6090  call void @use64(i64 %numskipbits)
6091  ret i64 %masked
6092}
6093
6094; 64-bit, but with 32-bit output
6095
6096; Everything done in 64-bit, truncation happens last.
6097define i32 @bextr64_32_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
6098; X86-NOBMI-LABEL: bextr64_32_c0:
6099; X86-NOBMI:       # %bb.0:
6100; X86-NOBMI-NEXT:    pushl %esi
6101; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6102; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6103; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6104; X86-NOBMI-NEXT:    movl %esi, %edx
6105; X86-NOBMI-NEXT:    shrl %cl, %edx
6106; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
6107; X86-NOBMI-NEXT:    testb $32, %cl
6108; X86-NOBMI-NEXT:    jne .LBB47_2
6109; X86-NOBMI-NEXT:  # %bb.1:
6110; X86-NOBMI-NEXT:    movl %eax, %edx
6111; X86-NOBMI-NEXT:  .LBB47_2:
6112; X86-NOBMI-NEXT:    movb $64, %cl
6113; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6114; X86-NOBMI-NEXT:    movl $-1, %eax
6115; X86-NOBMI-NEXT:    shrl %cl, %eax
6116; X86-NOBMI-NEXT:    testb $32, %cl
6117; X86-NOBMI-NEXT:    jne .LBB47_4
6118; X86-NOBMI-NEXT:  # %bb.3:
6119; X86-NOBMI-NEXT:    movl $-1, %eax
6120; X86-NOBMI-NEXT:  .LBB47_4:
6121; X86-NOBMI-NEXT:    andl %edx, %eax
6122; X86-NOBMI-NEXT:    popl %esi
6123; X86-NOBMI-NEXT:    retl
6124;
6125; X86-BMI1-LABEL: bextr64_32_c0:
6126; X86-BMI1:       # %bb.0:
6127; X86-BMI1-NEXT:    pushl %esi
6128; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6129; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
6130; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
6131; X86-BMI1-NEXT:    movl %esi, %edx
6132; X86-BMI1-NEXT:    shrl %cl, %edx
6133; X86-BMI1-NEXT:    shrdl %cl, %esi, %eax
6134; X86-BMI1-NEXT:    testb $32, %cl
6135; X86-BMI1-NEXT:    jne .LBB47_2
6136; X86-BMI1-NEXT:  # %bb.1:
6137; X86-BMI1-NEXT:    movl %eax, %edx
6138; X86-BMI1-NEXT:  .LBB47_2:
6139; X86-BMI1-NEXT:    movb $64, %cl
6140; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
6141; X86-BMI1-NEXT:    movl $-1, %eax
6142; X86-BMI1-NEXT:    shrl %cl, %eax
6143; X86-BMI1-NEXT:    testb $32, %cl
6144; X86-BMI1-NEXT:    jne .LBB47_4
6145; X86-BMI1-NEXT:  # %bb.3:
6146; X86-BMI1-NEXT:    movl $-1, %eax
6147; X86-BMI1-NEXT:  .LBB47_4:
6148; X86-BMI1-NEXT:    andl %edx, %eax
6149; X86-BMI1-NEXT:    popl %esi
6150; X86-BMI1-NEXT:    retl
6151;
6152; X86-BMI2-LABEL: bextr64_32_c0:
6153; X86-BMI2:       # %bb.0:
6154; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6155; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6156; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6157; X86-BMI2-NEXT:    shrdl %cl, %eax, %edx
6158; X86-BMI2-NEXT:    testb $32, %cl
6159; X86-BMI2-NEXT:    je .LBB47_2
6160; X86-BMI2-NEXT:  # %bb.1:
6161; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
6162; X86-BMI2-NEXT:  .LBB47_2:
6163; X86-BMI2-NEXT:    movb $64, %cl
6164; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6165; X86-BMI2-NEXT:    movl $-1, %eax
6166; X86-BMI2-NEXT:    testb $32, %cl
6167; X86-BMI2-NEXT:    je .LBB47_4
6168; X86-BMI2-NEXT:  # %bb.3:
6169; X86-BMI2-NEXT:    shrxl %ecx, %eax, %eax
6170; X86-BMI2-NEXT:  .LBB47_4:
6171; X86-BMI2-NEXT:    andl %edx, %eax
6172; X86-BMI2-NEXT:    retl
6173;
6174; X64-NOBMI-LABEL: bextr64_32_c0:
6175; X64-NOBMI:       # %bb.0:
6176; X64-NOBMI-NEXT:    movq %rsi, %rcx
6177; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6178; X64-NOBMI-NEXT:    shrq %cl, %rdi
6179; X64-NOBMI-NEXT:    negb %dl
6180; X64-NOBMI-NEXT:    movq $-1, %rax
6181; X64-NOBMI-NEXT:    movl %edx, %ecx
6182; X64-NOBMI-NEXT:    shrq %cl, %rax
6183; X64-NOBMI-NEXT:    andl %edi, %eax
6184; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
6185; X64-NOBMI-NEXT:    retq
6186;
6187; X64-BMI1-LABEL: bextr64_32_c0:
6188; X64-BMI1:       # %bb.0:
6189; X64-BMI1-NEXT:    shll $8, %edx
6190; X64-BMI1-NEXT:    movzbl %sil, %eax
6191; X64-BMI1-NEXT:    orl %edx, %eax
6192; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
6193; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
6194; X64-BMI1-NEXT:    retq
6195;
6196; X64-BMI2-LABEL: bextr64_32_c0:
6197; X64-BMI2:       # %bb.0:
6198; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6199; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6200; X64-BMI2-NEXT:    retq
6201  %shifted = lshr i64 %val, %numskipbits
6202  %numhighbits = sub i64 64, %numlowbits
6203  %mask = lshr i64 -1, %numhighbits
6204  %masked = and i64 %mask, %shifted
6205  %res = trunc i64 %masked to i32
6206  ret i32 %res
6207}
6208
6209; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
6210define i32 @bextr64_32_c1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
6211; X86-NOBMI-LABEL: bextr64_32_c1:
6212; X86-NOBMI:       # %bb.0:
6213; X86-NOBMI-NEXT:    pushl %esi
6214; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6215; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6216; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6217; X86-NOBMI-NEXT:    movl %esi, %eax
6218; X86-NOBMI-NEXT:    shrl %cl, %eax
6219; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
6220; X86-NOBMI-NEXT:    testb $32, %cl
6221; X86-NOBMI-NEXT:    jne .LBB48_2
6222; X86-NOBMI-NEXT:  # %bb.1:
6223; X86-NOBMI-NEXT:    movl %edx, %eax
6224; X86-NOBMI-NEXT:  .LBB48_2:
6225; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6226; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6227; X86-NOBMI-NEXT:    shll %cl, %eax
6228; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6229; X86-NOBMI-NEXT:    shrl %cl, %eax
6230; X86-NOBMI-NEXT:    popl %esi
6231; X86-NOBMI-NEXT:    retl
6232;
6233; X86-BMI1-LABEL: bextr64_32_c1:
6234; X86-BMI1:       # %bb.0:
6235; X86-BMI1-NEXT:    pushl %edi
6236; X86-BMI1-NEXT:    pushl %esi
6237; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6238; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6239; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
6240; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
6241; X86-BMI1-NEXT:    movl %edi, %edx
6242; X86-BMI1-NEXT:    shrl %cl, %edx
6243; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
6244; X86-BMI1-NEXT:    testb $32, %cl
6245; X86-BMI1-NEXT:    jne .LBB48_2
6246; X86-BMI1-NEXT:  # %bb.1:
6247; X86-BMI1-NEXT:    movl %esi, %edx
6248; X86-BMI1-NEXT:  .LBB48_2:
6249; X86-BMI1-NEXT:    shll $8, %eax
6250; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
6251; X86-BMI1-NEXT:    popl %esi
6252; X86-BMI1-NEXT:    popl %edi
6253; X86-BMI1-NEXT:    retl
6254;
6255; X86-BMI2-LABEL: bextr64_32_c1:
6256; X86-BMI2:       # %bb.0:
6257; X86-BMI2-NEXT:    pushl %esi
6258; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6259; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6260; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6261; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
6262; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
6263; X86-BMI2-NEXT:    testb $32, %cl
6264; X86-BMI2-NEXT:    je .LBB48_2
6265; X86-BMI2-NEXT:  # %bb.1:
6266; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
6267; X86-BMI2-NEXT:  .LBB48_2:
6268; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
6269; X86-BMI2-NEXT:    popl %esi
6270; X86-BMI2-NEXT:    retl
6271;
6272; X64-NOBMI-LABEL: bextr64_32_c1:
6273; X64-NOBMI:       # %bb.0:
6274; X64-NOBMI-NEXT:    movq %rsi, %rcx
6275; X64-NOBMI-NEXT:    movq %rdi, %rax
6276; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6277; X64-NOBMI-NEXT:    shrq %cl, %rax
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:    # kill: def $eax killed $eax killed $rax
6283; X64-NOBMI-NEXT:    retq
6284;
6285; X64-BMI1-LABEL: bextr64_32_c1:
6286; X64-BMI1:       # %bb.0:
6287; X64-BMI1-NEXT:    shll $8, %edx
6288; X64-BMI1-NEXT:    movzbl %sil, %eax
6289; X64-BMI1-NEXT:    orl %edx, %eax
6290; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
6291; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
6292; X64-BMI1-NEXT:    retq
6293;
6294; X64-BMI2-LABEL: bextr64_32_c1:
6295; X64-BMI2:       # %bb.0:
6296; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6297; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6298; X64-BMI2-NEXT:    retq
6299  %shifted = lshr i64 %val, %numskipbits
6300  %truncshifted = trunc i64 %shifted to i32
6301  %numhighbits = sub i32 32, %numlowbits
6302  %mask = lshr i32 -1, %numhighbits
6303  %masked = and i32 %mask, %truncshifted
6304  ret i32 %masked
6305}
6306
6307; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.
6308; Masking is 64-bit. Then truncation.
6309define i32 @bextr64_32_c2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
6310; X86-NOBMI-LABEL: bextr64_32_c2:
6311; X86-NOBMI:       # %bb.0:
6312; X86-NOBMI-NEXT:    pushl %esi
6313; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6314; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6315; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6316; X86-NOBMI-NEXT:    movl %esi, %eax
6317; X86-NOBMI-NEXT:    shrl %cl, %eax
6318; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
6319; X86-NOBMI-NEXT:    testb $32, %cl
6320; X86-NOBMI-NEXT:    jne .LBB49_2
6321; X86-NOBMI-NEXT:  # %bb.1:
6322; X86-NOBMI-NEXT:    movl %edx, %eax
6323; X86-NOBMI-NEXT:  .LBB49_2:
6324; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6325; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6326; X86-NOBMI-NEXT:    shll %cl, %eax
6327; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6328; X86-NOBMI-NEXT:    shrl %cl, %eax
6329; X86-NOBMI-NEXT:    popl %esi
6330; X86-NOBMI-NEXT:    retl
6331;
6332; X86-BMI1-LABEL: bextr64_32_c2:
6333; X86-BMI1:       # %bb.0:
6334; X86-BMI1-NEXT:    pushl %edi
6335; X86-BMI1-NEXT:    pushl %esi
6336; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6337; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6338; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
6339; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
6340; X86-BMI1-NEXT:    movl %edi, %edx
6341; X86-BMI1-NEXT:    shrl %cl, %edx
6342; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
6343; X86-BMI1-NEXT:    testb $32, %cl
6344; X86-BMI1-NEXT:    jne .LBB49_2
6345; X86-BMI1-NEXT:  # %bb.1:
6346; X86-BMI1-NEXT:    movl %esi, %edx
6347; X86-BMI1-NEXT:  .LBB49_2:
6348; X86-BMI1-NEXT:    shll $8, %eax
6349; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
6350; X86-BMI1-NEXT:    popl %esi
6351; X86-BMI1-NEXT:    popl %edi
6352; X86-BMI1-NEXT:    retl
6353;
6354; X86-BMI2-LABEL: bextr64_32_c2:
6355; X86-BMI2:       # %bb.0:
6356; X86-BMI2-NEXT:    pushl %esi
6357; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6358; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6359; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6360; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
6361; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
6362; X86-BMI2-NEXT:    testb $32, %cl
6363; X86-BMI2-NEXT:    je .LBB49_2
6364; X86-BMI2-NEXT:  # %bb.1:
6365; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
6366; X86-BMI2-NEXT:  .LBB49_2:
6367; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
6368; X86-BMI2-NEXT:    popl %esi
6369; X86-BMI2-NEXT:    retl
6370;
6371; X64-NOBMI-LABEL: bextr64_32_c2:
6372; X64-NOBMI:       # %bb.0:
6373; X64-NOBMI-NEXT:    movq %rsi, %rcx
6374; X64-NOBMI-NEXT:    movq %rdi, %rax
6375; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6376; X64-NOBMI-NEXT:    shrq %cl, %rax
6377; X64-NOBMI-NEXT:    negb %dl
6378; X64-NOBMI-NEXT:    movl %edx, %ecx
6379; X64-NOBMI-NEXT:    shll %cl, %eax
6380; X64-NOBMI-NEXT:    shrl %cl, %eax
6381; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
6382; X64-NOBMI-NEXT:    retq
6383;
6384; X64-BMI1-LABEL: bextr64_32_c2:
6385; X64-BMI1:       # %bb.0:
6386; X64-BMI1-NEXT:    shll $8, %edx
6387; X64-BMI1-NEXT:    movzbl %sil, %eax
6388; X64-BMI1-NEXT:    orl %edx, %eax
6389; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
6390; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
6391; X64-BMI1-NEXT:    retq
6392;
6393; X64-BMI2-LABEL: bextr64_32_c2:
6394; X64-BMI2:       # %bb.0:
6395; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
6396; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6397; X64-BMI2-NEXT:    retq
6398  %shifted = lshr i64 %val, %numskipbits
6399  %numhighbits = sub i32 32, %numlowbits
6400  %mask = lshr i32 -1, %numhighbits
6401  %zextmask = zext i32 %mask to i64
6402  %masked = and i64 %zextmask, %shifted
6403  %truncmasked = trunc i64 %masked to i32
6404  ret i32 %truncmasked
6405}
6406
6407; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit.
6408; Masking is 64-bit. Then truncation.
6409define i32 @bextr64_32_c3(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
6410; X86-NOBMI-LABEL: bextr64_32_c3:
6411; X86-NOBMI:       # %bb.0:
6412; X86-NOBMI-NEXT:    pushl %esi
6413; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6414; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6415; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6416; X86-NOBMI-NEXT:    movl %esi, %edx
6417; X86-NOBMI-NEXT:    shrl %cl, %edx
6418; X86-NOBMI-NEXT:    shrdl %cl, %esi, %eax
6419; X86-NOBMI-NEXT:    testb $32, %cl
6420; X86-NOBMI-NEXT:    jne .LBB50_2
6421; X86-NOBMI-NEXT:  # %bb.1:
6422; X86-NOBMI-NEXT:    movl %eax, %edx
6423; X86-NOBMI-NEXT:  .LBB50_2:
6424; X86-NOBMI-NEXT:    movb $64, %cl
6425; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6426; X86-NOBMI-NEXT:    xorl %eax, %eax
6427; X86-NOBMI-NEXT:    movl $-1, %esi
6428; X86-NOBMI-NEXT:    shrdl %cl, %eax, %esi
6429; X86-NOBMI-NEXT:    testb $32, %cl
6430; X86-NOBMI-NEXT:    jne .LBB50_4
6431; X86-NOBMI-NEXT:  # %bb.3:
6432; X86-NOBMI-NEXT:    movl %esi, %eax
6433; X86-NOBMI-NEXT:  .LBB50_4:
6434; X86-NOBMI-NEXT:    andl %edx, %eax
6435; X86-NOBMI-NEXT:    popl %esi
6436; X86-NOBMI-NEXT:    retl
6437;
6438; X86-BMI1-LABEL: bextr64_32_c3:
6439; X86-BMI1:       # %bb.0:
6440; X86-BMI1-NEXT:    pushl %esi
6441; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6442; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
6443; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
6444; X86-BMI1-NEXT:    movl %esi, %edx
6445; X86-BMI1-NEXT:    shrl %cl, %edx
6446; X86-BMI1-NEXT:    shrdl %cl, %esi, %eax
6447; X86-BMI1-NEXT:    testb $32, %cl
6448; X86-BMI1-NEXT:    jne .LBB50_2
6449; X86-BMI1-NEXT:  # %bb.1:
6450; X86-BMI1-NEXT:    movl %eax, %edx
6451; X86-BMI1-NEXT:  .LBB50_2:
6452; X86-BMI1-NEXT:    movb $64, %cl
6453; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
6454; X86-BMI1-NEXT:    xorl %eax, %eax
6455; X86-BMI1-NEXT:    movl $-1, %esi
6456; X86-BMI1-NEXT:    shrdl %cl, %eax, %esi
6457; X86-BMI1-NEXT:    testb $32, %cl
6458; X86-BMI1-NEXT:    jne .LBB50_4
6459; X86-BMI1-NEXT:  # %bb.3:
6460; X86-BMI1-NEXT:    movl %esi, %eax
6461; X86-BMI1-NEXT:  .LBB50_4:
6462; X86-BMI1-NEXT:    andl %edx, %eax
6463; X86-BMI1-NEXT:    popl %esi
6464; X86-BMI1-NEXT:    retl
6465;
6466; X86-BMI2-LABEL: bextr64_32_c3:
6467; X86-BMI2:       # %bb.0:
6468; X86-BMI2-NEXT:    pushl %esi
6469; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6470; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
6471; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
6472; X86-BMI2-NEXT:    shrdl %cl, %eax, %edx
6473; X86-BMI2-NEXT:    testb $32, %cl
6474; X86-BMI2-NEXT:    je .LBB50_2
6475; X86-BMI2-NEXT:  # %bb.1:
6476; X86-BMI2-NEXT:    shrxl %ecx, %eax, %edx
6477; X86-BMI2-NEXT:  .LBB50_2:
6478; X86-BMI2-NEXT:    movb $64, %cl
6479; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
6480; X86-BMI2-NEXT:    xorl %eax, %eax
6481; X86-BMI2-NEXT:    movl $-1, %esi
6482; X86-BMI2-NEXT:    shrdl %cl, %eax, %esi
6483; X86-BMI2-NEXT:    testb $32, %cl
6484; X86-BMI2-NEXT:    jne .LBB50_4
6485; X86-BMI2-NEXT:  # %bb.3:
6486; X86-BMI2-NEXT:    movl %esi, %eax
6487; X86-BMI2-NEXT:  .LBB50_4:
6488; X86-BMI2-NEXT:    andl %edx, %eax
6489; X86-BMI2-NEXT:    popl %esi
6490; X86-BMI2-NEXT:    retl
6491;
6492; X64-NOBMI-LABEL: bextr64_32_c3:
6493; X64-NOBMI:       # %bb.0:
6494; X64-NOBMI-NEXT:    movq %rsi, %rcx
6495; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
6496; X64-NOBMI-NEXT:    shrq %cl, %rdi
6497; X64-NOBMI-NEXT:    negb %dl
6498; X64-NOBMI-NEXT:    movl $4294967295, %eax # imm = 0xFFFFFFFF
6499; X64-NOBMI-NEXT:    movl %edx, %ecx
6500; X64-NOBMI-NEXT:    shrq %cl, %rax
6501; X64-NOBMI-NEXT:    andl %edi, %eax
6502; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
6503; X64-NOBMI-NEXT:    retq
6504;
6505; X64-BMI1-LABEL: bextr64_32_c3:
6506; X64-BMI1:       # %bb.0:
6507; X64-BMI1-NEXT:    movq %rsi, %rcx
6508; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
6509; X64-BMI1-NEXT:    shrq %cl, %rdi
6510; X64-BMI1-NEXT:    negb %dl
6511; X64-BMI1-NEXT:    movl $4294967295, %eax # imm = 0xFFFFFFFF
6512; X64-BMI1-NEXT:    movl %edx, %ecx
6513; X64-BMI1-NEXT:    shrq %cl, %rax
6514; X64-BMI1-NEXT:    andl %edi, %eax
6515; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
6516; X64-BMI1-NEXT:    retq
6517;
6518; X64-BMI2-LABEL: bextr64_32_c3:
6519; X64-BMI2:       # %bb.0:
6520; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rcx
6521; X64-BMI2-NEXT:    negb %dl
6522; X64-BMI2-NEXT:    movl $4294967295, %eax # imm = 0xFFFFFFFF
6523; X64-BMI2-NEXT:    shrxq %rdx, %rax, %rax
6524; X64-BMI2-NEXT:    andl %ecx, %eax
6525; X64-BMI2-NEXT:    # kill: def $eax killed $eax killed $rax
6526; X64-BMI2-NEXT:    retq
6527  %shifted = lshr i64 %val, %numskipbits
6528  %numhighbits = sub i64 64, %numlowbits
6529  %mask = lshr i64 4294967295, %numhighbits
6530  %masked = and i64 %mask, %shifted
6531  %truncmasked = trunc i64 %masked to i32
6532  ret i32 %truncmasked
6533}
6534
6535; ---------------------------------------------------------------------------- ;
6536; Pattern d. 32-bit.
6537; ---------------------------------------------------------------------------- ;
6538
6539define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
6540; X86-NOBMI-LABEL: bextr32_d0:
6541; X86-NOBMI:       # %bb.0:
6542; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6543; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6544; X86-NOBMI-NEXT:    shrl %cl, %eax
6545; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6546; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6547; X86-NOBMI-NEXT:    shll %cl, %eax
6548; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6549; X86-NOBMI-NEXT:    shrl %cl, %eax
6550; X86-NOBMI-NEXT:    retl
6551;
6552; X86-BMI1-LABEL: bextr32_d0:
6553; X86-BMI1:       # %bb.0:
6554; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6555; X86-BMI1-NEXT:    shll $8, %eax
6556; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6557; X86-BMI1-NEXT:    orl %eax, %ecx
6558; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
6559; X86-BMI1-NEXT:    retl
6560;
6561; X86-BMI2-LABEL: bextr32_d0:
6562; X86-BMI2:       # %bb.0:
6563; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6564; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6565; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
6566; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
6567; X86-BMI2-NEXT:    retl
6568;
6569; X64-NOBMI-LABEL: bextr32_d0:
6570; X64-NOBMI:       # %bb.0:
6571; X64-NOBMI-NEXT:    movl %esi, %ecx
6572; X64-NOBMI-NEXT:    movl %edi, %eax
6573; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6574; X64-NOBMI-NEXT:    shrl %cl, %eax
6575; X64-NOBMI-NEXT:    negb %dl
6576; X64-NOBMI-NEXT:    movl %edx, %ecx
6577; X64-NOBMI-NEXT:    shll %cl, %eax
6578; X64-NOBMI-NEXT:    shrl %cl, %eax
6579; X64-NOBMI-NEXT:    retq
6580;
6581; X64-BMI1-LABEL: bextr32_d0:
6582; X64-BMI1:       # %bb.0:
6583; X64-BMI1-NEXT:    shll $8, %edx
6584; X64-BMI1-NEXT:    movzbl %sil, %eax
6585; X64-BMI1-NEXT:    orl %edx, %eax
6586; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
6587; X64-BMI1-NEXT:    retq
6588;
6589; X64-BMI2-LABEL: bextr32_d0:
6590; X64-BMI2:       # %bb.0:
6591; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
6592; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6593; X64-BMI2-NEXT:    retq
6594  %shifted = lshr i32 %val, %numskipbits
6595  %numhighbits = sub i32 32, %numlowbits
6596  %highbitscleared = shl i32 %shifted, %numhighbits
6597  %masked = lshr i32 %highbitscleared, %numhighbits
6598  ret i32 %masked
6599}
6600
6601define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
6602; X86-NOBMI-LABEL: bextr32_d1_indexzext:
6603; X86-NOBMI:       # %bb.0:
6604; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6605; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6606; X86-NOBMI-NEXT:    shrl %cl, %eax
6607; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6608; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6609; X86-NOBMI-NEXT:    shll %cl, %eax
6610; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6611; X86-NOBMI-NEXT:    shrl %cl, %eax
6612; X86-NOBMI-NEXT:    retl
6613;
6614; X86-BMI1-LABEL: bextr32_d1_indexzext:
6615; X86-BMI1:       # %bb.0:
6616; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6617; X86-BMI1-NEXT:    shll $8, %eax
6618; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6619; X86-BMI1-NEXT:    orl %eax, %ecx
6620; X86-BMI1-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %eax
6621; X86-BMI1-NEXT:    retl
6622;
6623; X86-BMI2-LABEL: bextr32_d1_indexzext:
6624; X86-BMI2:       # %bb.0:
6625; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6626; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6627; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %ecx
6628; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
6629; X86-BMI2-NEXT:    retl
6630;
6631; X64-NOBMI-LABEL: bextr32_d1_indexzext:
6632; X64-NOBMI:       # %bb.0:
6633; X64-NOBMI-NEXT:    movl %esi, %ecx
6634; X64-NOBMI-NEXT:    movl %edi, %eax
6635; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6636; X64-NOBMI-NEXT:    shrl %cl, %eax
6637; X64-NOBMI-NEXT:    negb %dl
6638; X64-NOBMI-NEXT:    movl %edx, %ecx
6639; X64-NOBMI-NEXT:    shll %cl, %eax
6640; X64-NOBMI-NEXT:    shrl %cl, %eax
6641; X64-NOBMI-NEXT:    retq
6642;
6643; X64-BMI1-LABEL: bextr32_d1_indexzext:
6644; X64-BMI1:       # %bb.0:
6645; X64-BMI1-NEXT:    shll $8, %edx
6646; X64-BMI1-NEXT:    movzbl %sil, %eax
6647; X64-BMI1-NEXT:    orl %edx, %eax
6648; X64-BMI1-NEXT:    bextrl %eax, %edi, %eax
6649; X64-BMI1-NEXT:    retq
6650;
6651; X64-BMI2-LABEL: bextr32_d1_indexzext:
6652; X64-BMI2:       # %bb.0:
6653; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
6654; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6655; X64-BMI2-NEXT:    retq
6656  %skip = zext i8 %numskipbits to i32
6657  %shifted = lshr i32 %val, %skip
6658  %numhighbits = sub i8 32, %numlowbits
6659  %sh_prom = zext i8 %numhighbits to i32
6660  %highbitscleared = shl i32 %shifted, %sh_prom
6661  %masked = lshr i32 %highbitscleared, %sh_prom
6662  ret i32 %masked
6663}
6664
6665define i32 @bextr32_d2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {
6666; X86-NOBMI-LABEL: bextr32_d2_load:
6667; X86-NOBMI:       # %bb.0:
6668; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6669; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6670; X86-NOBMI-NEXT:    movl (%eax), %eax
6671; X86-NOBMI-NEXT:    shrl %cl, %eax
6672; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6673; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6674; X86-NOBMI-NEXT:    shll %cl, %eax
6675; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6676; X86-NOBMI-NEXT:    shrl %cl, %eax
6677; X86-NOBMI-NEXT:    retl
6678;
6679; X86-BMI1-LABEL: bextr32_d2_load:
6680; X86-BMI1:       # %bb.0:
6681; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
6682; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6683; X86-BMI1-NEXT:    shll $8, %ecx
6684; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6685; X86-BMI1-NEXT:    orl %ecx, %edx
6686; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
6687; X86-BMI1-NEXT:    retl
6688;
6689; X86-BMI2-LABEL: bextr32_d2_load:
6690; X86-BMI2:       # %bb.0:
6691; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6692; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6693; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6694; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
6695; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
6696; X86-BMI2-NEXT:    retl
6697;
6698; X64-NOBMI-LABEL: bextr32_d2_load:
6699; X64-NOBMI:       # %bb.0:
6700; X64-NOBMI-NEXT:    movl %esi, %ecx
6701; X64-NOBMI-NEXT:    movl (%rdi), %eax
6702; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6703; X64-NOBMI-NEXT:    shrl %cl, %eax
6704; X64-NOBMI-NEXT:    negb %dl
6705; X64-NOBMI-NEXT:    movl %edx, %ecx
6706; X64-NOBMI-NEXT:    shll %cl, %eax
6707; X64-NOBMI-NEXT:    shrl %cl, %eax
6708; X64-NOBMI-NEXT:    retq
6709;
6710; X64-BMI1-LABEL: bextr32_d2_load:
6711; X64-BMI1:       # %bb.0:
6712; X64-BMI1-NEXT:    shll $8, %edx
6713; X64-BMI1-NEXT:    movzbl %sil, %eax
6714; X64-BMI1-NEXT:    orl %edx, %eax
6715; X64-BMI1-NEXT:    bextrl %eax, (%rdi), %eax
6716; X64-BMI1-NEXT:    retq
6717;
6718; X64-BMI2-LABEL: bextr32_d2_load:
6719; X64-BMI2:       # %bb.0:
6720; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
6721; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6722; X64-BMI2-NEXT:    retq
6723  %val = load i32, ptr %w
6724  %shifted = lshr i32 %val, %numskipbits
6725  %numhighbits = sub i32 32, %numlowbits
6726  %highbitscleared = shl i32 %shifted, %numhighbits
6727  %masked = lshr i32 %highbitscleared, %numhighbits
6728  ret i32 %masked
6729}
6730
6731define i32 @bextr32_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {
6732; X86-NOBMI-LABEL: bextr32_d3_load_indexzext:
6733; X86-NOBMI:       # %bb.0:
6734; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6735; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6736; X86-NOBMI-NEXT:    movl (%eax), %eax
6737; X86-NOBMI-NEXT:    shrl %cl, %eax
6738; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6739; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6740; X86-NOBMI-NEXT:    shll %cl, %eax
6741; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6742; X86-NOBMI-NEXT:    shrl %cl, %eax
6743; X86-NOBMI-NEXT:    retl
6744;
6745; X86-BMI1-LABEL: bextr32_d3_load_indexzext:
6746; X86-BMI1:       # %bb.0:
6747; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
6748; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6749; X86-BMI1-NEXT:    shll $8, %ecx
6750; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6751; X86-BMI1-NEXT:    orl %ecx, %edx
6752; X86-BMI1-NEXT:    bextrl %edx, (%eax), %eax
6753; X86-BMI1-NEXT:    retl
6754;
6755; X86-BMI2-LABEL: bextr32_d3_load_indexzext:
6756; X86-BMI2:       # %bb.0:
6757; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6758; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6759; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6760; X86-BMI2-NEXT:    shrxl %edx, (%ecx), %ecx
6761; X86-BMI2-NEXT:    bzhil %eax, %ecx, %eax
6762; X86-BMI2-NEXT:    retl
6763;
6764; X64-NOBMI-LABEL: bextr32_d3_load_indexzext:
6765; X64-NOBMI:       # %bb.0:
6766; X64-NOBMI-NEXT:    movl %esi, %ecx
6767; X64-NOBMI-NEXT:    movl (%rdi), %eax
6768; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6769; X64-NOBMI-NEXT:    shrl %cl, %eax
6770; X64-NOBMI-NEXT:    negb %dl
6771; X64-NOBMI-NEXT:    movl %edx, %ecx
6772; X64-NOBMI-NEXT:    shll %cl, %eax
6773; X64-NOBMI-NEXT:    shrl %cl, %eax
6774; X64-NOBMI-NEXT:    retq
6775;
6776; X64-BMI1-LABEL: bextr32_d3_load_indexzext:
6777; X64-BMI1:       # %bb.0:
6778; X64-BMI1-NEXT:    shll $8, %edx
6779; X64-BMI1-NEXT:    movzbl %sil, %eax
6780; X64-BMI1-NEXT:    orl %edx, %eax
6781; X64-BMI1-NEXT:    bextrl %eax, (%rdi), %eax
6782; X64-BMI1-NEXT:    retq
6783;
6784; X64-BMI2-LABEL: bextr32_d3_load_indexzext:
6785; X64-BMI2:       # %bb.0:
6786; X64-BMI2-NEXT:    shrxl %esi, (%rdi), %eax
6787; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
6788; X64-BMI2-NEXT:    retq
6789  %val = load i32, ptr %w
6790  %skip = zext i8 %numskipbits to i32
6791  %shifted = lshr i32 %val, %skip
6792  %numhighbits = sub i8 32, %numlowbits
6793  %sh_prom = zext i8 %numhighbits to i32
6794  %highbitscleared = shl i32 %shifted, %sh_prom
6795  %masked = lshr i32 %highbitscleared, %sh_prom
6796  ret i32 %masked
6797}
6798
6799define i32 @bextr32_d5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
6800; X86-NOBMI-LABEL: bextr32_d5_skipextrauses:
6801; X86-NOBMI:       # %bb.0:
6802; X86-NOBMI-NEXT:    pushl %esi
6803; X86-NOBMI-NEXT:    subl $8, %esp
6804; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
6805; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
6806; X86-NOBMI-NEXT:    movl %eax, %ecx
6807; X86-NOBMI-NEXT:    shrl %cl, %esi
6808; X86-NOBMI-NEXT:    xorl %ecx, %ecx
6809; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6810; X86-NOBMI-NEXT:    shll %cl, %esi
6811; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
6812; X86-NOBMI-NEXT:    shrl %cl, %esi
6813; X86-NOBMI-NEXT:    movl %eax, (%esp)
6814; X86-NOBMI-NEXT:    calll use32@PLT
6815; X86-NOBMI-NEXT:    movl %esi, %eax
6816; X86-NOBMI-NEXT:    addl $8, %esp
6817; X86-NOBMI-NEXT:    popl %esi
6818; X86-NOBMI-NEXT:    retl
6819;
6820; X86-BMI1-LABEL: bextr32_d5_skipextrauses:
6821; X86-BMI1:       # %bb.0:
6822; X86-BMI1-NEXT:    pushl %esi
6823; X86-BMI1-NEXT:    subl $8, %esp
6824; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6825; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
6826; X86-BMI1-NEXT:    shll $8, %ecx
6827; X86-BMI1-NEXT:    movzbl %al, %edx
6828; X86-BMI1-NEXT:    orl %ecx, %edx
6829; X86-BMI1-NEXT:    bextrl %edx, {{[0-9]+}}(%esp), %esi
6830; X86-BMI1-NEXT:    movl %eax, (%esp)
6831; X86-BMI1-NEXT:    calll use32@PLT
6832; X86-BMI1-NEXT:    movl %esi, %eax
6833; X86-BMI1-NEXT:    addl $8, %esp
6834; X86-BMI1-NEXT:    popl %esi
6835; X86-BMI1-NEXT:    retl
6836;
6837; X86-BMI2-LABEL: bextr32_d5_skipextrauses:
6838; X86-BMI2:       # %bb.0:
6839; X86-BMI2-NEXT:    pushl %esi
6840; X86-BMI2-NEXT:    subl $8, %esp
6841; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
6842; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6843; X86-BMI2-NEXT:    shrxl %ecx, {{[0-9]+}}(%esp), %edx
6844; X86-BMI2-NEXT:    bzhil %eax, %edx, %esi
6845; X86-BMI2-NEXT:    movl %ecx, (%esp)
6846; X86-BMI2-NEXT:    calll use32@PLT
6847; X86-BMI2-NEXT:    movl %esi, %eax
6848; X86-BMI2-NEXT:    addl $8, %esp
6849; X86-BMI2-NEXT:    popl %esi
6850; X86-BMI2-NEXT:    retl
6851;
6852; X64-NOBMI-LABEL: bextr32_d5_skipextrauses:
6853; X64-NOBMI:       # %bb.0:
6854; X64-NOBMI-NEXT:    pushq %rbx
6855; X64-NOBMI-NEXT:    movl %edi, %ebx
6856; X64-NOBMI-NEXT:    movl %esi, %ecx
6857; X64-NOBMI-NEXT:    shrl %cl, %ebx
6858; X64-NOBMI-NEXT:    negb %dl
6859; X64-NOBMI-NEXT:    movl %edx, %ecx
6860; X64-NOBMI-NEXT:    shll %cl, %ebx
6861; X64-NOBMI-NEXT:    shrl %cl, %ebx
6862; X64-NOBMI-NEXT:    movl %esi, %edi
6863; X64-NOBMI-NEXT:    callq use32@PLT
6864; X64-NOBMI-NEXT:    movl %ebx, %eax
6865; X64-NOBMI-NEXT:    popq %rbx
6866; X64-NOBMI-NEXT:    retq
6867;
6868; X64-BMI1-LABEL: bextr32_d5_skipextrauses:
6869; X64-BMI1:       # %bb.0:
6870; X64-BMI1-NEXT:    pushq %rbx
6871; X64-BMI1-NEXT:    shll $8, %edx
6872; X64-BMI1-NEXT:    movzbl %sil, %eax
6873; X64-BMI1-NEXT:    orl %edx, %eax
6874; X64-BMI1-NEXT:    bextrl %eax, %edi, %ebx
6875; X64-BMI1-NEXT:    movl %esi, %edi
6876; X64-BMI1-NEXT:    callq use32@PLT
6877; X64-BMI1-NEXT:    movl %ebx, %eax
6878; X64-BMI1-NEXT:    popq %rbx
6879; X64-BMI1-NEXT:    retq
6880;
6881; X64-BMI2-LABEL: bextr32_d5_skipextrauses:
6882; X64-BMI2:       # %bb.0:
6883; X64-BMI2-NEXT:    pushq %rbx
6884; X64-BMI2-NEXT:    shrxl %esi, %edi, %eax
6885; X64-BMI2-NEXT:    bzhil %edx, %eax, %ebx
6886; X64-BMI2-NEXT:    movl %esi, %edi
6887; X64-BMI2-NEXT:    callq use32@PLT
6888; X64-BMI2-NEXT:    movl %ebx, %eax
6889; X64-BMI2-NEXT:    popq %rbx
6890; X64-BMI2-NEXT:    retq
6891  %shifted = lshr i32 %val, %numskipbits
6892  %numhighbits = sub i32 32, %numlowbits
6893  %highbitscleared = shl i32 %shifted, %numhighbits
6894  %masked = lshr i32 %highbitscleared, %numhighbits
6895  call void @use32(i32 %numskipbits)
6896  ret i32 %masked
6897}
6898
6899; 64-bit.
6900
6901define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
6902; X86-NOBMI-LABEL: bextr64_d0:
6903; X86-NOBMI:       # %bb.0:
6904; X86-NOBMI-NEXT:    pushl %ebx
6905; X86-NOBMI-NEXT:    pushl %edi
6906; X86-NOBMI-NEXT:    pushl %esi
6907; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6908; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
6909; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
6910; X86-NOBMI-NEXT:    movl %edx, %eax
6911; X86-NOBMI-NEXT:    shrl %cl, %eax
6912; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
6913; X86-NOBMI-NEXT:    xorl %esi, %esi
6914; X86-NOBMI-NEXT:    testb $32, %cl
6915; X86-NOBMI-NEXT:    je .LBB56_2
6916; X86-NOBMI-NEXT:  # %bb.1:
6917; X86-NOBMI-NEXT:    movl %eax, %edi
6918; X86-NOBMI-NEXT:    xorl %eax, %eax
6919; X86-NOBMI-NEXT:  .LBB56_2:
6920; X86-NOBMI-NEXT:    movb $64, %cl
6921; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
6922; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
6923; X86-NOBMI-NEXT:    shll %cl, %edi
6924; X86-NOBMI-NEXT:    testb $32, %cl
6925; X86-NOBMI-NEXT:    movl %edi, %ebx
6926; X86-NOBMI-NEXT:    jne .LBB56_4
6927; X86-NOBMI-NEXT:  # %bb.3:
6928; X86-NOBMI-NEXT:    movl %eax, %ebx
6929; X86-NOBMI-NEXT:  .LBB56_4:
6930; X86-NOBMI-NEXT:    movl %ebx, %eax
6931; X86-NOBMI-NEXT:    shrl %cl, %eax
6932; X86-NOBMI-NEXT:    testb $32, %cl
6933; X86-NOBMI-NEXT:    movl $0, %edx
6934; X86-NOBMI-NEXT:    jne .LBB56_6
6935; X86-NOBMI-NEXT:  # %bb.5:
6936; X86-NOBMI-NEXT:    movl %edi, %esi
6937; X86-NOBMI-NEXT:    movl %eax, %edx
6938; X86-NOBMI-NEXT:  .LBB56_6:
6939; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
6940; X86-NOBMI-NEXT:    testb $32, %cl
6941; X86-NOBMI-NEXT:    jne .LBB56_8
6942; X86-NOBMI-NEXT:  # %bb.7:
6943; X86-NOBMI-NEXT:    movl %esi, %eax
6944; X86-NOBMI-NEXT:  .LBB56_8:
6945; X86-NOBMI-NEXT:    popl %esi
6946; X86-NOBMI-NEXT:    popl %edi
6947; X86-NOBMI-NEXT:    popl %ebx
6948; X86-NOBMI-NEXT:    retl
6949;
6950; X86-BMI1-LABEL: bextr64_d0:
6951; X86-BMI1:       # %bb.0:
6952; X86-BMI1-NEXT:    pushl %ebx
6953; X86-BMI1-NEXT:    pushl %edi
6954; X86-BMI1-NEXT:    pushl %esi
6955; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6956; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
6957; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
6958; X86-BMI1-NEXT:    movl %edx, %eax
6959; X86-BMI1-NEXT:    shrl %cl, %eax
6960; X86-BMI1-NEXT:    shrdl %cl, %edx, %edi
6961; X86-BMI1-NEXT:    xorl %esi, %esi
6962; X86-BMI1-NEXT:    testb $32, %cl
6963; X86-BMI1-NEXT:    je .LBB56_2
6964; X86-BMI1-NEXT:  # %bb.1:
6965; X86-BMI1-NEXT:    movl %eax, %edi
6966; X86-BMI1-NEXT:    xorl %eax, %eax
6967; X86-BMI1-NEXT:  .LBB56_2:
6968; X86-BMI1-NEXT:    movb $64, %cl
6969; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
6970; X86-BMI1-NEXT:    shldl %cl, %edi, %eax
6971; X86-BMI1-NEXT:    shll %cl, %edi
6972; X86-BMI1-NEXT:    testb $32, %cl
6973; X86-BMI1-NEXT:    movl %edi, %ebx
6974; X86-BMI1-NEXT:    jne .LBB56_4
6975; X86-BMI1-NEXT:  # %bb.3:
6976; X86-BMI1-NEXT:    movl %eax, %ebx
6977; X86-BMI1-NEXT:  .LBB56_4:
6978; X86-BMI1-NEXT:    movl %ebx, %eax
6979; X86-BMI1-NEXT:    shrl %cl, %eax
6980; X86-BMI1-NEXT:    testb $32, %cl
6981; X86-BMI1-NEXT:    movl $0, %edx
6982; X86-BMI1-NEXT:    jne .LBB56_6
6983; X86-BMI1-NEXT:  # %bb.5:
6984; X86-BMI1-NEXT:    movl %edi, %esi
6985; X86-BMI1-NEXT:    movl %eax, %edx
6986; X86-BMI1-NEXT:  .LBB56_6:
6987; X86-BMI1-NEXT:    shrdl %cl, %ebx, %esi
6988; X86-BMI1-NEXT:    testb $32, %cl
6989; X86-BMI1-NEXT:    jne .LBB56_8
6990; X86-BMI1-NEXT:  # %bb.7:
6991; X86-BMI1-NEXT:    movl %esi, %eax
6992; X86-BMI1-NEXT:  .LBB56_8:
6993; X86-BMI1-NEXT:    popl %esi
6994; X86-BMI1-NEXT:    popl %edi
6995; X86-BMI1-NEXT:    popl %ebx
6996; X86-BMI1-NEXT:    retl
6997;
6998; X86-BMI2-LABEL: bextr64_d0:
6999; X86-BMI2:       # %bb.0:
7000; X86-BMI2-NEXT:    pushl %edi
7001; X86-BMI2-NEXT:    pushl %esi
7002; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7003; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7004; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7005; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7006; X86-BMI2-NEXT:    shrxl %ecx, %edx, %esi
7007; X86-BMI2-NEXT:    xorl %edx, %edx
7008; X86-BMI2-NEXT:    testb $32, %cl
7009; X86-BMI2-NEXT:    je .LBB56_2
7010; X86-BMI2-NEXT:  # %bb.1:
7011; X86-BMI2-NEXT:    movl %esi, %eax
7012; X86-BMI2-NEXT:    xorl %esi, %esi
7013; X86-BMI2-NEXT:  .LBB56_2:
7014; X86-BMI2-NEXT:    movb $64, %cl
7015; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7016; X86-BMI2-NEXT:    shldl %cl, %eax, %esi
7017; X86-BMI2-NEXT:    shlxl %ecx, %eax, %edi
7018; X86-BMI2-NEXT:    testb $32, %cl
7019; X86-BMI2-NEXT:    je .LBB56_4
7020; X86-BMI2-NEXT:  # %bb.3:
7021; X86-BMI2-NEXT:    movl %edi, %esi
7022; X86-BMI2-NEXT:    movl $0, %edi
7023; X86-BMI2-NEXT:  .LBB56_4:
7024; X86-BMI2-NEXT:    shrxl %ecx, %esi, %eax
7025; X86-BMI2-NEXT:    jne .LBB56_6
7026; X86-BMI2-NEXT:  # %bb.5:
7027; X86-BMI2-NEXT:    movl %eax, %edx
7028; X86-BMI2-NEXT:  .LBB56_6:
7029; X86-BMI2-NEXT:    shrdl %cl, %esi, %edi
7030; X86-BMI2-NEXT:    testb $32, %cl
7031; X86-BMI2-NEXT:    jne .LBB56_8
7032; X86-BMI2-NEXT:  # %bb.7:
7033; X86-BMI2-NEXT:    movl %edi, %eax
7034; X86-BMI2-NEXT:  .LBB56_8:
7035; X86-BMI2-NEXT:    popl %esi
7036; X86-BMI2-NEXT:    popl %edi
7037; X86-BMI2-NEXT:    retl
7038;
7039; X64-NOBMI-LABEL: bextr64_d0:
7040; X64-NOBMI:       # %bb.0:
7041; X64-NOBMI-NEXT:    movq %rsi, %rcx
7042; X64-NOBMI-NEXT:    movq %rdi, %rax
7043; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
7044; X64-NOBMI-NEXT:    shrq %cl, %rax
7045; X64-NOBMI-NEXT:    negb %dl
7046; X64-NOBMI-NEXT:    movl %edx, %ecx
7047; X64-NOBMI-NEXT:    shlq %cl, %rax
7048; X64-NOBMI-NEXT:    shrq %cl, %rax
7049; X64-NOBMI-NEXT:    retq
7050;
7051; X64-BMI1-LABEL: bextr64_d0:
7052; X64-BMI1:       # %bb.0:
7053; X64-BMI1-NEXT:    shll $8, %edx
7054; X64-BMI1-NEXT:    movzbl %sil, %eax
7055; X64-BMI1-NEXT:    orl %edx, %eax
7056; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
7057; X64-BMI1-NEXT:    retq
7058;
7059; X64-BMI2-LABEL: bextr64_d0:
7060; X64-BMI2:       # %bb.0:
7061; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7062; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7063; X64-BMI2-NEXT:    retq
7064  %shifted = lshr i64 %val, %numskipbits
7065  %numhighbits = sub i64 64, %numlowbits
7066  %highbitscleared = shl i64 %shifted, %numhighbits
7067  %masked = lshr i64 %highbitscleared, %numhighbits
7068  ret i64 %masked
7069}
7070
7071define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {
7072; X86-NOBMI-LABEL: bextr64_d1_indexzext:
7073; X86-NOBMI:       # %bb.0:
7074; X86-NOBMI-NEXT:    pushl %ebx
7075; X86-NOBMI-NEXT:    pushl %edi
7076; X86-NOBMI-NEXT:    pushl %esi
7077; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7078; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
7079; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7080; X86-NOBMI-NEXT:    movl %edx, %eax
7081; X86-NOBMI-NEXT:    shrl %cl, %eax
7082; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
7083; X86-NOBMI-NEXT:    xorl %esi, %esi
7084; X86-NOBMI-NEXT:    testb $32, %cl
7085; X86-NOBMI-NEXT:    je .LBB57_2
7086; X86-NOBMI-NEXT:  # %bb.1:
7087; X86-NOBMI-NEXT:    movl %eax, %edi
7088; X86-NOBMI-NEXT:    xorl %eax, %eax
7089; X86-NOBMI-NEXT:  .LBB57_2:
7090; X86-NOBMI-NEXT:    movb $64, %cl
7091; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7092; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
7093; X86-NOBMI-NEXT:    shll %cl, %edi
7094; X86-NOBMI-NEXT:    testb $32, %cl
7095; X86-NOBMI-NEXT:    movl %edi, %ebx
7096; X86-NOBMI-NEXT:    jne .LBB57_4
7097; X86-NOBMI-NEXT:  # %bb.3:
7098; X86-NOBMI-NEXT:    movl %eax, %ebx
7099; X86-NOBMI-NEXT:  .LBB57_4:
7100; X86-NOBMI-NEXT:    movl %ebx, %eax
7101; X86-NOBMI-NEXT:    shrl %cl, %eax
7102; X86-NOBMI-NEXT:    testb $32, %cl
7103; X86-NOBMI-NEXT:    movl $0, %edx
7104; X86-NOBMI-NEXT:    jne .LBB57_6
7105; X86-NOBMI-NEXT:  # %bb.5:
7106; X86-NOBMI-NEXT:    movl %edi, %esi
7107; X86-NOBMI-NEXT:    movl %eax, %edx
7108; X86-NOBMI-NEXT:  .LBB57_6:
7109; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
7110; X86-NOBMI-NEXT:    testb $32, %cl
7111; X86-NOBMI-NEXT:    jne .LBB57_8
7112; X86-NOBMI-NEXT:  # %bb.7:
7113; X86-NOBMI-NEXT:    movl %esi, %eax
7114; X86-NOBMI-NEXT:  .LBB57_8:
7115; X86-NOBMI-NEXT:    popl %esi
7116; X86-NOBMI-NEXT:    popl %edi
7117; X86-NOBMI-NEXT:    popl %ebx
7118; X86-NOBMI-NEXT:    retl
7119;
7120; X86-BMI1-LABEL: bextr64_d1_indexzext:
7121; X86-BMI1:       # %bb.0:
7122; X86-BMI1-NEXT:    pushl %ebx
7123; X86-BMI1-NEXT:    pushl %edi
7124; X86-BMI1-NEXT:    pushl %esi
7125; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7126; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
7127; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
7128; X86-BMI1-NEXT:    movl %edx, %eax
7129; X86-BMI1-NEXT:    shrl %cl, %eax
7130; X86-BMI1-NEXT:    shrdl %cl, %edx, %edi
7131; X86-BMI1-NEXT:    xorl %esi, %esi
7132; X86-BMI1-NEXT:    testb $32, %cl
7133; X86-BMI1-NEXT:    je .LBB57_2
7134; X86-BMI1-NEXT:  # %bb.1:
7135; X86-BMI1-NEXT:    movl %eax, %edi
7136; X86-BMI1-NEXT:    xorl %eax, %eax
7137; X86-BMI1-NEXT:  .LBB57_2:
7138; X86-BMI1-NEXT:    movb $64, %cl
7139; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
7140; X86-BMI1-NEXT:    shldl %cl, %edi, %eax
7141; X86-BMI1-NEXT:    shll %cl, %edi
7142; X86-BMI1-NEXT:    testb $32, %cl
7143; X86-BMI1-NEXT:    movl %edi, %ebx
7144; X86-BMI1-NEXT:    jne .LBB57_4
7145; X86-BMI1-NEXT:  # %bb.3:
7146; X86-BMI1-NEXT:    movl %eax, %ebx
7147; X86-BMI1-NEXT:  .LBB57_4:
7148; X86-BMI1-NEXT:    movl %ebx, %eax
7149; X86-BMI1-NEXT:    shrl %cl, %eax
7150; X86-BMI1-NEXT:    testb $32, %cl
7151; X86-BMI1-NEXT:    movl $0, %edx
7152; X86-BMI1-NEXT:    jne .LBB57_6
7153; X86-BMI1-NEXT:  # %bb.5:
7154; X86-BMI1-NEXT:    movl %edi, %esi
7155; X86-BMI1-NEXT:    movl %eax, %edx
7156; X86-BMI1-NEXT:  .LBB57_6:
7157; X86-BMI1-NEXT:    shrdl %cl, %ebx, %esi
7158; X86-BMI1-NEXT:    testb $32, %cl
7159; X86-BMI1-NEXT:    jne .LBB57_8
7160; X86-BMI1-NEXT:  # %bb.7:
7161; X86-BMI1-NEXT:    movl %esi, %eax
7162; X86-BMI1-NEXT:  .LBB57_8:
7163; X86-BMI1-NEXT:    popl %esi
7164; X86-BMI1-NEXT:    popl %edi
7165; X86-BMI1-NEXT:    popl %ebx
7166; X86-BMI1-NEXT:    retl
7167;
7168; X86-BMI2-LABEL: bextr64_d1_indexzext:
7169; X86-BMI2:       # %bb.0:
7170; X86-BMI2-NEXT:    pushl %edi
7171; X86-BMI2-NEXT:    pushl %esi
7172; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7173; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7174; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7175; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7176; X86-BMI2-NEXT:    shrxl %ecx, %edx, %esi
7177; X86-BMI2-NEXT:    xorl %edx, %edx
7178; X86-BMI2-NEXT:    testb $32, %cl
7179; X86-BMI2-NEXT:    je .LBB57_2
7180; X86-BMI2-NEXT:  # %bb.1:
7181; X86-BMI2-NEXT:    movl %esi, %eax
7182; X86-BMI2-NEXT:    xorl %esi, %esi
7183; X86-BMI2-NEXT:  .LBB57_2:
7184; X86-BMI2-NEXT:    movb $64, %cl
7185; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7186; X86-BMI2-NEXT:    shldl %cl, %eax, %esi
7187; X86-BMI2-NEXT:    shlxl %ecx, %eax, %edi
7188; X86-BMI2-NEXT:    testb $32, %cl
7189; X86-BMI2-NEXT:    je .LBB57_4
7190; X86-BMI2-NEXT:  # %bb.3:
7191; X86-BMI2-NEXT:    movl %edi, %esi
7192; X86-BMI2-NEXT:    movl $0, %edi
7193; X86-BMI2-NEXT:  .LBB57_4:
7194; X86-BMI2-NEXT:    shrxl %ecx, %esi, %eax
7195; X86-BMI2-NEXT:    jne .LBB57_6
7196; X86-BMI2-NEXT:  # %bb.5:
7197; X86-BMI2-NEXT:    movl %eax, %edx
7198; X86-BMI2-NEXT:  .LBB57_6:
7199; X86-BMI2-NEXT:    shrdl %cl, %esi, %edi
7200; X86-BMI2-NEXT:    testb $32, %cl
7201; X86-BMI2-NEXT:    jne .LBB57_8
7202; X86-BMI2-NEXT:  # %bb.7:
7203; X86-BMI2-NEXT:    movl %edi, %eax
7204; X86-BMI2-NEXT:  .LBB57_8:
7205; X86-BMI2-NEXT:    popl %esi
7206; X86-BMI2-NEXT:    popl %edi
7207; X86-BMI2-NEXT:    retl
7208;
7209; X64-NOBMI-LABEL: bextr64_d1_indexzext:
7210; X64-NOBMI:       # %bb.0:
7211; X64-NOBMI-NEXT:    movl %esi, %ecx
7212; X64-NOBMI-NEXT:    movq %rdi, %rax
7213; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
7214; X64-NOBMI-NEXT:    shrq %cl, %rax
7215; X64-NOBMI-NEXT:    negb %dl
7216; X64-NOBMI-NEXT:    movl %edx, %ecx
7217; X64-NOBMI-NEXT:    shlq %cl, %rax
7218; X64-NOBMI-NEXT:    shrq %cl, %rax
7219; X64-NOBMI-NEXT:    retq
7220;
7221; X64-BMI1-LABEL: bextr64_d1_indexzext:
7222; X64-BMI1:       # %bb.0:
7223; X64-BMI1-NEXT:    shll $8, %edx
7224; X64-BMI1-NEXT:    movzbl %sil, %eax
7225; X64-BMI1-NEXT:    orl %edx, %eax
7226; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
7227; X64-BMI1-NEXT:    retq
7228;
7229; X64-BMI2-LABEL: bextr64_d1_indexzext:
7230; X64-BMI2:       # %bb.0:
7231; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
7232; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
7233; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7234; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7235; X64-BMI2-NEXT:    retq
7236  %skip = zext i8 %numskipbits to i64
7237  %shifted = lshr i64 %val, %skip
7238  %numhighbits = sub i8 64, %numlowbits
7239  %sh_prom = zext i8 %numhighbits to i64
7240  %highbitscleared = shl i64 %shifted, %sh_prom
7241  %masked = lshr i64 %highbitscleared, %sh_prom
7242  ret i64 %masked
7243}
7244
7245define i64 @bextr64_d2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {
7246; X86-NOBMI-LABEL: bextr64_d2_load:
7247; X86-NOBMI:       # %bb.0:
7248; X86-NOBMI-NEXT:    pushl %ebx
7249; X86-NOBMI-NEXT:    pushl %edi
7250; X86-NOBMI-NEXT:    pushl %esi
7251; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7252; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7253; X86-NOBMI-NEXT:    movl (%eax), %edi
7254; X86-NOBMI-NEXT:    movl 4(%eax), %edx
7255; X86-NOBMI-NEXT:    movl %edx, %eax
7256; X86-NOBMI-NEXT:    shrl %cl, %eax
7257; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
7258; X86-NOBMI-NEXT:    xorl %esi, %esi
7259; X86-NOBMI-NEXT:    testb $32, %cl
7260; X86-NOBMI-NEXT:    je .LBB58_2
7261; X86-NOBMI-NEXT:  # %bb.1:
7262; X86-NOBMI-NEXT:    movl %eax, %edi
7263; X86-NOBMI-NEXT:    xorl %eax, %eax
7264; X86-NOBMI-NEXT:  .LBB58_2:
7265; X86-NOBMI-NEXT:    movb $64, %cl
7266; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7267; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
7268; X86-NOBMI-NEXT:    shll %cl, %edi
7269; X86-NOBMI-NEXT:    testb $32, %cl
7270; X86-NOBMI-NEXT:    movl %edi, %ebx
7271; X86-NOBMI-NEXT:    jne .LBB58_4
7272; X86-NOBMI-NEXT:  # %bb.3:
7273; X86-NOBMI-NEXT:    movl %eax, %ebx
7274; X86-NOBMI-NEXT:  .LBB58_4:
7275; X86-NOBMI-NEXT:    movl %ebx, %eax
7276; X86-NOBMI-NEXT:    shrl %cl, %eax
7277; X86-NOBMI-NEXT:    testb $32, %cl
7278; X86-NOBMI-NEXT:    movl $0, %edx
7279; X86-NOBMI-NEXT:    jne .LBB58_6
7280; X86-NOBMI-NEXT:  # %bb.5:
7281; X86-NOBMI-NEXT:    movl %edi, %esi
7282; X86-NOBMI-NEXT:    movl %eax, %edx
7283; X86-NOBMI-NEXT:  .LBB58_6:
7284; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
7285; X86-NOBMI-NEXT:    testb $32, %cl
7286; X86-NOBMI-NEXT:    jne .LBB58_8
7287; X86-NOBMI-NEXT:  # %bb.7:
7288; X86-NOBMI-NEXT:    movl %esi, %eax
7289; X86-NOBMI-NEXT:  .LBB58_8:
7290; X86-NOBMI-NEXT:    popl %esi
7291; X86-NOBMI-NEXT:    popl %edi
7292; X86-NOBMI-NEXT:    popl %ebx
7293; X86-NOBMI-NEXT:    retl
7294;
7295; X86-BMI1-LABEL: bextr64_d2_load:
7296; X86-BMI1:       # %bb.0:
7297; X86-BMI1-NEXT:    pushl %ebx
7298; X86-BMI1-NEXT:    pushl %edi
7299; X86-BMI1-NEXT:    pushl %esi
7300; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7301; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
7302; X86-BMI1-NEXT:    movl (%eax), %edi
7303; X86-BMI1-NEXT:    movl 4(%eax), %edx
7304; X86-BMI1-NEXT:    movl %edx, %eax
7305; X86-BMI1-NEXT:    shrl %cl, %eax
7306; X86-BMI1-NEXT:    shrdl %cl, %edx, %edi
7307; X86-BMI1-NEXT:    xorl %esi, %esi
7308; X86-BMI1-NEXT:    testb $32, %cl
7309; X86-BMI1-NEXT:    je .LBB58_2
7310; X86-BMI1-NEXT:  # %bb.1:
7311; X86-BMI1-NEXT:    movl %eax, %edi
7312; X86-BMI1-NEXT:    xorl %eax, %eax
7313; X86-BMI1-NEXT:  .LBB58_2:
7314; X86-BMI1-NEXT:    movb $64, %cl
7315; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
7316; X86-BMI1-NEXT:    shldl %cl, %edi, %eax
7317; X86-BMI1-NEXT:    shll %cl, %edi
7318; X86-BMI1-NEXT:    testb $32, %cl
7319; X86-BMI1-NEXT:    movl %edi, %ebx
7320; X86-BMI1-NEXT:    jne .LBB58_4
7321; X86-BMI1-NEXT:  # %bb.3:
7322; X86-BMI1-NEXT:    movl %eax, %ebx
7323; X86-BMI1-NEXT:  .LBB58_4:
7324; X86-BMI1-NEXT:    movl %ebx, %eax
7325; X86-BMI1-NEXT:    shrl %cl, %eax
7326; X86-BMI1-NEXT:    testb $32, %cl
7327; X86-BMI1-NEXT:    movl $0, %edx
7328; X86-BMI1-NEXT:    jne .LBB58_6
7329; X86-BMI1-NEXT:  # %bb.5:
7330; X86-BMI1-NEXT:    movl %edi, %esi
7331; X86-BMI1-NEXT:    movl %eax, %edx
7332; X86-BMI1-NEXT:  .LBB58_6:
7333; X86-BMI1-NEXT:    shrdl %cl, %ebx, %esi
7334; X86-BMI1-NEXT:    testb $32, %cl
7335; X86-BMI1-NEXT:    jne .LBB58_8
7336; X86-BMI1-NEXT:  # %bb.7:
7337; X86-BMI1-NEXT:    movl %esi, %eax
7338; X86-BMI1-NEXT:  .LBB58_8:
7339; X86-BMI1-NEXT:    popl %esi
7340; X86-BMI1-NEXT:    popl %edi
7341; X86-BMI1-NEXT:    popl %ebx
7342; X86-BMI1-NEXT:    retl
7343;
7344; X86-BMI2-LABEL: bextr64_d2_load:
7345; X86-BMI2:       # %bb.0:
7346; X86-BMI2-NEXT:    pushl %edi
7347; X86-BMI2-NEXT:    pushl %esi
7348; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7349; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7350; X86-BMI2-NEXT:    movl (%edx), %eax
7351; X86-BMI2-NEXT:    movl 4(%edx), %edx
7352; X86-BMI2-NEXT:    shrxl %ecx, %edx, %esi
7353; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7354; X86-BMI2-NEXT:    xorl %edx, %edx
7355; X86-BMI2-NEXT:    testb $32, %cl
7356; X86-BMI2-NEXT:    je .LBB58_2
7357; X86-BMI2-NEXT:  # %bb.1:
7358; X86-BMI2-NEXT:    movl %esi, %eax
7359; X86-BMI2-NEXT:    xorl %esi, %esi
7360; X86-BMI2-NEXT:  .LBB58_2:
7361; X86-BMI2-NEXT:    movb $64, %cl
7362; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7363; X86-BMI2-NEXT:    shldl %cl, %eax, %esi
7364; X86-BMI2-NEXT:    shlxl %ecx, %eax, %edi
7365; X86-BMI2-NEXT:    testb $32, %cl
7366; X86-BMI2-NEXT:    je .LBB58_4
7367; X86-BMI2-NEXT:  # %bb.3:
7368; X86-BMI2-NEXT:    movl %edi, %esi
7369; X86-BMI2-NEXT:    movl $0, %edi
7370; X86-BMI2-NEXT:  .LBB58_4:
7371; X86-BMI2-NEXT:    shrxl %ecx, %esi, %eax
7372; X86-BMI2-NEXT:    jne .LBB58_6
7373; X86-BMI2-NEXT:  # %bb.5:
7374; X86-BMI2-NEXT:    movl %eax, %edx
7375; X86-BMI2-NEXT:  .LBB58_6:
7376; X86-BMI2-NEXT:    shrdl %cl, %esi, %edi
7377; X86-BMI2-NEXT:    testb $32, %cl
7378; X86-BMI2-NEXT:    jne .LBB58_8
7379; X86-BMI2-NEXT:  # %bb.7:
7380; X86-BMI2-NEXT:    movl %edi, %eax
7381; X86-BMI2-NEXT:  .LBB58_8:
7382; X86-BMI2-NEXT:    popl %esi
7383; X86-BMI2-NEXT:    popl %edi
7384; X86-BMI2-NEXT:    retl
7385;
7386; X64-NOBMI-LABEL: bextr64_d2_load:
7387; X64-NOBMI:       # %bb.0:
7388; X64-NOBMI-NEXT:    movq %rsi, %rcx
7389; X64-NOBMI-NEXT:    movq (%rdi), %rax
7390; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
7391; X64-NOBMI-NEXT:    shrq %cl, %rax
7392; X64-NOBMI-NEXT:    negb %dl
7393; X64-NOBMI-NEXT:    movl %edx, %ecx
7394; X64-NOBMI-NEXT:    shlq %cl, %rax
7395; X64-NOBMI-NEXT:    shrq %cl, %rax
7396; X64-NOBMI-NEXT:    retq
7397;
7398; X64-BMI1-LABEL: bextr64_d2_load:
7399; X64-BMI1:       # %bb.0:
7400; X64-BMI1-NEXT:    shll $8, %edx
7401; X64-BMI1-NEXT:    movzbl %sil, %eax
7402; X64-BMI1-NEXT:    orl %edx, %eax
7403; X64-BMI1-NEXT:    bextrq %rax, (%rdi), %rax
7404; X64-BMI1-NEXT:    retq
7405;
7406; X64-BMI2-LABEL: bextr64_d2_load:
7407; X64-BMI2:       # %bb.0:
7408; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
7409; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7410; X64-BMI2-NEXT:    retq
7411  %val = load i64, ptr %w
7412  %shifted = lshr i64 %val, %numskipbits
7413  %numhighbits = sub i64 64, %numlowbits
7414  %highbitscleared = shl i64 %shifted, %numhighbits
7415  %masked = lshr i64 %highbitscleared, %numhighbits
7416  ret i64 %masked
7417}
7418
7419define i64 @bextr64_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {
7420; X86-NOBMI-LABEL: bextr64_d3_load_indexzext:
7421; X86-NOBMI:       # %bb.0:
7422; X86-NOBMI-NEXT:    pushl %ebx
7423; X86-NOBMI-NEXT:    pushl %edi
7424; X86-NOBMI-NEXT:    pushl %esi
7425; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7426; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7427; X86-NOBMI-NEXT:    movl (%eax), %edi
7428; X86-NOBMI-NEXT:    movl 4(%eax), %edx
7429; X86-NOBMI-NEXT:    movl %edx, %eax
7430; X86-NOBMI-NEXT:    shrl %cl, %eax
7431; X86-NOBMI-NEXT:    shrdl %cl, %edx, %edi
7432; X86-NOBMI-NEXT:    xorl %esi, %esi
7433; X86-NOBMI-NEXT:    testb $32, %cl
7434; X86-NOBMI-NEXT:    je .LBB59_2
7435; X86-NOBMI-NEXT:  # %bb.1:
7436; X86-NOBMI-NEXT:    movl %eax, %edi
7437; X86-NOBMI-NEXT:    xorl %eax, %eax
7438; X86-NOBMI-NEXT:  .LBB59_2:
7439; X86-NOBMI-NEXT:    movb $64, %cl
7440; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7441; X86-NOBMI-NEXT:    shldl %cl, %edi, %eax
7442; X86-NOBMI-NEXT:    shll %cl, %edi
7443; X86-NOBMI-NEXT:    testb $32, %cl
7444; X86-NOBMI-NEXT:    movl %edi, %ebx
7445; X86-NOBMI-NEXT:    jne .LBB59_4
7446; X86-NOBMI-NEXT:  # %bb.3:
7447; X86-NOBMI-NEXT:    movl %eax, %ebx
7448; X86-NOBMI-NEXT:  .LBB59_4:
7449; X86-NOBMI-NEXT:    movl %ebx, %eax
7450; X86-NOBMI-NEXT:    shrl %cl, %eax
7451; X86-NOBMI-NEXT:    testb $32, %cl
7452; X86-NOBMI-NEXT:    movl $0, %edx
7453; X86-NOBMI-NEXT:    jne .LBB59_6
7454; X86-NOBMI-NEXT:  # %bb.5:
7455; X86-NOBMI-NEXT:    movl %edi, %esi
7456; X86-NOBMI-NEXT:    movl %eax, %edx
7457; X86-NOBMI-NEXT:  .LBB59_6:
7458; X86-NOBMI-NEXT:    shrdl %cl, %ebx, %esi
7459; X86-NOBMI-NEXT:    testb $32, %cl
7460; X86-NOBMI-NEXT:    jne .LBB59_8
7461; X86-NOBMI-NEXT:  # %bb.7:
7462; X86-NOBMI-NEXT:    movl %esi, %eax
7463; X86-NOBMI-NEXT:  .LBB59_8:
7464; X86-NOBMI-NEXT:    popl %esi
7465; X86-NOBMI-NEXT:    popl %edi
7466; X86-NOBMI-NEXT:    popl %ebx
7467; X86-NOBMI-NEXT:    retl
7468;
7469; X86-BMI1-LABEL: bextr64_d3_load_indexzext:
7470; X86-BMI1:       # %bb.0:
7471; X86-BMI1-NEXT:    pushl %ebx
7472; X86-BMI1-NEXT:    pushl %edi
7473; X86-BMI1-NEXT:    pushl %esi
7474; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7475; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
7476; X86-BMI1-NEXT:    movl (%eax), %edi
7477; X86-BMI1-NEXT:    movl 4(%eax), %edx
7478; X86-BMI1-NEXT:    movl %edx, %eax
7479; X86-BMI1-NEXT:    shrl %cl, %eax
7480; X86-BMI1-NEXT:    shrdl %cl, %edx, %edi
7481; X86-BMI1-NEXT:    xorl %esi, %esi
7482; X86-BMI1-NEXT:    testb $32, %cl
7483; X86-BMI1-NEXT:    je .LBB59_2
7484; X86-BMI1-NEXT:  # %bb.1:
7485; X86-BMI1-NEXT:    movl %eax, %edi
7486; X86-BMI1-NEXT:    xorl %eax, %eax
7487; X86-BMI1-NEXT:  .LBB59_2:
7488; X86-BMI1-NEXT:    movb $64, %cl
7489; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
7490; X86-BMI1-NEXT:    shldl %cl, %edi, %eax
7491; X86-BMI1-NEXT:    shll %cl, %edi
7492; X86-BMI1-NEXT:    testb $32, %cl
7493; X86-BMI1-NEXT:    movl %edi, %ebx
7494; X86-BMI1-NEXT:    jne .LBB59_4
7495; X86-BMI1-NEXT:  # %bb.3:
7496; X86-BMI1-NEXT:    movl %eax, %ebx
7497; X86-BMI1-NEXT:  .LBB59_4:
7498; X86-BMI1-NEXT:    movl %ebx, %eax
7499; X86-BMI1-NEXT:    shrl %cl, %eax
7500; X86-BMI1-NEXT:    testb $32, %cl
7501; X86-BMI1-NEXT:    movl $0, %edx
7502; X86-BMI1-NEXT:    jne .LBB59_6
7503; X86-BMI1-NEXT:  # %bb.5:
7504; X86-BMI1-NEXT:    movl %edi, %esi
7505; X86-BMI1-NEXT:    movl %eax, %edx
7506; X86-BMI1-NEXT:  .LBB59_6:
7507; X86-BMI1-NEXT:    shrdl %cl, %ebx, %esi
7508; X86-BMI1-NEXT:    testb $32, %cl
7509; X86-BMI1-NEXT:    jne .LBB59_8
7510; X86-BMI1-NEXT:  # %bb.7:
7511; X86-BMI1-NEXT:    movl %esi, %eax
7512; X86-BMI1-NEXT:  .LBB59_8:
7513; X86-BMI1-NEXT:    popl %esi
7514; X86-BMI1-NEXT:    popl %edi
7515; X86-BMI1-NEXT:    popl %ebx
7516; X86-BMI1-NEXT:    retl
7517;
7518; X86-BMI2-LABEL: bextr64_d3_load_indexzext:
7519; X86-BMI2:       # %bb.0:
7520; X86-BMI2-NEXT:    pushl %edi
7521; X86-BMI2-NEXT:    pushl %esi
7522; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7523; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7524; X86-BMI2-NEXT:    movl (%edx), %eax
7525; X86-BMI2-NEXT:    movl 4(%edx), %edx
7526; X86-BMI2-NEXT:    shrxl %ecx, %edx, %esi
7527; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7528; X86-BMI2-NEXT:    xorl %edx, %edx
7529; X86-BMI2-NEXT:    testb $32, %cl
7530; X86-BMI2-NEXT:    je .LBB59_2
7531; X86-BMI2-NEXT:  # %bb.1:
7532; X86-BMI2-NEXT:    movl %esi, %eax
7533; X86-BMI2-NEXT:    xorl %esi, %esi
7534; X86-BMI2-NEXT:  .LBB59_2:
7535; X86-BMI2-NEXT:    movb $64, %cl
7536; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7537; X86-BMI2-NEXT:    shldl %cl, %eax, %esi
7538; X86-BMI2-NEXT:    shlxl %ecx, %eax, %edi
7539; X86-BMI2-NEXT:    testb $32, %cl
7540; X86-BMI2-NEXT:    je .LBB59_4
7541; X86-BMI2-NEXT:  # %bb.3:
7542; X86-BMI2-NEXT:    movl %edi, %esi
7543; X86-BMI2-NEXT:    movl $0, %edi
7544; X86-BMI2-NEXT:  .LBB59_4:
7545; X86-BMI2-NEXT:    shrxl %ecx, %esi, %eax
7546; X86-BMI2-NEXT:    jne .LBB59_6
7547; X86-BMI2-NEXT:  # %bb.5:
7548; X86-BMI2-NEXT:    movl %eax, %edx
7549; X86-BMI2-NEXT:  .LBB59_6:
7550; X86-BMI2-NEXT:    shrdl %cl, %esi, %edi
7551; X86-BMI2-NEXT:    testb $32, %cl
7552; X86-BMI2-NEXT:    jne .LBB59_8
7553; X86-BMI2-NEXT:  # %bb.7:
7554; X86-BMI2-NEXT:    movl %edi, %eax
7555; X86-BMI2-NEXT:  .LBB59_8:
7556; X86-BMI2-NEXT:    popl %esi
7557; X86-BMI2-NEXT:    popl %edi
7558; X86-BMI2-NEXT:    retl
7559;
7560; X64-NOBMI-LABEL: bextr64_d3_load_indexzext:
7561; X64-NOBMI:       # %bb.0:
7562; X64-NOBMI-NEXT:    movl %esi, %ecx
7563; X64-NOBMI-NEXT:    movq (%rdi), %rax
7564; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
7565; X64-NOBMI-NEXT:    shrq %cl, %rax
7566; X64-NOBMI-NEXT:    negb %dl
7567; X64-NOBMI-NEXT:    movl %edx, %ecx
7568; X64-NOBMI-NEXT:    shlq %cl, %rax
7569; X64-NOBMI-NEXT:    shrq %cl, %rax
7570; X64-NOBMI-NEXT:    retq
7571;
7572; X64-BMI1-LABEL: bextr64_d3_load_indexzext:
7573; X64-BMI1:       # %bb.0:
7574; X64-BMI1-NEXT:    shll $8, %edx
7575; X64-BMI1-NEXT:    movzbl %sil, %eax
7576; X64-BMI1-NEXT:    orl %edx, %eax
7577; X64-BMI1-NEXT:    bextrq %rax, (%rdi), %rax
7578; X64-BMI1-NEXT:    retq
7579;
7580; X64-BMI2-LABEL: bextr64_d3_load_indexzext:
7581; X64-BMI2:       # %bb.0:
7582; X64-BMI2-NEXT:    # kill: def $edx killed $edx def $rdx
7583; X64-BMI2-NEXT:    # kill: def $esi killed $esi def $rsi
7584; X64-BMI2-NEXT:    shrxq %rsi, (%rdi), %rax
7585; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7586; X64-BMI2-NEXT:    retq
7587  %val = load i64, ptr %w
7588  %skip = zext i8 %numskipbits to i64
7589  %shifted = lshr i64 %val, %skip
7590  %numhighbits = sub i8 64, %numlowbits
7591  %sh_prom = zext i8 %numhighbits to i64
7592  %highbitscleared = shl i64 %shifted, %sh_prom
7593  %masked = lshr i64 %highbitscleared, %sh_prom
7594  ret i64 %masked
7595}
7596
7597define i64 @bextr64_d5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
7598; X86-NOBMI-LABEL: bextr64_d5_skipextrauses:
7599; X86-NOBMI:       # %bb.0:
7600; X86-NOBMI-NEXT:    pushl %ebp
7601; X86-NOBMI-NEXT:    pushl %ebx
7602; X86-NOBMI-NEXT:    pushl %edi
7603; X86-NOBMI-NEXT:    pushl %esi
7604; X86-NOBMI-NEXT:    subl $12, %esp
7605; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
7606; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7607; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
7608; X86-NOBMI-NEXT:    movl %edx, %esi
7609; X86-NOBMI-NEXT:    movl %eax, %ecx
7610; X86-NOBMI-NEXT:    shrl %cl, %esi
7611; X86-NOBMI-NEXT:    shrdl %cl, %edx, %ebx
7612; X86-NOBMI-NEXT:    xorl %edx, %edx
7613; X86-NOBMI-NEXT:    testb $32, %al
7614; X86-NOBMI-NEXT:    je .LBB60_2
7615; X86-NOBMI-NEXT:  # %bb.1:
7616; X86-NOBMI-NEXT:    movl %esi, %ebx
7617; X86-NOBMI-NEXT:    xorl %esi, %esi
7618; X86-NOBMI-NEXT:  .LBB60_2:
7619; X86-NOBMI-NEXT:    movb $64, %cl
7620; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7621; X86-NOBMI-NEXT:    shldl %cl, %ebx, %esi
7622; X86-NOBMI-NEXT:    shll %cl, %ebx
7623; X86-NOBMI-NEXT:    testb $32, %cl
7624; X86-NOBMI-NEXT:    movl %ebx, %ebp
7625; X86-NOBMI-NEXT:    jne .LBB60_4
7626; X86-NOBMI-NEXT:  # %bb.3:
7627; X86-NOBMI-NEXT:    movl %esi, %ebp
7628; X86-NOBMI-NEXT:  .LBB60_4:
7629; X86-NOBMI-NEXT:    movl %ebp, %esi
7630; X86-NOBMI-NEXT:    shrl %cl, %esi
7631; X86-NOBMI-NEXT:    testb $32, %cl
7632; X86-NOBMI-NEXT:    movl $0, %edi
7633; X86-NOBMI-NEXT:    jne .LBB60_6
7634; X86-NOBMI-NEXT:  # %bb.5:
7635; X86-NOBMI-NEXT:    movl %ebx, %edx
7636; X86-NOBMI-NEXT:    movl %esi, %edi
7637; X86-NOBMI-NEXT:  .LBB60_6:
7638; X86-NOBMI-NEXT:    shrdl %cl, %ebp, %edx
7639; X86-NOBMI-NEXT:    testb $32, %cl
7640; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7641; X86-NOBMI-NEXT:    jne .LBB60_8
7642; X86-NOBMI-NEXT:  # %bb.7:
7643; X86-NOBMI-NEXT:    movl %edx, %esi
7644; X86-NOBMI-NEXT:  .LBB60_8:
7645; X86-NOBMI-NEXT:    subl $8, %esp
7646; X86-NOBMI-NEXT:    pushl %ecx
7647; X86-NOBMI-NEXT:    pushl %eax
7648; X86-NOBMI-NEXT:    calll use64@PLT
7649; X86-NOBMI-NEXT:    addl $16, %esp
7650; X86-NOBMI-NEXT:    movl %esi, %eax
7651; X86-NOBMI-NEXT:    movl %edi, %edx
7652; X86-NOBMI-NEXT:    addl $12, %esp
7653; X86-NOBMI-NEXT:    popl %esi
7654; X86-NOBMI-NEXT:    popl %edi
7655; X86-NOBMI-NEXT:    popl %ebx
7656; X86-NOBMI-NEXT:    popl %ebp
7657; X86-NOBMI-NEXT:    retl
7658;
7659; X86-BMI1-LABEL: bextr64_d5_skipextrauses:
7660; X86-BMI1:       # %bb.0:
7661; X86-BMI1-NEXT:    pushl %ebp
7662; X86-BMI1-NEXT:    pushl %ebx
7663; X86-BMI1-NEXT:    pushl %edi
7664; X86-BMI1-NEXT:    pushl %esi
7665; X86-BMI1-NEXT:    subl $12, %esp
7666; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ebx
7667; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
7668; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
7669; X86-BMI1-NEXT:    movl %edx, %esi
7670; X86-BMI1-NEXT:    movl %eax, %ecx
7671; X86-BMI1-NEXT:    shrl %cl, %esi
7672; X86-BMI1-NEXT:    shrdl %cl, %edx, %ebx
7673; X86-BMI1-NEXT:    xorl %edx, %edx
7674; X86-BMI1-NEXT:    testb $32, %al
7675; X86-BMI1-NEXT:    je .LBB60_2
7676; X86-BMI1-NEXT:  # %bb.1:
7677; X86-BMI1-NEXT:    movl %esi, %ebx
7678; X86-BMI1-NEXT:    xorl %esi, %esi
7679; X86-BMI1-NEXT:  .LBB60_2:
7680; X86-BMI1-NEXT:    movb $64, %cl
7681; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
7682; X86-BMI1-NEXT:    shldl %cl, %ebx, %esi
7683; X86-BMI1-NEXT:    shll %cl, %ebx
7684; X86-BMI1-NEXT:    testb $32, %cl
7685; X86-BMI1-NEXT:    movl %ebx, %ebp
7686; X86-BMI1-NEXT:    jne .LBB60_4
7687; X86-BMI1-NEXT:  # %bb.3:
7688; X86-BMI1-NEXT:    movl %esi, %ebp
7689; X86-BMI1-NEXT:  .LBB60_4:
7690; X86-BMI1-NEXT:    movl %ebp, %esi
7691; X86-BMI1-NEXT:    shrl %cl, %esi
7692; X86-BMI1-NEXT:    testb $32, %cl
7693; X86-BMI1-NEXT:    movl $0, %edi
7694; X86-BMI1-NEXT:    jne .LBB60_6
7695; X86-BMI1-NEXT:  # %bb.5:
7696; X86-BMI1-NEXT:    movl %ebx, %edx
7697; X86-BMI1-NEXT:    movl %esi, %edi
7698; X86-BMI1-NEXT:  .LBB60_6:
7699; X86-BMI1-NEXT:    shrdl %cl, %ebp, %edx
7700; X86-BMI1-NEXT:    testb $32, %cl
7701; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7702; X86-BMI1-NEXT:    jne .LBB60_8
7703; X86-BMI1-NEXT:  # %bb.7:
7704; X86-BMI1-NEXT:    movl %edx, %esi
7705; X86-BMI1-NEXT:  .LBB60_8:
7706; X86-BMI1-NEXT:    subl $8, %esp
7707; X86-BMI1-NEXT:    pushl %ecx
7708; X86-BMI1-NEXT:    pushl %eax
7709; X86-BMI1-NEXT:    calll use64@PLT
7710; X86-BMI1-NEXT:    addl $16, %esp
7711; X86-BMI1-NEXT:    movl %esi, %eax
7712; X86-BMI1-NEXT:    movl %edi, %edx
7713; X86-BMI1-NEXT:    addl $12, %esp
7714; X86-BMI1-NEXT:    popl %esi
7715; X86-BMI1-NEXT:    popl %edi
7716; X86-BMI1-NEXT:    popl %ebx
7717; X86-BMI1-NEXT:    popl %ebp
7718; X86-BMI1-NEXT:    retl
7719;
7720; X86-BMI2-LABEL: bextr64_d5_skipextrauses:
7721; X86-BMI2:       # %bb.0:
7722; X86-BMI2-NEXT:    pushl %ebx
7723; X86-BMI2-NEXT:    pushl %edi
7724; X86-BMI2-NEXT:    pushl %esi
7725; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edi
7726; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7727; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7728; X86-BMI2-NEXT:    movl %eax, %ecx
7729; X86-BMI2-NEXT:    shrdl %cl, %edx, %edi
7730; X86-BMI2-NEXT:    shrxl %eax, %edx, %edx
7731; X86-BMI2-NEXT:    xorl %esi, %esi
7732; X86-BMI2-NEXT:    testb $32, %al
7733; X86-BMI2-NEXT:    je .LBB60_2
7734; X86-BMI2-NEXT:  # %bb.1:
7735; X86-BMI2-NEXT:    movl %edx, %edi
7736; X86-BMI2-NEXT:    xorl %edx, %edx
7737; X86-BMI2-NEXT:  .LBB60_2:
7738; X86-BMI2-NEXT:    movb $64, %cl
7739; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7740; X86-BMI2-NEXT:    shldl %cl, %edi, %edx
7741; X86-BMI2-NEXT:    shlxl %ecx, %edi, %ebx
7742; X86-BMI2-NEXT:    testb $32, %cl
7743; X86-BMI2-NEXT:    je .LBB60_4
7744; X86-BMI2-NEXT:  # %bb.3:
7745; X86-BMI2-NEXT:    movl %ebx, %edx
7746; X86-BMI2-NEXT:    movl $0, %ebx
7747; X86-BMI2-NEXT:  .LBB60_4:
7748; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edi
7749; X86-BMI2-NEXT:    jne .LBB60_6
7750; X86-BMI2-NEXT:  # %bb.5:
7751; X86-BMI2-NEXT:    movl %edi, %esi
7752; X86-BMI2-NEXT:  .LBB60_6:
7753; X86-BMI2-NEXT:    shrdl %cl, %edx, %ebx
7754; X86-BMI2-NEXT:    testb $32, %cl
7755; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
7756; X86-BMI2-NEXT:    jne .LBB60_8
7757; X86-BMI2-NEXT:  # %bb.7:
7758; X86-BMI2-NEXT:    movl %ebx, %edi
7759; X86-BMI2-NEXT:  .LBB60_8:
7760; X86-BMI2-NEXT:    subl $8, %esp
7761; X86-BMI2-NEXT:    pushl %ecx
7762; X86-BMI2-NEXT:    pushl %eax
7763; X86-BMI2-NEXT:    calll use64@PLT
7764; X86-BMI2-NEXT:    addl $16, %esp
7765; X86-BMI2-NEXT:    movl %edi, %eax
7766; X86-BMI2-NEXT:    movl %esi, %edx
7767; X86-BMI2-NEXT:    popl %esi
7768; X86-BMI2-NEXT:    popl %edi
7769; X86-BMI2-NEXT:    popl %ebx
7770; X86-BMI2-NEXT:    retl
7771;
7772; X64-NOBMI-LABEL: bextr64_d5_skipextrauses:
7773; X64-NOBMI:       # %bb.0:
7774; X64-NOBMI-NEXT:    pushq %rbx
7775; X64-NOBMI-NEXT:    movq %rdi, %rbx
7776; X64-NOBMI-NEXT:    movl %esi, %ecx
7777; X64-NOBMI-NEXT:    shrq %cl, %rbx
7778; X64-NOBMI-NEXT:    negb %dl
7779; X64-NOBMI-NEXT:    movl %edx, %ecx
7780; X64-NOBMI-NEXT:    shlq %cl, %rbx
7781; X64-NOBMI-NEXT:    shrq %cl, %rbx
7782; X64-NOBMI-NEXT:    movq %rsi, %rdi
7783; X64-NOBMI-NEXT:    callq use64@PLT
7784; X64-NOBMI-NEXT:    movq %rbx, %rax
7785; X64-NOBMI-NEXT:    popq %rbx
7786; X64-NOBMI-NEXT:    retq
7787;
7788; X64-BMI1-LABEL: bextr64_d5_skipextrauses:
7789; X64-BMI1:       # %bb.0:
7790; X64-BMI1-NEXT:    pushq %rbx
7791; X64-BMI1-NEXT:    shll $8, %edx
7792; X64-BMI1-NEXT:    movzbl %sil, %eax
7793; X64-BMI1-NEXT:    orl %edx, %eax
7794; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rbx
7795; X64-BMI1-NEXT:    movq %rsi, %rdi
7796; X64-BMI1-NEXT:    callq use64@PLT
7797; X64-BMI1-NEXT:    movq %rbx, %rax
7798; X64-BMI1-NEXT:    popq %rbx
7799; X64-BMI1-NEXT:    retq
7800;
7801; X64-BMI2-LABEL: bextr64_d5_skipextrauses:
7802; X64-BMI2:       # %bb.0:
7803; X64-BMI2-NEXT:    pushq %rbx
7804; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7805; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rbx
7806; X64-BMI2-NEXT:    movq %rsi, %rdi
7807; X64-BMI2-NEXT:    callq use64@PLT
7808; X64-BMI2-NEXT:    movq %rbx, %rax
7809; X64-BMI2-NEXT:    popq %rbx
7810; X64-BMI2-NEXT:    retq
7811  %shifted = lshr i64 %val, %numskipbits
7812  %numhighbits = sub i64 64, %numlowbits
7813  %highbitscleared = shl i64 %shifted, %numhighbits
7814  %masked = lshr i64 %highbitscleared, %numhighbits
7815  call void @use64(i64 %numskipbits)
7816  ret i64 %masked
7817}
7818
7819; 64-bit, but with 32-bit output
7820
7821; Everything done in 64-bit, truncation happens last.
7822define i32 @bextr64_32_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
7823; X86-NOBMI-LABEL: bextr64_32_d0:
7824; X86-NOBMI:       # %bb.0:
7825; X86-NOBMI-NEXT:    pushl %esi
7826; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7827; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7828; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
7829; X86-NOBMI-NEXT:    movl %esi, %eax
7830; X86-NOBMI-NEXT:    shrl %cl, %eax
7831; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
7832; X86-NOBMI-NEXT:    testb $32, %cl
7833; X86-NOBMI-NEXT:    je .LBB61_2
7834; X86-NOBMI-NEXT:  # %bb.1:
7835; X86-NOBMI-NEXT:    movl %eax, %edx
7836; X86-NOBMI-NEXT:    xorl %eax, %eax
7837; X86-NOBMI-NEXT:  .LBB61_2:
7838; X86-NOBMI-NEXT:    movb $64, %cl
7839; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7840; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
7841; X86-NOBMI-NEXT:    shll %cl, %edx
7842; X86-NOBMI-NEXT:    testb $32, %cl
7843; X86-NOBMI-NEXT:    je .LBB61_4
7844; X86-NOBMI-NEXT:  # %bb.3:
7845; X86-NOBMI-NEXT:    movl %edx, %eax
7846; X86-NOBMI-NEXT:    xorl %edx, %edx
7847; X86-NOBMI-NEXT:  .LBB61_4:
7848; X86-NOBMI-NEXT:    shrdl %cl, %eax, %edx
7849; X86-NOBMI-NEXT:    shrl %cl, %eax
7850; X86-NOBMI-NEXT:    testb $32, %cl
7851; X86-NOBMI-NEXT:    jne .LBB61_6
7852; X86-NOBMI-NEXT:  # %bb.5:
7853; X86-NOBMI-NEXT:    movl %edx, %eax
7854; X86-NOBMI-NEXT:  .LBB61_6:
7855; X86-NOBMI-NEXT:    popl %esi
7856; X86-NOBMI-NEXT:    retl
7857;
7858; X86-BMI1-LABEL: bextr64_32_d0:
7859; X86-BMI1:       # %bb.0:
7860; X86-BMI1-NEXT:    pushl %esi
7861; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7862; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
7863; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
7864; X86-BMI1-NEXT:    movl %esi, %eax
7865; X86-BMI1-NEXT:    shrl %cl, %eax
7866; X86-BMI1-NEXT:    shrdl %cl, %esi, %edx
7867; X86-BMI1-NEXT:    testb $32, %cl
7868; X86-BMI1-NEXT:    je .LBB61_2
7869; X86-BMI1-NEXT:  # %bb.1:
7870; X86-BMI1-NEXT:    movl %eax, %edx
7871; X86-BMI1-NEXT:    xorl %eax, %eax
7872; X86-BMI1-NEXT:  .LBB61_2:
7873; X86-BMI1-NEXT:    movb $64, %cl
7874; X86-BMI1-NEXT:    subb {{[0-9]+}}(%esp), %cl
7875; X86-BMI1-NEXT:    shldl %cl, %edx, %eax
7876; X86-BMI1-NEXT:    shll %cl, %edx
7877; X86-BMI1-NEXT:    testb $32, %cl
7878; X86-BMI1-NEXT:    je .LBB61_4
7879; X86-BMI1-NEXT:  # %bb.3:
7880; X86-BMI1-NEXT:    movl %edx, %eax
7881; X86-BMI1-NEXT:    xorl %edx, %edx
7882; X86-BMI1-NEXT:  .LBB61_4:
7883; X86-BMI1-NEXT:    shrdl %cl, %eax, %edx
7884; X86-BMI1-NEXT:    shrl %cl, %eax
7885; X86-BMI1-NEXT:    testb $32, %cl
7886; X86-BMI1-NEXT:    jne .LBB61_6
7887; X86-BMI1-NEXT:  # %bb.5:
7888; X86-BMI1-NEXT:    movl %edx, %eax
7889; X86-BMI1-NEXT:  .LBB61_6:
7890; X86-BMI1-NEXT:    popl %esi
7891; X86-BMI1-NEXT:    retl
7892;
7893; X86-BMI2-LABEL: bextr64_32_d0:
7894; X86-BMI2:       # %bb.0:
7895; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7896; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
7897; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
7898; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7899; X86-BMI2-NEXT:    shrxl %ecx, %edx, %edx
7900; X86-BMI2-NEXT:    testb $32, %cl
7901; X86-BMI2-NEXT:    je .LBB61_2
7902; X86-BMI2-NEXT:  # %bb.1:
7903; X86-BMI2-NEXT:    movl %edx, %eax
7904; X86-BMI2-NEXT:    xorl %edx, %edx
7905; X86-BMI2-NEXT:  .LBB61_2:
7906; X86-BMI2-NEXT:    movb $64, %cl
7907; X86-BMI2-NEXT:    subb {{[0-9]+}}(%esp), %cl
7908; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
7909; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
7910; X86-BMI2-NEXT:    testb $32, %cl
7911; X86-BMI2-NEXT:    je .LBB61_4
7912; X86-BMI2-NEXT:  # %bb.3:
7913; X86-BMI2-NEXT:    movl %eax, %edx
7914; X86-BMI2-NEXT:    xorl %eax, %eax
7915; X86-BMI2-NEXT:  .LBB61_4:
7916; X86-BMI2-NEXT:    shrdl %cl, %edx, %eax
7917; X86-BMI2-NEXT:    testb $32, %cl
7918; X86-BMI2-NEXT:    je .LBB61_6
7919; X86-BMI2-NEXT:  # %bb.5:
7920; X86-BMI2-NEXT:    shrxl %ecx, %edx, %eax
7921; X86-BMI2-NEXT:  .LBB61_6:
7922; X86-BMI2-NEXT:    retl
7923;
7924; X64-NOBMI-LABEL: bextr64_32_d0:
7925; X64-NOBMI:       # %bb.0:
7926; X64-NOBMI-NEXT:    movq %rsi, %rcx
7927; X64-NOBMI-NEXT:    movq %rdi, %rax
7928; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
7929; X64-NOBMI-NEXT:    shrq %cl, %rax
7930; X64-NOBMI-NEXT:    negb %dl
7931; X64-NOBMI-NEXT:    movl %edx, %ecx
7932; X64-NOBMI-NEXT:    shlq %cl, %rax
7933; X64-NOBMI-NEXT:    shrq %cl, %rax
7934; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
7935; X64-NOBMI-NEXT:    retq
7936;
7937; X64-BMI1-LABEL: bextr64_32_d0:
7938; X64-BMI1:       # %bb.0:
7939; X64-BMI1-NEXT:    shll $8, %edx
7940; X64-BMI1-NEXT:    movzbl %sil, %eax
7941; X64-BMI1-NEXT:    orl %edx, %eax
7942; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
7943; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
7944; X64-BMI1-NEXT:    retq
7945;
7946; X64-BMI2-LABEL: bextr64_32_d0:
7947; X64-BMI2:       # %bb.0:
7948; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
7949; X64-BMI2-NEXT:    bzhiq %rdx, %rax, %rax
7950; X64-BMI2-NEXT:    # kill: def $eax killed $eax killed $rax
7951; X64-BMI2-NEXT:    retq
7952  %shifted = lshr i64 %val, %numskipbits
7953  %numhighbits = sub i64 64, %numlowbits
7954  %highbitscleared = shl i64 %shifted, %numhighbits
7955  %masked = lshr i64 %highbitscleared, %numhighbits
7956  %res = trunc i64 %masked to i32
7957  ret i32 %res
7958}
7959
7960; Shifting happens in 64-bit, then truncation. Masking is 32-bit.
7961define i32 @bextr64_32_d1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {
7962; X86-NOBMI-LABEL: bextr64_32_d1:
7963; X86-NOBMI:       # %bb.0:
7964; X86-NOBMI-NEXT:    pushl %esi
7965; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7966; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
7967; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
7968; X86-NOBMI-NEXT:    movl %esi, %eax
7969; X86-NOBMI-NEXT:    shrl %cl, %eax
7970; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
7971; X86-NOBMI-NEXT:    testb $32, %cl
7972; X86-NOBMI-NEXT:    jne .LBB62_2
7973; X86-NOBMI-NEXT:  # %bb.1:
7974; X86-NOBMI-NEXT:    movl %edx, %eax
7975; X86-NOBMI-NEXT:  .LBB62_2:
7976; X86-NOBMI-NEXT:    xorl %ecx, %ecx
7977; X86-NOBMI-NEXT:    subb {{[0-9]+}}(%esp), %cl
7978; X86-NOBMI-NEXT:    shll %cl, %eax
7979; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
7980; X86-NOBMI-NEXT:    shrl %cl, %eax
7981; X86-NOBMI-NEXT:    popl %esi
7982; X86-NOBMI-NEXT:    retl
7983;
7984; X86-BMI1-LABEL: bextr64_32_d1:
7985; X86-BMI1:       # %bb.0:
7986; X86-BMI1-NEXT:    pushl %edi
7987; X86-BMI1-NEXT:    pushl %esi
7988; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
7989; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
7990; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %esi
7991; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edi
7992; X86-BMI1-NEXT:    movl %edi, %edx
7993; X86-BMI1-NEXT:    shrl %cl, %edx
7994; X86-BMI1-NEXT:    shrdl %cl, %edi, %esi
7995; X86-BMI1-NEXT:    testb $32, %cl
7996; X86-BMI1-NEXT:    jne .LBB62_2
7997; X86-BMI1-NEXT:  # %bb.1:
7998; X86-BMI1-NEXT:    movl %esi, %edx
7999; X86-BMI1-NEXT:  .LBB62_2:
8000; X86-BMI1-NEXT:    shll $8, %eax
8001; X86-BMI1-NEXT:    bextrl %eax, %edx, %eax
8002; X86-BMI1-NEXT:    popl %esi
8003; X86-BMI1-NEXT:    popl %edi
8004; X86-BMI1-NEXT:    retl
8005;
8006; X86-BMI2-LABEL: bextr64_32_d1:
8007; X86-BMI2:       # %bb.0:
8008; X86-BMI2-NEXT:    pushl %esi
8009; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
8010; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
8011; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
8012; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %esi
8013; X86-BMI2-NEXT:    shrdl %cl, %esi, %edx
8014; X86-BMI2-NEXT:    testb $32, %cl
8015; X86-BMI2-NEXT:    je .LBB62_2
8016; X86-BMI2-NEXT:  # %bb.1:
8017; X86-BMI2-NEXT:    shrxl %ecx, %esi, %edx
8018; X86-BMI2-NEXT:  .LBB62_2:
8019; X86-BMI2-NEXT:    bzhil %eax, %edx, %eax
8020; X86-BMI2-NEXT:    popl %esi
8021; X86-BMI2-NEXT:    retl
8022;
8023; X64-NOBMI-LABEL: bextr64_32_d1:
8024; X64-NOBMI:       # %bb.0:
8025; X64-NOBMI-NEXT:    movq %rsi, %rcx
8026; X64-NOBMI-NEXT:    movq %rdi, %rax
8027; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
8028; X64-NOBMI-NEXT:    shrq %cl, %rax
8029; X64-NOBMI-NEXT:    negb %dl
8030; X64-NOBMI-NEXT:    movl %edx, %ecx
8031; X64-NOBMI-NEXT:    shll %cl, %eax
8032; X64-NOBMI-NEXT:    shrl %cl, %eax
8033; X64-NOBMI-NEXT:    # kill: def $eax killed $eax killed $rax
8034; X64-NOBMI-NEXT:    retq
8035;
8036; X64-BMI1-LABEL: bextr64_32_d1:
8037; X64-BMI1:       # %bb.0:
8038; X64-BMI1-NEXT:    shll $8, %edx
8039; X64-BMI1-NEXT:    movzbl %sil, %eax
8040; X64-BMI1-NEXT:    orl %edx, %eax
8041; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
8042; X64-BMI1-NEXT:    # kill: def $eax killed $eax killed $rax
8043; X64-BMI1-NEXT:    retq
8044;
8045; X64-BMI2-LABEL: bextr64_32_d1:
8046; X64-BMI2:       # %bb.0:
8047; X64-BMI2-NEXT:    shrxq %rsi, %rdi, %rax
8048; X64-BMI2-NEXT:    bzhil %edx, %eax, %eax
8049; X64-BMI2-NEXT:    retq
8050  %shifted = lshr i64 %val, %numskipbits
8051  %truncshifted = trunc i64 %shifted to i32
8052  %numhighbits = sub i32 32, %numlowbits
8053  %highbitscleared = shl i32 %truncshifted, %numhighbits
8054  %masked = lshr i32 %highbitscleared, %numhighbits
8055  ret i32 %masked
8056}
8057
8058; ---------------------------------------------------------------------------- ;
8059; Constant
8060; ---------------------------------------------------------------------------- ;
8061
8062; https://bugs.llvm.org/show_bug.cgi?id=38938
8063define void @pr38938(ptr %a0, ptr %a1) nounwind {
8064; X86-NOBMI-LABEL: pr38938:
8065; X86-NOBMI:       # %bb.0:
8066; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8067; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8068; X86-NOBMI-NEXT:    movl (%ecx), %ecx
8069; X86-NOBMI-NEXT:    shrl $19, %ecx
8070; X86-NOBMI-NEXT:    andl $4092, %ecx # imm = 0xFFC
8071; X86-NOBMI-NEXT:    incl (%eax,%ecx)
8072; X86-NOBMI-NEXT:    retl
8073;
8074; X86-BMINOTBM-LABEL: pr38938:
8075; X86-BMINOTBM:       # %bb.0:
8076; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8077; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8078; X86-BMINOTBM-NEXT:    movl $2581, %edx # imm = 0xA15
8079; X86-BMINOTBM-NEXT:    bextrl %edx, (%ecx), %ecx
8080; X86-BMINOTBM-NEXT:    incl (%eax,%ecx,4)
8081; X86-BMINOTBM-NEXT:    retl
8082;
8083; X86-BMITBM-LABEL: pr38938:
8084; X86-BMITBM:       # %bb.0:
8085; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8086; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8087; X86-BMITBM-NEXT:    bextrl $2581, (%ecx), %ecx # imm = 0xA15
8088; X86-BMITBM-NEXT:    incl (%eax,%ecx,4)
8089; X86-BMITBM-NEXT:    retl
8090;
8091; X64-NOBMI-LABEL: pr38938:
8092; X64-NOBMI:       # %bb.0:
8093; X64-NOBMI-NEXT:    movl (%rsi), %eax
8094; X64-NOBMI-NEXT:    shrl $19, %eax
8095; X64-NOBMI-NEXT:    andl $4092, %eax # imm = 0xFFC
8096; X64-NOBMI-NEXT:    incl (%rdi,%rax)
8097; X64-NOBMI-NEXT:    retq
8098;
8099; X64-BMINOTBM-LABEL: pr38938:
8100; X64-BMINOTBM:       # %bb.0:
8101; X64-BMINOTBM-NEXT:    movl $2581, %eax # imm = 0xA15
8102; X64-BMINOTBM-NEXT:    bextrl %eax, (%rsi), %eax
8103; X64-BMINOTBM-NEXT:    incl (%rdi,%rax,4)
8104; X64-BMINOTBM-NEXT:    retq
8105;
8106; X64-BMITBM-LABEL: pr38938:
8107; X64-BMITBM:       # %bb.0:
8108; X64-BMITBM-NEXT:    bextrl $2581, (%rsi), %eax # imm = 0xA15
8109; X64-BMITBM-NEXT:    incl (%rdi,%rax,4)
8110; X64-BMITBM-NEXT:    retq
8111  %tmp = load i64, ptr %a1, align 8
8112  %tmp1 = lshr i64 %tmp, 21
8113  %tmp2 = and i64 %tmp1, 1023
8114  %tmp3 = getelementptr inbounds i32, ptr %a0, i64 %tmp2
8115  %tmp4 = load i32, ptr %tmp3, align 4
8116  %tmp5 = add nsw i32 %tmp4, 1
8117  store i32 %tmp5, ptr %tmp3, align 4
8118  ret void
8119}
8120
8121; The most canonical variant
8122define i32 @c0_i32(i32 %arg) nounwind {
8123; X86-NOBMI-LABEL: c0_i32:
8124; X86-NOBMI:       # %bb.0:
8125; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8126; X86-NOBMI-NEXT:    shrl $19, %eax
8127; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
8128; X86-NOBMI-NEXT:    retl
8129;
8130; X86-BMINOTBM-LABEL: c0_i32:
8131; X86-BMINOTBM:       # %bb.0:
8132; X86-BMINOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
8133; X86-BMINOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
8134; X86-BMINOTBM-NEXT:    retl
8135;
8136; X86-BMITBM-LABEL: c0_i32:
8137; X86-BMITBM:       # %bb.0:
8138; X86-BMITBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
8139; X86-BMITBM-NEXT:    retl
8140;
8141; X64-NOBMI-LABEL: c0_i32:
8142; X64-NOBMI:       # %bb.0:
8143; X64-NOBMI-NEXT:    movl %edi, %eax
8144; X64-NOBMI-NEXT:    shrl $19, %eax
8145; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
8146; X64-NOBMI-NEXT:    retq
8147;
8148; X64-BMINOTBM-LABEL: c0_i32:
8149; X64-BMINOTBM:       # %bb.0:
8150; X64-BMINOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
8151; X64-BMINOTBM-NEXT:    bextrl %eax, %edi, %eax
8152; X64-BMINOTBM-NEXT:    retq
8153;
8154; X64-BMITBM-LABEL: c0_i32:
8155; X64-BMITBM:       # %bb.0:
8156; X64-BMITBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
8157; X64-BMITBM-NEXT:    retq
8158  %tmp0 = lshr i32 %arg, 19
8159  %tmp1 = and i32 %tmp0, 1023
8160  ret i32 %tmp1
8161}
8162
8163; Should be still fine, but the mask is shifted
8164define i32 @c1_i32(i32 %arg) nounwind {
8165; X86-LABEL: c1_i32:
8166; X86:       # %bb.0:
8167; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8168; X86-NEXT:    shrl $19, %eax
8169; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
8170; X86-NEXT:    retl
8171;
8172; X64-LABEL: c1_i32:
8173; X64:       # %bb.0:
8174; X64-NEXT:    movl %edi, %eax
8175; X64-NEXT:    shrl $19, %eax
8176; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
8177; X64-NEXT:    retq
8178  %tmp0 = lshr i32 %arg, 19
8179  %tmp1 = and i32 %tmp0, 4092
8180  ret i32 %tmp1
8181}
8182
8183; Should be still fine, but the result is shifted left afterwards
8184define i32 @c2_i32(i32 %arg) nounwind {
8185; X86-LABEL: c2_i32:
8186; X86:       # %bb.0:
8187; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8188; X86-NEXT:    shrl $17, %eax
8189; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
8190; X86-NEXT:    retl
8191;
8192; X64-LABEL: c2_i32:
8193; X64:       # %bb.0:
8194; X64-NEXT:    movl %edi, %eax
8195; X64-NEXT:    shrl $17, %eax
8196; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
8197; X64-NEXT:    retq
8198  %tmp0 = lshr i32 %arg, 19
8199  %tmp1 = and i32 %tmp0, 1023
8200  %tmp2 = shl i32 %tmp1, 2
8201  ret i32 %tmp2
8202}
8203
8204; The mask covers newly shifted-in bit
8205define i32 @c4_i32_bad(i32 %arg) nounwind {
8206; X86-LABEL: c4_i32_bad:
8207; X86:       # %bb.0:
8208; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8209; X86-NEXT:    shrl $19, %eax
8210; X86-NEXT:    andl $-2, %eax
8211; X86-NEXT:    retl
8212;
8213; X64-LABEL: c4_i32_bad:
8214; X64:       # %bb.0:
8215; X64-NEXT:    movl %edi, %eax
8216; X64-NEXT:    shrl $19, %eax
8217; X64-NEXT:    andl $-2, %eax
8218; X64-NEXT:    retq
8219  %tmp0 = lshr i32 %arg, 19
8220  %tmp1 = and i32 %tmp0, 16382
8221  ret i32 %tmp1
8222}
8223
8224; i64
8225
8226; The most canonical variant
8227define i64 @c0_i64(i64 %arg) nounwind {
8228; X86-NOBMI-LABEL: c0_i64:
8229; X86-NOBMI:       # %bb.0:
8230; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8231; X86-NOBMI-NEXT:    shrl $19, %eax
8232; X86-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
8233; X86-NOBMI-NEXT:    xorl %edx, %edx
8234; X86-NOBMI-NEXT:    retl
8235;
8236; X86-BMINOTBM-LABEL: c0_i64:
8237; X86-BMINOTBM:       # %bb.0:
8238; X86-BMINOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
8239; X86-BMINOTBM-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
8240; X86-BMINOTBM-NEXT:    xorl %edx, %edx
8241; X86-BMINOTBM-NEXT:    retl
8242;
8243; X86-BMITBM-LABEL: c0_i64:
8244; X86-BMITBM:       # %bb.0:
8245; X86-BMITBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13
8246; X86-BMITBM-NEXT:    xorl %edx, %edx
8247; X86-BMITBM-NEXT:    retl
8248;
8249; X64-NOBMI-LABEL: c0_i64:
8250; X64-NOBMI:       # %bb.0:
8251; X64-NOBMI-NEXT:    movq %rdi, %rax
8252; X64-NOBMI-NEXT:    shrq $51, %rax
8253; X64-NOBMI-NEXT:    andl $1023, %eax # imm = 0x3FF
8254; X64-NOBMI-NEXT:    retq
8255;
8256; X64-BMINOTBM-LABEL: c0_i64:
8257; X64-BMINOTBM:       # %bb.0:
8258; X64-BMINOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
8259; X64-BMINOTBM-NEXT:    bextrq %rax, %rdi, %rax
8260; X64-BMINOTBM-NEXT:    retq
8261;
8262; X64-BMITBM-LABEL: c0_i64:
8263; X64-BMITBM:       # %bb.0:
8264; X64-BMITBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
8265; X64-BMITBM-NEXT:    retq
8266  %tmp0 = lshr i64 %arg, 51
8267  %tmp1 = and i64 %tmp0, 1023
8268  ret i64 %tmp1
8269}
8270
8271; Should be still fine, but the mask is shifted
8272define i64 @c1_i64(i64 %arg) nounwind {
8273; X86-LABEL: c1_i64:
8274; X86:       # %bb.0:
8275; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8276; X86-NEXT:    shrl $19, %eax
8277; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
8278; X86-NEXT:    xorl %edx, %edx
8279; X86-NEXT:    retl
8280;
8281; X64-LABEL: c1_i64:
8282; X64:       # %bb.0:
8283; X64-NEXT:    movq %rdi, %rax
8284; X64-NEXT:    shrq $51, %rax
8285; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
8286; X64-NEXT:    retq
8287  %tmp0 = lshr i64 %arg, 51
8288  %tmp1 = and i64 %tmp0, 4092
8289  ret i64 %tmp1
8290}
8291
8292; Should be still fine, but the result is shifted left afterwards
8293define i64 @c2_i64(i64 %arg) nounwind {
8294; X86-LABEL: c2_i64:
8295; X86:       # %bb.0:
8296; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8297; X86-NEXT:    shrl $17, %eax
8298; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
8299; X86-NEXT:    xorl %edx, %edx
8300; X86-NEXT:    retl
8301;
8302; X64-LABEL: c2_i64:
8303; X64:       # %bb.0:
8304; X64-NEXT:    movq %rdi, %rax
8305; X64-NEXT:    shrq $49, %rax
8306; X64-NEXT:    andl $4092, %eax # imm = 0xFFC
8307; X64-NEXT:    retq
8308  %tmp0 = lshr i64 %arg, 51
8309  %tmp1 = and i64 %tmp0, 1023
8310  %tmp2 = shl i64 %tmp1, 2
8311  ret i64 %tmp2
8312}
8313
8314; The mask covers newly shifted-in bit
8315define i64 @c4_i64_bad(i64 %arg) nounwind {
8316; X86-LABEL: c4_i64_bad:
8317; X86:       # %bb.0:
8318; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8319; X86-NEXT:    shrl $19, %eax
8320; X86-NEXT:    andl $-2, %eax
8321; X86-NEXT:    xorl %edx, %edx
8322; X86-NEXT:    retl
8323;
8324; X64-LABEL: c4_i64_bad:
8325; X64:       # %bb.0:
8326; X64-NEXT:    movq %rdi, %rax
8327; X64-NEXT:    shrq $51, %rax
8328; X64-NEXT:    andl $-2, %eax
8329; X64-NEXT:    retq
8330  %tmp0 = lshr i64 %arg, 51
8331  %tmp1 = and i64 %tmp0, 16382
8332  ret i64 %tmp1
8333}
8334
8335; ---------------------------------------------------------------------------- ;
8336; Constant, storing the result afterwards.
8337; ---------------------------------------------------------------------------- ;
8338
8339; i32
8340
8341; The most canonical variant
8342define void @c5_i32(i32 %arg, ptr %ptr) nounwind {
8343; X86-NOBMI-LABEL: c5_i32:
8344; X86-NOBMI:       # %bb.0:
8345; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8346; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8347; X86-NOBMI-NEXT:    shrl $19, %ecx
8348; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
8349; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8350; X86-NOBMI-NEXT:    retl
8351;
8352; X86-BMINOTBM-LABEL: c5_i32:
8353; X86-BMINOTBM:       # %bb.0:
8354; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8355; X86-BMINOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
8356; X86-BMINOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8357; X86-BMINOTBM-NEXT:    movl %ecx, (%eax)
8358; X86-BMINOTBM-NEXT:    retl
8359;
8360; X86-BMITBM-LABEL: c5_i32:
8361; X86-BMITBM:       # %bb.0:
8362; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8363; X86-BMITBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
8364; X86-BMITBM-NEXT:    movl %ecx, (%eax)
8365; X86-BMITBM-NEXT:    retl
8366;
8367; X64-NOBMI-LABEL: c5_i32:
8368; X64-NOBMI:       # %bb.0:
8369; X64-NOBMI-NEXT:    shrl $19, %edi
8370; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
8371; X64-NOBMI-NEXT:    movl %edi, (%rsi)
8372; X64-NOBMI-NEXT:    retq
8373;
8374; X64-BMINOTBM-LABEL: c5_i32:
8375; X64-BMINOTBM:       # %bb.0:
8376; X64-BMINOTBM-NEXT:    movl $2579, %eax # imm = 0xA13
8377; X64-BMINOTBM-NEXT:    bextrl %eax, %edi, %eax
8378; X64-BMINOTBM-NEXT:    movl %eax, (%rsi)
8379; X64-BMINOTBM-NEXT:    retq
8380;
8381; X64-BMITBM-LABEL: c5_i32:
8382; X64-BMITBM:       # %bb.0:
8383; X64-BMITBM-NEXT:    bextrl $2579, %edi, %eax # imm = 0xA13
8384; X64-BMITBM-NEXT:    movl %eax, (%rsi)
8385; X64-BMITBM-NEXT:    retq
8386  %tmp0 = lshr i32 %arg, 19
8387  %tmp1 = and i32 %tmp0, 1023
8388  store i32 %tmp1, ptr %ptr
8389  ret void
8390}
8391
8392; Should be still fine, but the mask is shifted
8393define void @c6_i32(i32 %arg, ptr %ptr) nounwind {
8394; X86-NOBMI-LABEL: c6_i32:
8395; X86-NOBMI:       # %bb.0:
8396; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8397; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8398; X86-NOBMI-NEXT:    shrl $19, %ecx
8399; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
8400; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8401; X86-NOBMI-NEXT:    retl
8402;
8403; X86-BMINOTBM-LABEL: c6_i32:
8404; X86-BMINOTBM:       # %bb.0:
8405; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8406; X86-BMINOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
8407; X86-BMINOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8408; X86-BMINOTBM-NEXT:    movl %ecx, (%eax)
8409; X86-BMINOTBM-NEXT:    retl
8410;
8411; X86-BMITBM-LABEL: c6_i32:
8412; X86-BMITBM:       # %bb.0:
8413; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8414; X86-BMITBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
8415; X86-BMITBM-NEXT:    movl %ecx, (%eax)
8416; X86-BMITBM-NEXT:    retl
8417;
8418; X64-NOBMI-LABEL: c6_i32:
8419; X64-NOBMI:       # %bb.0:
8420; X64-NOBMI-NEXT:    shrl $19, %edi
8421; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
8422; X64-NOBMI-NEXT:    movl %edi, (%rsi)
8423; X64-NOBMI-NEXT:    retq
8424;
8425; X64-BMINOTBM-LABEL: c6_i32:
8426; X64-BMINOTBM:       # %bb.0:
8427; X64-BMINOTBM-NEXT:    movl $3091, %eax # imm = 0xC13
8428; X64-BMINOTBM-NEXT:    bextrl %eax, %edi, %eax
8429; X64-BMINOTBM-NEXT:    movl %eax, (%rsi)
8430; X64-BMINOTBM-NEXT:    retq
8431;
8432; X64-BMITBM-LABEL: c6_i32:
8433; X64-BMITBM:       # %bb.0:
8434; X64-BMITBM-NEXT:    bextrl $3091, %edi, %eax # imm = 0xC13
8435; X64-BMITBM-NEXT:    movl %eax, (%rsi)
8436; X64-BMITBM-NEXT:    retq
8437  %tmp0 = lshr i32 %arg, 19
8438  %tmp1 = and i32 %tmp0, 4095
8439  store i32 %tmp1, ptr %ptr
8440  ret void
8441}
8442
8443; Should be still fine, but the result is shifted left afterwards
8444define void @c7_i32(i32 %arg, ptr %ptr) nounwind {
8445; X86-LABEL: c7_i32:
8446; X86:       # %bb.0:
8447; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8448; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8449; X86-NEXT:    shrl $17, %ecx
8450; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
8451; X86-NEXT:    movl %ecx, (%eax)
8452; X86-NEXT:    retl
8453;
8454; X64-LABEL: c7_i32:
8455; X64:       # %bb.0:
8456; X64-NEXT:    shrl $17, %edi
8457; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
8458; X64-NEXT:    movl %edi, (%rsi)
8459; X64-NEXT:    retq
8460  %tmp0 = lshr i32 %arg, 19
8461  %tmp1 = and i32 %tmp0, 1023
8462  %tmp2 = shl i32 %tmp1, 2
8463  store i32 %tmp2, ptr %ptr
8464  ret void
8465}
8466
8467; i64
8468
8469; The most canonical variant
8470define void @c5_i64(i64 %arg, ptr %ptr) nounwind {
8471; X86-NOBMI-LABEL: c5_i64:
8472; X86-NOBMI:       # %bb.0:
8473; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8474; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8475; X86-NOBMI-NEXT:    shrl $19, %ecx
8476; X86-NOBMI-NEXT:    andl $1023, %ecx # imm = 0x3FF
8477; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8478; X86-NOBMI-NEXT:    movl $0, 4(%eax)
8479; X86-NOBMI-NEXT:    retl
8480;
8481; X86-BMINOTBM-LABEL: c5_i64:
8482; X86-BMINOTBM:       # %bb.0:
8483; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8484; X86-BMINOTBM-NEXT:    movl $2579, %ecx # imm = 0xA13
8485; X86-BMINOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8486; X86-BMINOTBM-NEXT:    movl %ecx, (%eax)
8487; X86-BMINOTBM-NEXT:    movl $0, 4(%eax)
8488; X86-BMINOTBM-NEXT:    retl
8489;
8490; X86-BMITBM-LABEL: c5_i64:
8491; X86-BMITBM:       # %bb.0:
8492; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8493; X86-BMITBM-NEXT:    bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13
8494; X86-BMITBM-NEXT:    movl %ecx, (%eax)
8495; X86-BMITBM-NEXT:    movl $0, 4(%eax)
8496; X86-BMITBM-NEXT:    retl
8497;
8498; X64-NOBMI-LABEL: c5_i64:
8499; X64-NOBMI:       # %bb.0:
8500; X64-NOBMI-NEXT:    shrq $51, %rdi
8501; X64-NOBMI-NEXT:    andl $1023, %edi # imm = 0x3FF
8502; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
8503; X64-NOBMI-NEXT:    retq
8504;
8505; X64-BMINOTBM-LABEL: c5_i64:
8506; X64-BMINOTBM:       # %bb.0:
8507; X64-BMINOTBM-NEXT:    movl $2611, %eax # imm = 0xA33
8508; X64-BMINOTBM-NEXT:    bextrq %rax, %rdi, %rax
8509; X64-BMINOTBM-NEXT:    movq %rax, (%rsi)
8510; X64-BMINOTBM-NEXT:    retq
8511;
8512; X64-BMITBM-LABEL: c5_i64:
8513; X64-BMITBM:       # %bb.0:
8514; X64-BMITBM-NEXT:    bextrq $2611, %rdi, %rax # imm = 0xA33
8515; X64-BMITBM-NEXT:    movq %rax, (%rsi)
8516; X64-BMITBM-NEXT:    retq
8517  %tmp0 = lshr i64 %arg, 51
8518  %tmp1 = and i64 %tmp0, 1023
8519  store i64 %tmp1, ptr %ptr
8520  ret void
8521}
8522
8523; Should be still fine, but the mask is shifted
8524define void @c6_i64(i64 %arg, ptr %ptr) nounwind {
8525; X86-NOBMI-LABEL: c6_i64:
8526; X86-NOBMI:       # %bb.0:
8527; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
8528; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8529; X86-NOBMI-NEXT:    shrl $19, %ecx
8530; X86-NOBMI-NEXT:    andl $4095, %ecx # imm = 0xFFF
8531; X86-NOBMI-NEXT:    movl %ecx, (%eax)
8532; X86-NOBMI-NEXT:    movl $0, 4(%eax)
8533; X86-NOBMI-NEXT:    retl
8534;
8535; X86-BMINOTBM-LABEL: c6_i64:
8536; X86-BMINOTBM:       # %bb.0:
8537; X86-BMINOTBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8538; X86-BMINOTBM-NEXT:    movl $3091, %ecx # imm = 0xC13
8539; X86-BMINOTBM-NEXT:    bextrl %ecx, {{[0-9]+}}(%esp), %ecx
8540; X86-BMINOTBM-NEXT:    movl %ecx, (%eax)
8541; X86-BMINOTBM-NEXT:    movl $0, 4(%eax)
8542; X86-BMINOTBM-NEXT:    retl
8543;
8544; X86-BMITBM-LABEL: c6_i64:
8545; X86-BMITBM:       # %bb.0:
8546; X86-BMITBM-NEXT:    movl {{[0-9]+}}(%esp), %eax
8547; X86-BMITBM-NEXT:    bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13
8548; X86-BMITBM-NEXT:    movl %ecx, (%eax)
8549; X86-BMITBM-NEXT:    movl $0, 4(%eax)
8550; X86-BMITBM-NEXT:    retl
8551;
8552; X64-NOBMI-LABEL: c6_i64:
8553; X64-NOBMI:       # %bb.0:
8554; X64-NOBMI-NEXT:    shrq $51, %rdi
8555; X64-NOBMI-NEXT:    andl $4095, %edi # imm = 0xFFF
8556; X64-NOBMI-NEXT:    movq %rdi, (%rsi)
8557; X64-NOBMI-NEXT:    retq
8558;
8559; X64-BMINOTBM-LABEL: c6_i64:
8560; X64-BMINOTBM:       # %bb.0:
8561; X64-BMINOTBM-NEXT:    movl $3123, %eax # imm = 0xC33
8562; X64-BMINOTBM-NEXT:    bextrq %rax, %rdi, %rax
8563; X64-BMINOTBM-NEXT:    movq %rax, (%rsi)
8564; X64-BMINOTBM-NEXT:    retq
8565;
8566; X64-BMITBM-LABEL: c6_i64:
8567; X64-BMITBM:       # %bb.0:
8568; X64-BMITBM-NEXT:    bextrq $3123, %rdi, %rax # imm = 0xC33
8569; X64-BMITBM-NEXT:    movq %rax, (%rsi)
8570; X64-BMITBM-NEXT:    retq
8571  %tmp0 = lshr i64 %arg, 51
8572  %tmp1 = and i64 %tmp0, 4095
8573  store i64 %tmp1, ptr %ptr
8574  ret void
8575}
8576
8577; Should be still fine, but the result is shifted left afterwards
8578define void @c7_i64(i64 %arg, ptr %ptr) nounwind {
8579; X86-LABEL: c7_i64:
8580; X86:       # %bb.0:
8581; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8582; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
8583; X86-NEXT:    shrl $17, %ecx
8584; X86-NEXT:    andl $4092, %ecx # imm = 0xFFC
8585; X86-NEXT:    movl %ecx, (%eax)
8586; X86-NEXT:    movl $0, 4(%eax)
8587; X86-NEXT:    retl
8588;
8589; X64-LABEL: c7_i64:
8590; X64:       # %bb.0:
8591; X64-NEXT:    shrq $49, %rdi
8592; X64-NEXT:    andl $4092, %edi # imm = 0xFFC
8593; X64-NEXT:    movq %rdi, (%rsi)
8594; X64-NEXT:    retq
8595  %tmp0 = lshr i64 %arg, 51
8596  %tmp1 = and i64 %tmp0, 1023
8597  %tmp2 = shl i64 %tmp1, 2
8598  store i64 %tmp2, ptr %ptr
8599  ret void
8600}
8601
8602define i64 @c8_i64(i64 %arg, ptr %ptr) nounwind {
8603; X86-LABEL: c8_i64:
8604; X86:       # %bb.0:
8605; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
8606; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
8607; X86-NEXT:    movl (%eax), %eax
8608; X86-NEXT:    shrl $19, %eax
8609; X86-NEXT:    andl $4092, %eax # imm = 0xFFC
8610; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
8611; X86-NEXT:    adcl $0, %edx
8612; X86-NEXT:    retl
8613;
8614; X64-NOBMI-LABEL: c8_i64:
8615; X64-NOBMI:       # %bb.0:
8616; X64-NOBMI-NEXT:    movl (%rsi), %eax
8617; X64-NOBMI-NEXT:    shrl $19, %eax
8618; X64-NOBMI-NEXT:    andl $4092, %eax # imm = 0xFFC
8619; X64-NOBMI-NEXT:    addq %rdi, %rax
8620; X64-NOBMI-NEXT:    retq
8621;
8622; X64-BMINOTBM-LABEL: c8_i64:
8623; X64-BMINOTBM:       # %bb.0:
8624; X64-BMINOTBM-NEXT:    movl $2581, %eax # imm = 0xA15
8625; X64-BMINOTBM-NEXT:    bextrl %eax, (%rsi), %eax
8626; X64-BMINOTBM-NEXT:    leaq (%rdi,%rax,4), %rax
8627; X64-BMINOTBM-NEXT:    retq
8628;
8629; X64-BMITBM-LABEL: c8_i64:
8630; X64-BMITBM:       # %bb.0:
8631; X64-BMITBM-NEXT:    bextrl $2581, (%rsi), %eax # imm = 0xA15
8632; X64-BMITBM-NEXT:    leaq (%rdi,%rax,4), %rax
8633; X64-BMITBM-NEXT:    retq
8634  %tmp = load i32, ptr %ptr, align 8
8635  %tmp1 = lshr i32 %tmp, 19
8636  %tmp2 = and i32 %tmp1, 4092
8637  %tmp3 = zext i32 %tmp2 to i64
8638  %tmp4 = add i64 %arg, %tmp3
8639  ret i64 %tmp4
8640}
8641