xref: /llvm-project/llvm/test/CodeGen/X86/shift-mask.ll (revision a70d5e25f32ebd5f1d1c394312036a37591e998b)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s --check-prefixes=X64,X64-MASK
4; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver1 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-SHIFT2
5; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver2 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-TBM
6; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver3 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-TBM
7; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver4 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-TBM
8; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver1 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-SHIFT2
9; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver2 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-BMI,X64-BMI1
10; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver1 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-BMI,X64-BMI2
11; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver2 | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-BMI,X64-BMI2
12; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+fast-scalar-shift-masks | FileCheck %s --check-prefixes=X64,X64-SHIFT,X64-SHIFT2
13
14;
15; fold (shl (lshr x, c1), c2) -> (0) (and x, MASK) or
16;                                (1) (and (shl x, (sub c2, c1), MASK) or
17;                                (2) (and (lshr x, (sub c1, c2), MASK)
18;
19
20define i8 @test_i8_shl_lshr_0(i8 %a0) {
21; X86-LABEL: test_i8_shl_lshr_0:
22; X86:       # %bb.0:
23; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
24; X86-NEXT:    andb $-8, %al
25; X86-NEXT:    retl
26;
27; X64-LABEL: test_i8_shl_lshr_0:
28; X64:       # %bb.0:
29; X64-NEXT:    movl %edi, %eax
30; X64-NEXT:    andb $-8, %al
31; X64-NEXT:    # kill: def $al killed $al killed $eax
32; X64-NEXT:    retq
33  %1 = lshr i8 %a0, 3
34  %2 = shl i8 %1, 3
35  ret i8 %2
36}
37
38define i8 @test_i8_shl_lshr_1(i8 %a0) {
39; X86-LABEL: test_i8_shl_lshr_1:
40; X86:       # %bb.0:
41; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
42; X86-NEXT:    shlb $2, %al
43; X86-NEXT:    andb $-32, %al
44; X86-NEXT:    retl
45;
46; X64-MASK-LABEL: test_i8_shl_lshr_1:
47; X64-MASK:       # %bb.0:
48; X64-MASK-NEXT:    # kill: def $edi killed $edi def $rdi
49; X64-MASK-NEXT:    leal (,%rdi,4), %eax
50; X64-MASK-NEXT:    andb $-32, %al
51; X64-MASK-NEXT:    # kill: def $al killed $al killed $eax
52; X64-MASK-NEXT:    retq
53;
54; X64-SHIFT-LABEL: test_i8_shl_lshr_1:
55; X64-SHIFT:       # %bb.0:
56; X64-SHIFT-NEXT:    movl %edi, %eax
57; X64-SHIFT-NEXT:    shrb $3, %al
58; X64-SHIFT-NEXT:    shlb $5, %al
59; X64-SHIFT-NEXT:    # kill: def $al killed $al killed $eax
60; X64-SHIFT-NEXT:    retq
61  %1 = lshr i8 %a0, 3
62  %2 = shl i8 %1, 5
63  ret i8 %2
64}
65
66define i8 @test_i8_shl_lshr_2(i8 %a0) {
67; X86-LABEL: test_i8_shl_lshr_2:
68; X86:       # %bb.0:
69; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
70; X86-NEXT:    shrb $2, %al
71; X86-NEXT:    andb $56, %al
72; X86-NEXT:    retl
73;
74; X64-MASK-LABEL: test_i8_shl_lshr_2:
75; X64-MASK:       # %bb.0:
76; X64-MASK-NEXT:    movl %edi, %eax
77; X64-MASK-NEXT:    shrb $2, %al
78; X64-MASK-NEXT:    andb $56, %al
79; X64-MASK-NEXT:    # kill: def $al killed $al killed $eax
80; X64-MASK-NEXT:    retq
81;
82; X64-SHIFT-LABEL: test_i8_shl_lshr_2:
83; X64-SHIFT:       # %bb.0:
84; X64-SHIFT-NEXT:    # kill: def $edi killed $edi def $rdi
85; X64-SHIFT-NEXT:    shrb $5, %dil
86; X64-SHIFT-NEXT:    leal (,%rdi,8), %eax
87; X64-SHIFT-NEXT:    # kill: def $al killed $al killed $eax
88; X64-SHIFT-NEXT:    retq
89  %1 = lshr i8 %a0, 5
90  %2 = shl i8 %1, 3
91  ret i8 %2
92}
93
94define i16 @test_i16_shl_lshr_0(i16 %a0) {
95; X86-LABEL: test_i16_shl_lshr_0:
96; X86:       # %bb.0:
97; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
98; X86-NEXT:    andl $-8, %eax
99; X86-NEXT:    # kill: def $ax killed $ax killed $eax
100; X86-NEXT:    retl
101;
102; X64-LABEL: test_i16_shl_lshr_0:
103; X64:       # %bb.0:
104; X64-NEXT:    movl %edi, %eax
105; X64-NEXT:    andl $65528, %eax # imm = 0xFFF8
106; X64-NEXT:    # kill: def $ax killed $ax killed $eax
107; X64-NEXT:    retq
108  %1 = lshr i16 %a0, 3
109  %2 = shl i16 %1, 3
110  ret i16 %2
111}
112
113define i16 @test_i16_shl_lshr_1(i16 %a0) {
114; X86-LABEL: test_i16_shl_lshr_1:
115; X86:       # %bb.0:
116; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
117; X86-NEXT:    shll $2, %eax
118; X86-NEXT:    andl $65504, %eax # imm = 0xFFE0
119; X86-NEXT:    # kill: def $ax killed $ax killed $eax
120; X86-NEXT:    retl
121;
122; X64-MASK-LABEL: test_i16_shl_lshr_1:
123; X64-MASK:       # %bb.0:
124; X64-MASK-NEXT:    # kill: def $edi killed $edi def $rdi
125; X64-MASK-NEXT:    leal (,%rdi,4), %eax
126; X64-MASK-NEXT:    andl $65504, %eax # imm = 0xFFE0
127; X64-MASK-NEXT:    # kill: def $ax killed $ax killed $eax
128; X64-MASK-NEXT:    retq
129;
130; X64-SHIFT-LABEL: test_i16_shl_lshr_1:
131; X64-SHIFT:       # %bb.0:
132; X64-SHIFT-NEXT:    movzwl %di, %eax
133; X64-SHIFT-NEXT:    shrl $3, %eax
134; X64-SHIFT-NEXT:    shll $5, %eax
135; X64-SHIFT-NEXT:    # kill: def $ax killed $ax killed $eax
136; X64-SHIFT-NEXT:    retq
137  %1 = lshr i16 %a0, 3
138  %2 = shl i16 %1, 5
139  ret i16 %2
140}
141
142define i16 @test_i16_shl_lshr_2(i16 %a0) {
143; X86-LABEL: test_i16_shl_lshr_2:
144; X86:       # %bb.0:
145; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
146; X86-NEXT:    shrl $2, %eax
147; X86-NEXT:    andl $-8, %eax
148; X86-NEXT:    # kill: def $ax killed $ax killed $eax
149; X86-NEXT:    retl
150;
151; X64-MASK-LABEL: test_i16_shl_lshr_2:
152; X64-MASK:       # %bb.0:
153; X64-MASK-NEXT:    movl %edi, %eax
154; X64-MASK-NEXT:    shrl $2, %eax
155; X64-MASK-NEXT:    andl $16376, %eax # imm = 0x3FF8
156; X64-MASK-NEXT:    # kill: def $ax killed $ax killed $eax
157; X64-MASK-NEXT:    retq
158;
159; X64-SHIFT-LABEL: test_i16_shl_lshr_2:
160; X64-SHIFT:       # %bb.0:
161; X64-SHIFT-NEXT:    movzwl %di, %eax
162; X64-SHIFT-NEXT:    shrl $5, %eax
163; X64-SHIFT-NEXT:    shll $3, %eax
164; X64-SHIFT-NEXT:    # kill: def $ax killed $ax killed $eax
165; X64-SHIFT-NEXT:    retq
166  %1 = lshr i16 %a0, 5
167  %2 = shl i16 %1, 3
168  ret i16 %2
169}
170
171define i32 @test_i32_shl_lshr_0(i32 %a0) {
172; X86-LABEL: test_i32_shl_lshr_0:
173; X86:       # %bb.0:
174; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
175; X86-NEXT:    andl $-8, %eax
176; X86-NEXT:    retl
177;
178; X64-LABEL: test_i32_shl_lshr_0:
179; X64:       # %bb.0:
180; X64-NEXT:    movl %edi, %eax
181; X64-NEXT:    andl $-8, %eax
182; X64-NEXT:    retq
183  %1 = lshr i32 %a0, 3
184  %2 = shl i32 %1, 3
185  ret i32 %2
186}
187
188define i32 @test_i32_shl_lshr_1(i32 %a0) {
189; X86-LABEL: test_i32_shl_lshr_1:
190; X86:       # %bb.0:
191; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
192; X86-NEXT:    shll $2, %eax
193; X86-NEXT:    andl $-32, %eax
194; X86-NEXT:    retl
195;
196; X64-MASK-LABEL: test_i32_shl_lshr_1:
197; X64-MASK:       # %bb.0:
198; X64-MASK-NEXT:    # kill: def $edi killed $edi def $rdi
199; X64-MASK-NEXT:    leal (,%rdi,4), %eax
200; X64-MASK-NEXT:    andl $-32, %eax
201; X64-MASK-NEXT:    retq
202;
203; X64-SHIFT-LABEL: test_i32_shl_lshr_1:
204; X64-SHIFT:       # %bb.0:
205; X64-SHIFT-NEXT:    movl %edi, %eax
206; X64-SHIFT-NEXT:    shrl $3, %eax
207; X64-SHIFT-NEXT:    shll $5, %eax
208; X64-SHIFT-NEXT:    retq
209  %1 = lshr i32 %a0, 3
210  %2 = shl i32 %1, 5
211  ret i32 %2
212}
213
214define i32 @test_i32_shl_lshr_2(i32 %a0) {
215; X86-LABEL: test_i32_shl_lshr_2:
216; X86:       # %bb.0:
217; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
218; X86-NEXT:    shrl $2, %eax
219; X86-NEXT:    andl $-8, %eax
220; X86-NEXT:    retl
221;
222; X64-MASK-LABEL: test_i32_shl_lshr_2:
223; X64-MASK:       # %bb.0:
224; X64-MASK-NEXT:    movl %edi, %eax
225; X64-MASK-NEXT:    shrl $2, %eax
226; X64-MASK-NEXT:    andl $-8, %eax
227; X64-MASK-NEXT:    retq
228;
229; X64-SHIFT-LABEL: test_i32_shl_lshr_2:
230; X64-SHIFT:       # %bb.0:
231; X64-SHIFT-NEXT:    # kill: def $edi killed $edi def $rdi
232; X64-SHIFT-NEXT:    shrl $5, %edi
233; X64-SHIFT-NEXT:    leal (,%rdi,8), %eax
234; X64-SHIFT-NEXT:    retq
235  %1 = lshr i32 %a0, 5
236  %2 = shl i32 %1, 3
237  ret i32 %2
238}
239
240define i64 @test_i64_shl_lshr_0(i64 %a0) {
241; X86-LABEL: test_i64_shl_lshr_0:
242; X86:       # %bb.0:
243; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
244; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
245; X86-NEXT:    andl $-8, %eax
246; X86-NEXT:    retl
247;
248; X64-LABEL: test_i64_shl_lshr_0:
249; X64:       # %bb.0:
250; X64-NEXT:    movq %rdi, %rax
251; X64-NEXT:    andq $-8, %rax
252; X64-NEXT:    retq
253  %1 = lshr i64 %a0, 3
254  %2 = shl i64 %1, 3
255  ret i64 %2
256}
257
258define i64 @test_i64_shl_lshr_1(i64 %a0) {
259; X86-LABEL: test_i64_shl_lshr_1:
260; X86:       # %bb.0:
261; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
262; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
263; X86-NEXT:    shldl $2, %eax, %edx
264; X86-NEXT:    shll $2, %eax
265; X86-NEXT:    andl $-32, %eax
266; X86-NEXT:    retl
267;
268; X64-MASK-LABEL: test_i64_shl_lshr_1:
269; X64-MASK:       # %bb.0:
270; X64-MASK-NEXT:    leaq (,%rdi,4), %rax
271; X64-MASK-NEXT:    andq $-32, %rax
272; X64-MASK-NEXT:    retq
273;
274; X64-SHIFT-LABEL: test_i64_shl_lshr_1:
275; X64-SHIFT:       # %bb.0:
276; X64-SHIFT-NEXT:    movq %rdi, %rax
277; X64-SHIFT-NEXT:    shrq $3, %rax
278; X64-SHIFT-NEXT:    shlq $5, %rax
279; X64-SHIFT-NEXT:    retq
280  %1 = lshr i64 %a0, 3
281  %2 = shl i64 %1, 5
282  ret i64 %2
283}
284
285define i64 @test_i64_shl_lshr_2(i64 %a0) {
286; X86-LABEL: test_i64_shl_lshr_2:
287; X86:       # %bb.0:
288; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
289; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
290; X86-NEXT:    shrdl $2, %edx, %eax
291; X86-NEXT:    shrl $2, %edx
292; X86-NEXT:    andl $-8, %eax
293; X86-NEXT:    retl
294;
295; X64-MASK-LABEL: test_i64_shl_lshr_2:
296; X64-MASK:       # %bb.0:
297; X64-MASK-NEXT:    movq %rdi, %rax
298; X64-MASK-NEXT:    shrq $2, %rax
299; X64-MASK-NEXT:    andq $-8, %rax
300; X64-MASK-NEXT:    retq
301;
302; X64-SHIFT-LABEL: test_i64_shl_lshr_2:
303; X64-SHIFT:       # %bb.0:
304; X64-SHIFT-NEXT:    shrq $5, %rdi
305; X64-SHIFT-NEXT:    leaq (,%rdi,8), %rax
306; X64-SHIFT-NEXT:    retq
307  %1 = lshr i64 %a0, 5
308  %2 = shl i64 %1, 3
309  ret i64 %2
310}
311
312;
313; fold (lshr (shl x, c1), c2) -> (0) (and x, MASK) or
314;                                (1) (and (shl x, (sub c1, c2), MASK) or
315;                                (2) (and (lshr x, (sub c2, c1), MASK)
316;
317
318define i8 @test_i8_lshr_lshr_0(i8 %a0) {
319; X86-LABEL: test_i8_lshr_lshr_0:
320; X86:       # %bb.0:
321; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
322; X86-NEXT:    andb $31, %al
323; X86-NEXT:    retl
324;
325; X64-LABEL: test_i8_lshr_lshr_0:
326; X64:       # %bb.0:
327; X64-NEXT:    movl %edi, %eax
328; X64-NEXT:    andb $31, %al
329; X64-NEXT:    # kill: def $al killed $al killed $eax
330; X64-NEXT:    retq
331  %1 = shl i8 %a0, 3
332  %2 = lshr i8 %1, 3
333  ret i8 %2
334}
335
336define i8 @test_i8_lshr_lshr_1(i8 %a0) {
337; X86-LABEL: test_i8_lshr_lshr_1:
338; X86:       # %bb.0:
339; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
340; X86-NEXT:    shrb $2, %al
341; X86-NEXT:    andb $7, %al
342; X86-NEXT:    retl
343;
344; X64-MASK-LABEL: test_i8_lshr_lshr_1:
345; X64-MASK:       # %bb.0:
346; X64-MASK-NEXT:    movl %edi, %eax
347; X64-MASK-NEXT:    shrb $2, %al
348; X64-MASK-NEXT:    andb $7, %al
349; X64-MASK-NEXT:    # kill: def $al killed $al killed $eax
350; X64-MASK-NEXT:    retq
351;
352; X64-SHIFT-LABEL: test_i8_lshr_lshr_1:
353; X64-SHIFT:       # %bb.0:
354; X64-SHIFT-NEXT:    # kill: def $edi killed $edi def $rdi
355; X64-SHIFT-NEXT:    leal (,%rdi,8), %eax
356; X64-SHIFT-NEXT:    shrb $5, %al
357; X64-SHIFT-NEXT:    # kill: def $al killed $al killed $eax
358; X64-SHIFT-NEXT:    retq
359  %1 = shl i8 %a0, 3
360  %2 = lshr i8 %1, 5
361  ret i8 %2
362}
363
364define i8 @test_i8_lshr_lshr_2(i8 %a0) {
365; X86-LABEL: test_i8_lshr_lshr_2:
366; X86:       # %bb.0:
367; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
368; X86-NEXT:    shlb $2, %al
369; X86-NEXT:    andb $28, %al
370; X86-NEXT:    retl
371;
372; X64-MASK-LABEL: test_i8_lshr_lshr_2:
373; X64-MASK:       # %bb.0:
374; X64-MASK-NEXT:    # kill: def $edi killed $edi def $rdi
375; X64-MASK-NEXT:    leal (,%rdi,4), %eax
376; X64-MASK-NEXT:    andb $28, %al
377; X64-MASK-NEXT:    # kill: def $al killed $al killed $eax
378; X64-MASK-NEXT:    retq
379;
380; X64-SHIFT-LABEL: test_i8_lshr_lshr_2:
381; X64-SHIFT:       # %bb.0:
382; X64-SHIFT-NEXT:    movl %edi, %eax
383; X64-SHIFT-NEXT:    shlb $5, %al
384; X64-SHIFT-NEXT:    shrb $3, %al
385; X64-SHIFT-NEXT:    # kill: def $al killed $al killed $eax
386; X64-SHIFT-NEXT:    retq
387  %1 = shl i8 %a0, 5
388  %2 = lshr i8 %1, 3
389  ret i8 %2
390}
391
392define i16 @test_i16_lshr_lshr_0(i16 %a0) {
393; X86-LABEL: test_i16_lshr_lshr_0:
394; X86:       # %bb.0:
395; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
396; X86-NEXT:    andl $8191, %eax # imm = 0x1FFF
397; X86-NEXT:    # kill: def $ax killed $ax killed $eax
398; X86-NEXT:    retl
399;
400; X64-LABEL: test_i16_lshr_lshr_0:
401; X64:       # %bb.0:
402; X64-NEXT:    movl %edi, %eax
403; X64-NEXT:    andl $8191, %eax # imm = 0x1FFF
404; X64-NEXT:    # kill: def $ax killed $ax killed $eax
405; X64-NEXT:    retq
406  %1 = shl i16 %a0, 3
407  %2 = lshr i16 %1, 3
408  ret i16 %2
409}
410
411define i16 @test_i16_lshr_lshr_1(i16 %a0) {
412; X86-LABEL: test_i16_lshr_lshr_1:
413; X86:       # %bb.0:
414; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
415; X86-NEXT:    shrl $2, %eax
416; X86-NEXT:    andl $2047, %eax # imm = 0x7FF
417; X86-NEXT:    # kill: def $ax killed $ax killed $eax
418; X86-NEXT:    retl
419;
420; X64-MASK-LABEL: test_i16_lshr_lshr_1:
421; X64-MASK:       # %bb.0:
422; X64-MASK-NEXT:    movl %edi, %eax
423; X64-MASK-NEXT:    shrl $2, %eax
424; X64-MASK-NEXT:    andl $2047, %eax # imm = 0x7FF
425; X64-MASK-NEXT:    # kill: def $ax killed $ax killed $eax
426; X64-MASK-NEXT:    retq
427;
428; X64-SHIFT2-LABEL: test_i16_lshr_lshr_1:
429; X64-SHIFT2:       # %bb.0:
430; X64-SHIFT2-NEXT:    movl %edi, %eax
431; X64-SHIFT2-NEXT:    shrl $2, %eax
432; X64-SHIFT2-NEXT:    andl $2047, %eax # imm = 0x7FF
433; X64-SHIFT2-NEXT:    # kill: def $ax killed $ax killed $eax
434; X64-SHIFT2-NEXT:    retq
435;
436; X64-TBM-LABEL: test_i16_lshr_lshr_1:
437; X64-TBM:       # %bb.0:
438; X64-TBM-NEXT:    bextrl $2818, %edi, %eax # imm = 0xB02
439; X64-TBM-NEXT:    # kill: def $ax killed $ax killed $eax
440; X64-TBM-NEXT:    retq
441;
442; X64-BMI-LABEL: test_i16_lshr_lshr_1:
443; X64-BMI:       # %bb.0:
444; X64-BMI-NEXT:    movl $2818, %eax # imm = 0xB02
445; X64-BMI-NEXT:    bextrl %eax, %edi, %eax
446; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
447; X64-BMI-NEXT:    retq
448  %1 = shl i16 %a0, 3
449  %2 = lshr i16 %1, 5
450  ret i16 %2
451}
452
453define i16 @test_i16_lshr_lshr_2(i16 %a0) {
454; X86-LABEL: test_i16_lshr_lshr_2:
455; X86:       # %bb.0:
456; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
457; X86-NEXT:    shll $2, %eax
458; X86-NEXT:    andl $8188, %eax # imm = 0x1FFC
459; X86-NEXT:    # kill: def $ax killed $ax killed $eax
460; X86-NEXT:    retl
461;
462; X64-LABEL: test_i16_lshr_lshr_2:
463; X64:       # %bb.0:
464; X64-NEXT:    # kill: def $edi killed $edi def $rdi
465; X64-NEXT:    leal (,%rdi,4), %eax
466; X64-NEXT:    andl $8188, %eax # imm = 0x1FFC
467; X64-NEXT:    # kill: def $ax killed $ax killed $eax
468; X64-NEXT:    retq
469  %1 = shl i16 %a0, 5
470  %2 = lshr i16 %1, 3
471  ret i16 %2
472}
473
474define i32 @test_i32_lshr_lshr_0(i32 %a0) {
475; X86-LABEL: test_i32_lshr_lshr_0:
476; X86:       # %bb.0:
477; X86-NEXT:    movl $536870911, %eax # imm = 0x1FFFFFFF
478; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
479; X86-NEXT:    retl
480;
481; X64-LABEL: test_i32_lshr_lshr_0:
482; X64:       # %bb.0:
483; X64-NEXT:    movl %edi, %eax
484; X64-NEXT:    andl $536870911, %eax # imm = 0x1FFFFFFF
485; X64-NEXT:    retq
486  %1 = shl i32 %a0, 3
487  %2 = lshr i32 %1, 3
488  ret i32 %2
489}
490
491define i32 @test_i32_lshr_lshr_1(i32 %a0) {
492; X86-LABEL: test_i32_lshr_lshr_1:
493; X86:       # %bb.0:
494; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
495; X86-NEXT:    shrl $2, %eax
496; X86-NEXT:    andl $134217727, %eax # imm = 0x7FFFFFF
497; X86-NEXT:    retl
498;
499; X64-MASK-LABEL: test_i32_lshr_lshr_1:
500; X64-MASK:       # %bb.0:
501; X64-MASK-NEXT:    movl %edi, %eax
502; X64-MASK-NEXT:    shrl $2, %eax
503; X64-MASK-NEXT:    andl $134217727, %eax # imm = 0x7FFFFFF
504; X64-MASK-NEXT:    retq
505;
506; X64-SHIFT-LABEL: test_i32_lshr_lshr_1:
507; X64-SHIFT:       # %bb.0:
508; X64-SHIFT-NEXT:    # kill: def $edi killed $edi def $rdi
509; X64-SHIFT-NEXT:    leal (,%rdi,8), %eax
510; X64-SHIFT-NEXT:    shrl $5, %eax
511; X64-SHIFT-NEXT:    retq
512  %1 = shl i32 %a0, 3
513  %2 = lshr i32 %1, 5
514  ret i32 %2
515}
516
517define i32 @test_i32_lshr_lshr_2(i32 %a0) {
518; X86-LABEL: test_i32_lshr_lshr_2:
519; X86:       # %bb.0:
520; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
521; X86-NEXT:    shll $2, %eax
522; X86-NEXT:    andl $536870908, %eax # imm = 0x1FFFFFFC
523; X86-NEXT:    retl
524;
525; X64-MASK-LABEL: test_i32_lshr_lshr_2:
526; X64-MASK:       # %bb.0:
527; X64-MASK-NEXT:    # kill: def $edi killed $edi def $rdi
528; X64-MASK-NEXT:    leal (,%rdi,4), %eax
529; X64-MASK-NEXT:    andl $536870908, %eax # imm = 0x1FFFFFFC
530; X64-MASK-NEXT:    retq
531;
532; X64-SHIFT-LABEL: test_i32_lshr_lshr_2:
533; X64-SHIFT:       # %bb.0:
534; X64-SHIFT-NEXT:    movl %edi, %eax
535; X64-SHIFT-NEXT:    shll $5, %eax
536; X64-SHIFT-NEXT:    shrl $3, %eax
537; X64-SHIFT-NEXT:    retq
538  %1 = shl i32 %a0, 5
539  %2 = lshr i32 %1, 3
540  ret i32 %2
541}
542
543define i64 @test_i64_lshr_lshr_0(i64 %a0) {
544; X86-LABEL: test_i64_lshr_lshr_0:
545; X86:       # %bb.0:
546; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
547; X86-NEXT:    movl $536870911, %edx # imm = 0x1FFFFFFF
548; X86-NEXT:    andl {{[0-9]+}}(%esp), %edx
549; X86-NEXT:    retl
550;
551; X64-MASK-LABEL: test_i64_lshr_lshr_0:
552; X64-MASK:       # %bb.0:
553; X64-MASK-NEXT:    movabsq $2305843009213693951, %rax # imm = 0x1FFFFFFFFFFFFFFF
554; X64-MASK-NEXT:    andq %rdi, %rax
555; X64-MASK-NEXT:    retq
556;
557; X64-SHIFT2-LABEL: test_i64_lshr_lshr_0:
558; X64-SHIFT2:       # %bb.0:
559; X64-SHIFT2-NEXT:    movabsq $2305843009213693951, %rax # imm = 0x1FFFFFFFFFFFFFFF
560; X64-SHIFT2-NEXT:    andq %rdi, %rax
561; X64-SHIFT2-NEXT:    retq
562;
563; X64-TBM-LABEL: test_i64_lshr_lshr_0:
564; X64-TBM:       # %bb.0:
565; X64-TBM-NEXT:    bextrq $15616, %rdi, %rax # imm = 0x3D00
566; X64-TBM-NEXT:    retq
567;
568; X64-BMI1-LABEL: test_i64_lshr_lshr_0:
569; X64-BMI1:       # %bb.0:
570; X64-BMI1-NEXT:    movl $15616, %eax # imm = 0x3D00
571; X64-BMI1-NEXT:    bextrq %rax, %rdi, %rax
572; X64-BMI1-NEXT:    retq
573;
574; X64-BMI2-LABEL: test_i64_lshr_lshr_0:
575; X64-BMI2:       # %bb.0:
576; X64-BMI2-NEXT:    movb $61, %al
577; X64-BMI2-NEXT:    bzhiq %rax, %rdi, %rax
578; X64-BMI2-NEXT:    retq
579  %1 = shl i64 %a0, 3
580  %2 = lshr i64 %1, 3
581  ret i64 %2
582}
583
584define i64 @test_i64_lshr_lshr_1(i64 %a0) {
585; X86-LABEL: test_i64_lshr_lshr_1:
586; X86:       # %bb.0:
587; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
588; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
589; X86-NEXT:    shrdl $2, %edx, %eax
590; X86-NEXT:    shrl $2, %edx
591; X86-NEXT:    andl $134217727, %edx # imm = 0x7FFFFFF
592; X86-NEXT:    retl
593;
594; X64-MASK-LABEL: test_i64_lshr_lshr_1:
595; X64-MASK:       # %bb.0:
596; X64-MASK-NEXT:    shrq $2, %rdi
597; X64-MASK-NEXT:    movabsq $576460752303423487, %rax # imm = 0x7FFFFFFFFFFFFFF
598; X64-MASK-NEXT:    andq %rdi, %rax
599; X64-MASK-NEXT:    retq
600;
601; X64-SHIFT-LABEL: test_i64_lshr_lshr_1:
602; X64-SHIFT:       # %bb.0:
603; X64-SHIFT-NEXT:    leaq (,%rdi,8), %rax
604; X64-SHIFT-NEXT:    shrq $5, %rax
605; X64-SHIFT-NEXT:    retq
606  %1 = shl i64 %a0, 3
607  %2 = lshr i64 %1, 5
608  ret i64 %2
609}
610
611define i64 @test_i64_lshr_lshr_2(i64 %a0) {
612; X86-LABEL: test_i64_lshr_lshr_2:
613; X86:       # %bb.0:
614; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
615; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
616; X86-NEXT:    shldl $2, %eax, %edx
617; X86-NEXT:    shll $2, %eax
618; X86-NEXT:    andl $536870911, %edx # imm = 0x1FFFFFFF
619; X86-NEXT:    retl
620;
621; X64-MASK-LABEL: test_i64_lshr_lshr_2:
622; X64-MASK:       # %bb.0:
623; X64-MASK-NEXT:    leaq (,%rdi,4), %rcx
624; X64-MASK-NEXT:    movabsq $2305843009213693948, %rax # imm = 0x1FFFFFFFFFFFFFFC
625; X64-MASK-NEXT:    andq %rcx, %rax
626; X64-MASK-NEXT:    retq
627;
628; X64-SHIFT-LABEL: test_i64_lshr_lshr_2:
629; X64-SHIFT:       # %bb.0:
630; X64-SHIFT-NEXT:    movq %rdi, %rax
631; X64-SHIFT-NEXT:    shlq $5, %rax
632; X64-SHIFT-NEXT:    shrq $3, %rax
633; X64-SHIFT-NEXT:    retq
634  %1 = shl i64 %a0, 5
635  %2 = lshr i64 %1, 3
636  ret i64 %2
637}
638