xref: /llvm-project/llvm/test/Transforms/InstCombine/shl-bo.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(i8)
5
6define i8 @lshr_add(i8 %a, i8 %y) {
7; CHECK-LABEL: @lshr_add(
8; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
9; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 5
10; CHECK-NEXT:    [[R2:%.*]] = add i8 [[Y:%.*]], [[B1]]
11; CHECK-NEXT:    [[L:%.*]] = and i8 [[R2]], -32
12; CHECK-NEXT:    ret i8 [[L]]
13;
14  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
15  %r = lshr i8 %y, 5
16  %b = add i8 %r, %x
17  %l = shl i8 %b, 5
18  ret i8 %l
19}
20
21define <2 x i8> @lshr_add_commute_splat(<2 x i8> %a, <2 x i8> %y) {
22; CHECK-LABEL: @lshr_add_commute_splat(
23; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
24; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 5)
25; CHECK-NEXT:    [[R2:%.*]] = add <2 x i8> [[Y:%.*]], [[B1]]
26; CHECK-NEXT:    [[L:%.*]] = and <2 x i8> [[R2]], splat (i8 -32)
27; CHECK-NEXT:    ret <2 x i8> [[L]]
28;
29  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
30  %r = lshr <2 x i8> %y, <i8 5, i8 5>
31  %b = add <2 x i8> %x, %r
32  %l = shl <2 x i8> %b, <i8 5, i8 5>
33  ret <2 x i8> %l
34}
35
36define i8 @lshr_sub(i8 %a, i8 %y) {
37; CHECK-LABEL: @lshr_sub(
38; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
39; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
40; CHECK-NEXT:    [[B:%.*]] = sub nsw i8 [[X]], [[R]]
41; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
42; CHECK-NEXT:    ret i8 [[L]]
43;
44  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
45  %r = lshr i8 %y, 3
46  %b = sub i8 %x, %r
47  %l = shl i8 %b, 3
48  ret i8 %l
49}
50
51define <2 x i8> @lshr_sub_commute_splat(<2 x i8> %a, <2 x i8> %y) {
52; CHECK-LABEL: @lshr_sub_commute_splat(
53; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
54; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3)
55; CHECK-NEXT:    [[R2:%.*]] = sub <2 x i8> [[Y:%.*]], [[B1]]
56; CHECK-NEXT:    [[L:%.*]] = and <2 x i8> [[R2]], splat (i8 -8)
57; CHECK-NEXT:    ret <2 x i8> [[L]]
58;
59  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
60  %r = lshr <2 x i8> %y, <i8 3, i8 3>
61  %b = sub <2 x i8> %r, %x
62  %l = shl <2 x i8> %b, <i8 3, i8 3>
63  ret <2 x i8> %l
64}
65
66define i8 @lshr_and(i8 %a, i8 %y) {
67; CHECK-LABEL: @lshr_and(
68; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
69; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 6
70; CHECK-NEXT:    [[R2:%.*]] = and i8 [[Y:%.*]], [[B1]]
71; CHECK-NEXT:    ret i8 [[R2]]
72;
73  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
74  %r = lshr i8 %y, 6
75  %b = and i8 %r, %x
76  %l = shl i8 %b, 6
77  ret i8 %l
78}
79
80define <2 x i8> @lshr_and_commute_splat(<2 x i8> %a, <2 x i8> %y) {
81; CHECK-LABEL: @lshr_and_commute_splat(
82; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
83; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 6)
84; CHECK-NEXT:    [[R2:%.*]] = and <2 x i8> [[Y:%.*]], [[B1]]
85; CHECK-NEXT:    ret <2 x i8> [[R2]]
86;
87  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
88  %r = lshr <2 x i8> %y, <i8 6, i8 6>
89  %b = and <2 x i8> %x, %r
90  %l = shl <2 x i8> %b, <i8 6, i8 6>
91  ret <2 x i8> %l
92}
93
94define i8 @lshr_or(i8 %a, i8 %y) {
95; CHECK-LABEL: @lshr_or(
96; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
97; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 4
98; CHECK-NEXT:    [[Y_MASKED:%.*]] = and i8 [[Y:%.*]], -16
99; CHECK-NEXT:    [[L:%.*]] = or i8 [[Y_MASKED]], [[B1]]
100; CHECK-NEXT:    ret i8 [[L]]
101;
102  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
103  %r = lshr i8 %y, 4
104  %b = or i8 %x, %r
105  %l = shl i8 %b, 4
106  ret i8 %l
107}
108
109define <2 x i8> @lshr_or_commute_splat(<2 x i8> %a, <2 x i8> %y) {
110; CHECK-LABEL: @lshr_or_commute_splat(
111; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
112; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 4)
113; CHECK-NEXT:    [[Y_MASKED:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 -16)
114; CHECK-NEXT:    [[L:%.*]] = or <2 x i8> [[Y_MASKED]], [[B1]]
115; CHECK-NEXT:    ret <2 x i8> [[L]]
116;
117  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
118  %r = lshr <2 x i8> %y, <i8 4, i8 4>
119  %b = or <2 x i8> %r, %x
120  %l = shl <2 x i8> %b, <i8 4, i8 4>
121  ret <2 x i8> %l
122}
123
124define i8 @lshr_xor(i8 %a, i8 %y) {
125; CHECK-LABEL: @lshr_xor(
126; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
127; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 3
128; CHECK-NEXT:    [[Y_MASKED:%.*]] = and i8 [[Y:%.*]], -8
129; CHECK-NEXT:    [[L:%.*]] = xor i8 [[Y_MASKED]], [[B1]]
130; CHECK-NEXT:    ret i8 [[L]]
131;
132  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
133  %r = lshr i8 %y, 3
134  %b = xor i8 %r, %x
135  %l = shl i8 %b, 3
136  ret i8 %l
137}
138
139define <2 x i8> @lshr_xor_commute_splat(<2 x i8> %a, <2 x i8> %y) {
140; CHECK-LABEL: @lshr_xor_commute_splat(
141; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
142; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3)
143; CHECK-NEXT:    [[Y_MASKED:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 -8)
144; CHECK-NEXT:    [[L:%.*]] = xor <2 x i8> [[Y_MASKED]], [[B1]]
145; CHECK-NEXT:    ret <2 x i8> [[L]]
146;
147  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
148  %r = lshr <2 x i8> %y, <i8 3, i8 3>
149  %b = xor <2 x i8> %x, %r
150  %l = shl <2 x i8> %b, <i8 3, i8 3>
151  ret <2 x i8> %l
152}
153
154define i8 @lshr_add_use1(i8 %x, i8 %y) {
155; CHECK-LABEL: @lshr_add_use1(
156; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 5
157; CHECK-NEXT:    call void @use(i8 [[R]])
158; CHECK-NEXT:    [[B:%.*]] = add i8 [[R]], [[X:%.*]]
159; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 5
160; CHECK-NEXT:    ret i8 [[L]]
161;
162  %r = lshr i8 %y, 5
163  call void @use(i8 %r)
164  %b = add i8 %r, %x
165  %l = shl i8 %b, 5
166  ret i8 %l
167}
168
169define i8 @lshr_add_use2(i8 %x, i8 %y) {
170; CHECK-LABEL: @lshr_add_use2(
171; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 5
172; CHECK-NEXT:    [[B:%.*]] = add i8 [[R]], [[X:%.*]]
173; CHECK-NEXT:    call void @use(i8 [[B]])
174; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 5
175; CHECK-NEXT:    ret i8 [[L]]
176;
177  %r = lshr i8 %y, 5
178  %b = add i8 %r, %x
179  call void @use(i8 %b)
180  %l = shl i8 %b, 5
181  ret i8 %l
182}
183
184define i8 @lshr_and_add(i8 %a, i8 %y)  {
185; CHECK-LABEL: @lshr_and_add(
186; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
187; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 3
188; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 96
189; CHECK-NEXT:    [[L:%.*]] = add i8 [[Y_MASK]], [[B1]]
190; CHECK-NEXT:    ret i8 [[L]]
191;
192  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
193  %r = lshr i8 %y, 3
194  %m = and i8 %r, 12
195  %b = add i8 %x, %m
196  %l = shl i8 %b, 3
197  ret i8 %l
198}
199
200define <2 x i8> @lshr_and_add_commute_splat(<2 x i8> %a, <2 x i8> %y)  {
201; CHECK-LABEL: @lshr_and_add_commute_splat(
202; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
203; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 3)
204; CHECK-NEXT:    [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 96)
205; CHECK-NEXT:    [[L:%.*]] = add <2 x i8> [[Y_MASK]], [[B1]]
206; CHECK-NEXT:    ret <2 x i8> [[L]]
207;
208  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
209  %r = lshr <2 x i8> %y, <i8 3, i8 3>
210  %m = and <2 x i8> %r, <i8 12, i8 12>
211  %b = add <2 x i8> %m, %x
212  %l = shl <2 x i8> %b, <i8 3, i8 3>
213  ret <2 x i8> %l
214}
215
216define i8 @lshr_and_sub(i8 %a, i8 %y)  {
217; CHECK-LABEL: @lshr_and_sub(
218; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
219; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 2
220; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 13
221; CHECK-NEXT:    [[B:%.*]] = sub nsw i8 [[X]], [[M]]
222; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 2
223; CHECK-NEXT:    ret i8 [[L]]
224;
225  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
226  %r = lshr i8 %y, 2
227  %m = and i8 %r, 13
228  %b = sub i8 %x, %m
229  %l = shl i8 %b, 2
230  ret i8 %l
231}
232
233define <2 x i8> @lshr_and_sub_commute_splat(<2 x i8> %a, <2 x i8> %y)  {
234; CHECK-LABEL: @lshr_and_sub_commute_splat(
235; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
236; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2)
237; CHECK-NEXT:    [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52)
238; CHECK-NEXT:    [[L:%.*]] = sub <2 x i8> [[Y_MASK]], [[B1]]
239; CHECK-NEXT:    ret <2 x i8> [[L]]
240;
241  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
242  %r = lshr <2 x i8> %y, <i8 2, i8 2>
243  %m = and <2 x i8> %r, <i8 13, i8 13>
244  %b = sub <2 x i8> %m, %x
245  %l = shl <2 x i8> %b, <i8 2, i8 2>
246  ret <2 x i8> %l
247}
248
249define i8 @lshr_and_and(i8 %a, i8 %y)  {
250; CHECK-LABEL: @lshr_and_and(
251; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
252; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 2
253; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
254; CHECK-NEXT:    [[L:%.*]] = and i8 [[Y_MASK]], [[B1]]
255; CHECK-NEXT:    ret i8 [[L]]
256;
257  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
258  %r = lshr i8 %y, 2
259  %m = and i8 %r, 13
260  %b = and i8 %m, %x
261  %l = shl i8 %b, 2
262  ret i8 %l
263}
264
265define <2 x i8> @lshr_and_and_commute_splat(<2 x i8> %a, <2 x i8> %y)  {
266; CHECK-LABEL: @lshr_and_and_commute_splat(
267; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
268; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2)
269; CHECK-NEXT:    [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52)
270; CHECK-NEXT:    [[L:%.*]] = and <2 x i8> [[Y_MASK]], [[B1]]
271; CHECK-NEXT:    ret <2 x i8> [[L]]
272;
273  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
274  %r = lshr <2 x i8> %y, <i8 2, i8 2>
275  %m = and <2 x i8> %r, <i8 13, i8 13>
276  %b = and <2 x i8> %x, %m
277  %l = shl <2 x i8> %b, <i8 2, i8 2>
278  ret <2 x i8> %l
279}
280
281define i8 @lshr_and_or(i8 %a, i8 %y)  {
282; CHECK-LABEL: @lshr_and_or(
283; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
284; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 2
285; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
286; CHECK-NEXT:    [[L:%.*]] = or i8 [[Y_MASK]], [[B1]]
287; CHECK-NEXT:    ret i8 [[L]]
288;
289  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
290  %r = lshr i8 %y, 2
291  %m = and i8 %r, 13
292  %b = or i8 %x, %m
293  %l = shl i8 %b, 2
294  ret i8 %l
295}
296
297define i8 @lshr_and_or_disjoint(i8 %a, i8 %y)  {
298; CHECK-LABEL: @lshr_and_or_disjoint(
299; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
300; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 2
301; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
302; CHECK-NEXT:    [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]]
303; CHECK-NEXT:    ret i8 [[L]]
304;
305  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
306  %r = lshr i8 %y, 2
307  %m = and i8 %r, 13
308  %b = or disjoint i8 %x, %m
309  %l = shl i8 %b, 2
310  ret i8 %l
311}
312
313define i8 @ashr_and_or_disjoint(i8 %a, i8 %y)  {
314; CHECK-LABEL: @ashr_and_or_disjoint(
315; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
316; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 2
317; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
318; CHECK-NEXT:    [[L:%.*]] = or disjoint i8 [[Y_MASK]], [[B1]]
319; CHECK-NEXT:    ret i8 [[L]]
320;
321  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
322  %r = ashr i8 %y, 2
323  %m = and i8 %r, 13
324  %b = or disjoint i8 %x, %m
325  %l = shl i8 %b, 2
326  ret i8 %l
327}
328
329
330define <2 x i8> @lshr_and_or_commute_splat(<2 x i8> %a, <2 x i8> %y)  {
331; CHECK-LABEL: @lshr_and_or_commute_splat(
332; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
333; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2)
334; CHECK-NEXT:    [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52)
335; CHECK-NEXT:    [[L:%.*]] = or <2 x i8> [[Y_MASK]], [[B1]]
336; CHECK-NEXT:    ret <2 x i8> [[L]]
337;
338  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
339  %r = lshr <2 x i8> %y, <i8 2, i8 2>
340  %m = and <2 x i8> %r, <i8 13, i8 13>
341  %b = or <2 x i8> %m, %x
342  %l = shl <2 x i8> %b, <i8 2, i8 2>
343  ret <2 x i8> %l
344}
345
346define i8 @lshr_and_xor(i8 %a, i8 %y)  {
347; CHECK-LABEL: @lshr_and_xor(
348; CHECK-NEXT:    [[X:%.*]] = srem i8 [[A:%.*]], 42
349; CHECK-NEXT:    [[B1:%.*]] = shl i8 [[X]], 2
350; CHECK-NEXT:    [[Y_MASK:%.*]] = and i8 [[Y:%.*]], 52
351; CHECK-NEXT:    [[L:%.*]] = xor i8 [[Y_MASK]], [[B1]]
352; CHECK-NEXT:    ret i8 [[L]]
353;
354  %x = srem i8 %a, 42 ; thwart complexity-based canonicalization
355  %r = lshr i8 %y, 2
356  %m = and i8 %r, 13
357  %b = xor i8 %m, %x
358  %l = shl i8 %b, 2
359  ret i8 %l
360}
361
362define <2 x i8> @lshr_and_xor_commute_splat(<2 x i8> %a, <2 x i8> %y)  {
363; CHECK-LABEL: @lshr_and_xor_commute_splat(
364; CHECK-NEXT:    [[X:%.*]] = srem <2 x i8> [[A:%.*]], splat (i8 42)
365; CHECK-NEXT:    [[B1:%.*]] = shl <2 x i8> [[X]], splat (i8 2)
366; CHECK-NEXT:    [[Y_MASK:%.*]] = and <2 x i8> [[Y:%.*]], splat (i8 52)
367; CHECK-NEXT:    [[L:%.*]] = xor <2 x i8> [[Y_MASK]], [[B1]]
368; CHECK-NEXT:    ret <2 x i8> [[L]]
369;
370  %x = srem <2 x i8> %a, <i8 42, i8 42> ; thwart complexity-based canonicalization
371  %r = lshr <2 x i8> %y, <i8 2, i8 2>
372  %m = and <2 x i8> %r, <i8 13, i8 13>
373  %b = xor <2 x i8> %x, %m
374  %l = shl <2 x i8> %b, <i8 2, i8 2>
375  ret <2 x i8> %l
376}
377
378define i8 @lshr_and_add_use1(i8 %x, i8 %y)  {
379; CHECK-LABEL: @lshr_and_add_use1(
380; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
381; CHECK-NEXT:    call void @use(i8 [[R]])
382; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
383; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
384; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
385; CHECK-NEXT:    ret i8 [[L]]
386;
387  %r = lshr i8 %y, 3
388  call void @use(i8 %r)
389  %m = and i8 %r, 12
390  %b = add i8 %x, %m
391  %l = shl i8 %b, 3
392  ret i8 %l
393}
394
395define i8 @lshr_and_add_use2(i8 %x, i8 %y)  {
396; CHECK-LABEL: @lshr_and_add_use2(
397; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
398; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
399; CHECK-NEXT:    call void @use(i8 [[M]])
400; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
401; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
402; CHECK-NEXT:    ret i8 [[L]]
403;
404  %r = lshr i8 %y, 3
405  %m = and i8 %r, 12
406  call void @use(i8 %m)
407  %b = add i8 %x, %m
408  %l = shl i8 %b, 3
409  ret i8 %l
410}
411
412define i8 @lshr_and_add_use3(i8 %x, i8 %y)  {
413; CHECK-LABEL: @lshr_and_add_use3(
414; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
415; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
416; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
417; CHECK-NEXT:    call void @use(i8 [[B]])
418; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
419; CHECK-NEXT:    ret i8 [[L]]
420;
421  %r = lshr i8 %y, 3
422  %m = and i8 %r, 12
423  %b = add i8 %x, %m
424  call void @use(i8 %b)
425  %l = shl i8 %b, 3
426  ret i8 %l
427}
428
429define i8 @lshr_and_add_use4(i8 %x, i8 %y)  {
430; CHECK-LABEL: @lshr_and_add_use4(
431; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
432; CHECK-NEXT:    call void @use(i8 [[R]])
433; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
434; CHECK-NEXT:    call void @use(i8 [[M]])
435; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
436; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
437; CHECK-NEXT:    ret i8 [[L]]
438;
439  %r = lshr i8 %y, 3
440  call void @use(i8 %r)
441  %m = and i8 %r, 12
442  call void @use(i8 %m)
443  %b = add i8 %x, %m
444  %l = shl i8 %b, 3
445  ret i8 %l
446}
447
448define i8 @lshr_and_add_use5(i8 %x, i8 %y)  {
449; CHECK-LABEL: @lshr_and_add_use5(
450; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
451; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
452; CHECK-NEXT:    call void @use(i8 [[M]])
453; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
454; CHECK-NEXT:    call void @use(i8 [[B]])
455; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
456; CHECK-NEXT:    ret i8 [[L]]
457;
458  %r = lshr i8 %y, 3
459  %m = and i8 %r, 12
460  call void @use(i8 %m)
461  %b = add i8 %x, %m
462  call void @use(i8 %b)
463  %l = shl i8 %b, 3
464  ret i8 %l
465}
466
467define i8 @lshr_and_add_use6(i8 %x, i8 %y)  {
468; CHECK-LABEL: @lshr_and_add_use6(
469; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[Y:%.*]], 3
470; CHECK-NEXT:    call void @use(i8 [[R]])
471; CHECK-NEXT:    [[M:%.*]] = and i8 [[R]], 12
472; CHECK-NEXT:    call void @use(i8 [[M]])
473; CHECK-NEXT:    [[B:%.*]] = add i8 [[X:%.*]], [[M]]
474; CHECK-NEXT:    [[L:%.*]] = shl i8 [[B]], 3
475; CHECK-NEXT:    ret i8 [[L]]
476;
477  %r = lshr i8 %y, 3
478  call void @use(i8 %r)
479  %m = and i8 %r, 12
480  call void @use(i8 %m)
481  %b = add i8 %x, %m
482  %l = shl i8 %b, 3
483  ret i8 %l
484}
485
486define <2 x i8> @lshr_add_shl_v2i8_undef(<2 x i8> %x, <2 x i8> %y) {
487; CHECK-LABEL: @lshr_add_shl_v2i8_undef(
488; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 undef>
489; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A]], [[X:%.*]]
490; CHECK-NEXT:    [[C:%.*]] = shl <2 x i8> [[B]], <i8 undef, i8 5>
491; CHECK-NEXT:    ret <2 x i8> [[C]]
492;
493  %a = lshr <2 x i8> %y, <i8 5, i8 undef>
494  %b = add <2 x i8> %a, %x
495  %c = shl <2 x i8> %b, <i8 undef, i8 5>
496  ret <2 x i8> %c
497}
498
499define <2 x i8> @lshr_add_shl_v2i8_nonuniform(<2 x i8> %x, <2 x i8> %y) {
500; CHECK-LABEL: @lshr_add_shl_v2i8_nonuniform(
501; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 6>
502; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A]], [[X:%.*]]
503; CHECK-NEXT:    [[C:%.*]] = shl <2 x i8> [[B]], <i8 5, i8 6>
504; CHECK-NEXT:    ret <2 x i8> [[C]]
505;
506  %a = lshr <2 x i8> %y, <i8 5, i8 6>
507  %b = add <2 x i8> %a, %x
508  %c = shl <2 x i8> %b, <i8 5, i8 6>
509  ret <2 x i8> %c
510}
511
512define i32 @lshr_add_and_shl(i32 %x, i32 %y)  {
513; CHECK-LABEL: @lshr_add_and_shl(
514; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[Y:%.*]], 5
515; CHECK-NEXT:    [[X_MASK:%.*]] = and i32 [[X:%.*]], 4064
516; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[X_MASK]], [[TMP1]]
517; CHECK-NEXT:    ret i32 [[TMP2]]
518;
519  %1 = lshr i32 %x, 5
520  %2 = and i32 %1, 127
521  %3 = add i32 %y, %2
522  %4 = shl i32 %3, 5
523  ret i32 %4
524}
525
526define <2 x i32> @lshr_add_and_shl_v2i32(<2 x i32> %x, <2 x i32> %y)  {
527; CHECK-LABEL: @lshr_add_and_shl_v2i32(
528; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], splat (i32 5)
529; CHECK-NEXT:    [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 4064)
530; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i32> [[X_MASK]], [[TMP1]]
531; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
532;
533  %1 = lshr <2 x i32> %x, <i32 5, i32 5>
534  %2 = and <2 x i32> %1, <i32 127, i32 127>
535  %3 = add <2 x i32> %y, %2
536  %4 = shl <2 x i32> %3, <i32 5, i32 5>
537  ret <2 x i32> %4
538}
539
540define <2 x i32> @lshr_add_and_shl_v2i32_undef(<2 x i32> %x, <2 x i32> %y)  {
541; CHECK-LABEL: @lshr_add_and_shl_v2i32_undef(
542; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 undef, i32 5>
543; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], splat (i32 127)
544; CHECK-NEXT:    [[TMP3:%.*]] = add <2 x i32> [[Y:%.*]], [[TMP2]]
545; CHECK-NEXT:    [[TMP4:%.*]] = shl <2 x i32> [[TMP3]], <i32 5, i32 undef>
546; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
547;
548  %1 = lshr <2 x i32> %x, <i32 undef, i32 5>
549  %2 = and <2 x i32> %1, <i32 127, i32 127>
550  %3 = add <2 x i32> %y, %2
551  %4 = shl <2 x i32> %3, <i32 5, i32 undef>
552  ret <2 x i32> %4
553}
554
555define <2 x i32> @lshr_add_and_shl_v2i32_nonuniform(<2 x i32> %x, <2 x i32> %y)  {
556; CHECK-LABEL: @lshr_add_and_shl_v2i32_nonuniform(
557; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 6>
558; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 127, i32 255>
559; CHECK-NEXT:    [[TMP3:%.*]] = add <2 x i32> [[Y:%.*]], [[TMP2]]
560; CHECK-NEXT:    [[TMP4:%.*]] = shl <2 x i32> [[TMP3]], <i32 5, i32 6>
561; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
562;
563  %1 = lshr <2 x i32> %x, <i32 5, i32 6>
564  %2 = and <2 x i32> %1, <i32 127, i32 255>
565  %3 = add <2 x i32> %y, %2
566  %4 = shl <2 x i32> %3, <i32 5, i32 6>
567  ret <2 x i32> %4
568}
569
570define i32 @shl_add_and_lshr(i32 %x, i32 %y) {
571; CHECK-LABEL: @shl_add_and_lshr(
572; CHECK-NEXT:    [[C1:%.*]] = shl i32 [[Y:%.*]], 4
573; CHECK-NEXT:    [[X_MASK:%.*]] = and i32 [[X:%.*]], 128
574; CHECK-NEXT:    [[D:%.*]] = add i32 [[X_MASK]], [[C1]]
575; CHECK-NEXT:    ret i32 [[D]]
576;
577  %a = lshr i32 %x, 4
578  %b = and i32 %a, 8
579  %c = add i32 %b, %y
580  %d = shl i32 %c, 4
581  ret i32 %d
582}
583
584define <2 x i32> @shl_add_and_lshr_v2i32(<2 x i32> %x, <2 x i32> %y) {
585; CHECK-LABEL: @shl_add_and_lshr_v2i32(
586; CHECK-NEXT:    [[C1:%.*]] = shl <2 x i32> [[Y:%.*]], splat (i32 4)
587; CHECK-NEXT:    [[X_MASK:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)
588; CHECK-NEXT:    [[D:%.*]] = add <2 x i32> [[X_MASK]], [[C1]]
589; CHECK-NEXT:    ret <2 x i32> [[D]]
590;
591  %a = lshr <2 x i32> %x, <i32 4, i32 4>
592  %b = and <2 x i32> %a, <i32 8, i32 8>
593  %c = add <2 x i32> %b, %y
594  %d = shl <2 x i32> %c, <i32 4, i32 4>
595  ret <2 x i32> %d
596}
597
598define <2 x i32> @shl_add_and_lshr_v2i32_undef(<2 x i32> %x, <2 x i32> %y) {
599; CHECK-LABEL: @shl_add_and_lshr_v2i32_undef(
600; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 undef>
601; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A]], <i32 8, i32 undef>
602; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]]
603; CHECK-NEXT:    [[D:%.*]] = shl <2 x i32> [[C]], <i32 4, i32 undef>
604; CHECK-NEXT:    ret <2 x i32> [[D]]
605;
606  %a = lshr <2 x i32> %x, <i32 4, i32 undef>
607  %b = and <2 x i32> %a, <i32 8, i32 undef>
608  %c = add <2 x i32> %b, %y
609  %d = shl <2 x i32> %c, <i32 4, i32 undef>
610  ret <2 x i32> %d
611}
612
613define <2 x i32> @shl_add_and_lshr_v2i32_nonuniform(<2 x i32> %x, <2 x i32> %y) {
614; CHECK-LABEL: @shl_add_and_lshr_v2i32_nonuniform(
615; CHECK-NEXT:    [[A:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 5>
616; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A]], <i32 8, i32 9>
617; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]]
618; CHECK-NEXT:    [[D:%.*]] = shl <2 x i32> [[C]], <i32 4, i32 5>
619; CHECK-NEXT:    ret <2 x i32> [[D]]
620;
621  %a = lshr <2 x i32> %x, <i32 4, i32 5>
622  %b = and <2 x i32> %a, <i32 8, i32 9>
623  %c = add <2 x i32> %b, %y
624  %d = shl <2 x i32> %c, <i32 4, i32 5>
625  ret <2 x i32> %d
626}
627
628define <4 x i32> @test_FoldShiftByConstant_CreateSHL(<4 x i32> %in) {
629; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL(
630; CHECK-NEXT:    [[VSHL_N:%.*]] = mul <4 x i32> [[IN:%.*]], <i32 0, i32 -32, i32 0, i32 -32>
631; CHECK-NEXT:    ret <4 x i32> [[VSHL_N]]
632;
633  %mul.i = mul <4 x i32> %in, <i32 0, i32 -1, i32 0, i32 -1>
634  %vshl_n = shl <4 x i32> %mul.i, <i32 5, i32 5, i32 5, i32 5>
635  ret <4 x i32> %vshl_n
636}
637
638define <8 x i16> @test_FoldShiftByConstant_CreateSHL2(<8 x i16> %in) {
639; CHECK-LABEL: @test_FoldShiftByConstant_CreateSHL2(
640; CHECK-NEXT:    [[VSHL_N:%.*]] = mul <8 x i16> [[IN:%.*]], <i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32, i16 0, i16 -32>
641; CHECK-NEXT:    ret <8 x i16> [[VSHL_N]]
642;
643  %mul.i = mul <8 x i16> %in, <i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1, i16 0, i16 -1>
644  %vshl_n = shl <8 x i16> %mul.i, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
645  ret <8 x i16> %vshl_n
646}
647
648define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
649; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd(
650; CHECK-NEXT:    [[VSRA_N2:%.*]] = mul <16 x i8> [[IN0:%.*]], splat (i8 33)
651; CHECK-NEXT:    [[VSHL_N:%.*]] = and <16 x i8> [[VSRA_N2]], splat (i8 -32)
652; CHECK-NEXT:    ret <16 x i8> [[VSHL_N]]
653;
654  %vsra_n = ashr <16 x i8> %in0, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
655  %tmp = add <16 x i8> %in0, %vsra_n
656  %vshl_n = shl <16 x i8> %tmp, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
657  ret <16 x i8> %vshl_n
658}
659