xref: /llvm-project/llvm/test/Transforms/InstCombine/apint-shift.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
4define i55 @test6(i55 %A) {
5; CHECK-LABEL: @test6(
6; CHECK-NEXT:    [[C:%.*]] = mul i55 [[A:%.*]], 6
7; CHECK-NEXT:    ret i55 [[C]]
8;
9  %B = shl i55 %A, 1
10  %C = mul i55 %B, 3
11  ret i55 %C
12}
13
14; (X * C2) << C1 --> X * (C2 << C1)
15
16define i55 @test6a(i55 %A) {
17; CHECK-LABEL: @test6a(
18; CHECK-NEXT:    [[C:%.*]] = mul i55 [[A:%.*]], 6
19; CHECK-NEXT:    ret i55 [[C]]
20;
21  %B = mul i55 %A, 3
22  %C = shl i55 %B, 1
23  ret i55 %C
24}
25
26declare void @use(i55 %0)
27
28define i55 @test6a_negative_oneuse(i55 %A) {
29; CHECK-LABEL: @test6a_negative_oneuse(
30; CHECK-NEXT:    [[B:%.*]] = mul i55 [[A:%.*]], 3
31; CHECK-NEXT:    [[C:%.*]] = mul i55 [[A]], 6
32; CHECK-NEXT:    call void @use(i55 [[B]])
33; CHECK-NEXT:    ret i55 [[C]]
34;
35  %B = mul i55 %A, 3
36  %C = shl i55 %B, 1
37  call void @use(i55 %B)
38  ret i55 %C
39}
40
41; (X * C2) << C1 --> X * (C2 << C1)
42
43define <2 x i55> @test6a_vec(<2 x i55> %A) {
44; CHECK-LABEL: @test6a_vec(
45; CHECK-NEXT:    [[C:%.*]] = mul <2 x i55> [[A:%.*]], <i55 6, i55 48>
46; CHECK-NEXT:    ret <2 x i55> [[C]]
47;
48  %B = mul <2 x i55> %A, <i55 3, i55 12>
49  %C = shl <2 x i55> %B, <i55 1, i55 2>
50  ret <2 x i55> %C
51}
52
53define i29 @test7(i8 %X) {
54; CHECK-LABEL: @test7(
55; CHECK-NEXT:    ret i29 -1
56;
57  %A = zext i8 %X to i29
58  %B = ashr i29 -1, %A
59  ret i29 %B
60}
61
62define i7 @test8(i7 %A) {
63; CHECK-LABEL: @test8(
64; CHECK-NEXT:    ret i7 0
65;
66  %B = shl i7 %A, 4
67  %C = shl i7 %B, 3
68  ret i7 %C
69}
70
71define i17 @test9(i17 %A) {
72; CHECK-LABEL: @test9(
73; CHECK-NEXT:    [[B:%.*]] = and i17 [[A:%.*]], 1
74; CHECK-NEXT:    ret i17 [[B]]
75;
76  %B = shl i17 %A, 16
77  %C = lshr i17 %B, 16
78  ret i17 %C
79}
80
81; shl (lshr X, C), C --> and X, C'
82
83define i19 @test10(i19 %X) {
84; CHECK-LABEL: @test10(
85; CHECK-NEXT:    [[SH1:%.*]] = and i19 [[X:%.*]], -262144
86; CHECK-NEXT:    ret i19 [[SH1]]
87;
88  %sh1 = lshr i19 %X, 18
89  %sh2 = shl i19 %sh1, 18
90  ret i19 %sh2
91}
92
93; Two right shifts in the same direction:
94; lshr (lshr X, C1), C2 --> lshr X, C1 + C2
95
96define <2 x i19> @lshr_lshr_splat_vec(<2 x i19> %X) {
97; CHECK-LABEL: @lshr_lshr_splat_vec(
98; CHECK-NEXT:    [[SH1:%.*]] = lshr <2 x i19> [[X:%.*]], splat (i19 5)
99; CHECK-NEXT:    ret <2 x i19> [[SH1]]
100;
101  %sh1 = lshr <2 x i19> %X, <i19 3, i19 3>
102  %sh2 = lshr <2 x i19> %sh1, <i19 2, i19 2>
103  ret <2 x i19> %sh2
104}
105
106define i9 @multiuse_lshr_lshr(i9 %x) {
107; CHECK-LABEL: @multiuse_lshr_lshr(
108; CHECK-NEXT:    [[SH1:%.*]] = lshr i9 [[X:%.*]], 2
109; CHECK-NEXT:    [[SH2:%.*]] = lshr i9 [[X]], 5
110; CHECK-NEXT:    [[MUL:%.*]] = mul i9 [[SH1]], [[SH2]]
111; CHECK-NEXT:    ret i9 [[MUL]]
112;
113  %sh1 = lshr i9 %x, 2
114  %sh2 = lshr i9 %sh1, 3
115  %mul = mul i9 %sh1, %sh2
116  ret i9 %mul
117}
118
119define <2 x i9> @multiuse_lshr_lshr_splat(<2 x i9> %x) {
120; CHECK-LABEL: @multiuse_lshr_lshr_splat(
121; CHECK-NEXT:    [[SH1:%.*]] = lshr <2 x i9> [[X:%.*]], splat (i9 2)
122; CHECK-NEXT:    [[SH2:%.*]] = lshr <2 x i9> [[X]], splat (i9 5)
123; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i9> [[SH1]], [[SH2]]
124; CHECK-NEXT:    ret <2 x i9> [[MUL]]
125;
126  %sh1 = lshr <2 x i9> %x, <i9 2, i9 2>
127  %sh2 = lshr <2 x i9> %sh1, <i9 3, i9 3>
128  %mul = mul <2 x i9> %sh1, %sh2
129  ret <2 x i9> %mul
130}
131
132; Two left shifts in the same direction:
133; shl (shl X, C1), C2 -->  shl X, C1 + C2
134
135define <2 x i19> @shl_shl_splat_vec(<2 x i19> %X) {
136; CHECK-LABEL: @shl_shl_splat_vec(
137; CHECK-NEXT:    [[SH1:%.*]] = shl <2 x i19> [[X:%.*]], splat (i19 5)
138; CHECK-NEXT:    ret <2 x i19> [[SH1]]
139;
140  %sh1 = shl <2 x i19> %X, <i19 3, i19 3>
141  %sh2 = shl <2 x i19> %sh1, <i19 2, i19 2>
142  ret <2 x i19> %sh2
143}
144
145define i42 @multiuse_shl_shl(i42 %x) {
146; CHECK-LABEL: @multiuse_shl_shl(
147; CHECK-NEXT:    [[SH1:%.*]] = shl i42 [[X:%.*]], 8
148; CHECK-NEXT:    [[SH2:%.*]] = shl i42 [[X]], 17
149; CHECK-NEXT:    [[MUL:%.*]] = mul i42 [[SH1]], [[SH2]]
150; CHECK-NEXT:    ret i42 [[MUL]]
151;
152  %sh1 = shl i42 %x, 8
153  %sh2 = shl i42 %sh1, 9
154  %mul = mul i42 %sh1, %sh2
155  ret i42 %mul
156}
157
158define <2 x i42> @multiuse_shl_shl_splat(<2 x i42> %x) {
159; CHECK-LABEL: @multiuse_shl_shl_splat(
160; CHECK-NEXT:    [[SH1:%.*]] = shl <2 x i42> [[X:%.*]], splat (i42 8)
161; CHECK-NEXT:    [[SH2:%.*]] = shl <2 x i42> [[X]], splat (i42 17)
162; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i42> [[SH1]], [[SH2]]
163; CHECK-NEXT:    ret <2 x i42> [[MUL]]
164;
165  %sh1 = shl <2 x i42> %x, <i42 8, i42 8>
166  %sh2 = shl <2 x i42> %sh1, <i42 9, i42 9>
167  %mul = mul <2 x i42> %sh1, %sh2
168  ret <2 x i42> %mul
169}
170
171; Equal shift amounts in opposite directions become bitwise 'and':
172; lshr (shl X, C), C --> and X, C'
173
174define <2 x i19> @eq_shl_lshr_splat_vec(<2 x i19> %X) {
175; CHECK-LABEL: @eq_shl_lshr_splat_vec(
176; CHECK-NEXT:    [[SH1:%.*]] = and <2 x i19> [[X:%.*]], splat (i19 65535)
177; CHECK-NEXT:    ret <2 x i19> [[SH1]]
178;
179  %sh1 = shl <2 x i19> %X, <i19 3, i19 3>
180  %sh2 = lshr <2 x i19> %sh1, <i19 3, i19 3>
181  ret <2 x i19> %sh2
182}
183
184; Equal shift amounts in opposite directions become bitwise 'and':
185; shl (lshr X, C), C --> and X, C'
186
187define <2 x i19> @eq_lshr_shl_splat_vec(<2 x i19> %X) {
188; CHECK-LABEL: @eq_lshr_shl_splat_vec(
189; CHECK-NEXT:    [[SH1:%.*]] = and <2 x i19> [[X:%.*]], splat (i19 -8)
190; CHECK-NEXT:    ret <2 x i19> [[SH1]]
191;
192  %sh1 = lshr <2 x i19> %X, <i19 3, i19 3>
193  %sh2 = shl <2 x i19> %sh1, <i19 3, i19 3>
194  ret <2 x i19> %sh2
195}
196
197; In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
198; shl (lshr X, C1), C2 --> lshr X, C1 - C2
199
200define <2 x i7> @lshr_shl_splat_vec(<2 x i7> %X) {
201; CHECK-LABEL: @lshr_shl_splat_vec(
202; CHECK-NEXT:    [[DOTNEG:%.*]] = mul <2 x i7> [[X:%.*]], splat (i7 60)
203; CHECK-NEXT:    [[SH2:%.*]] = and <2 x i7> [[DOTNEG]], splat (i7 60)
204; CHECK-NEXT:    ret <2 x i7> [[SH2]]
205;
206  %mul = mul <2 x i7> %X, <i7 -8, i7 -8>
207  %sh1 = lshr exact <2 x i7> %mul, <i7 3, i7 3>
208  %sh2 = shl nuw nsw <2 x i7> %sh1, <i7 2, i7 2>
209  ret <2 x i7> %sh2
210}
211
212; In general, we would need an 'and' for this transform, but the masked-off bits are known zero.
213; lshr (shl X, C1), C2 -->  shl X, C1 - C2
214
215define <2 x i7> @shl_lshr_splat_vec(<2 x i7> %X) {
216; CHECK-LABEL: @shl_lshr_splat_vec(
217; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i7> [[X:%.*]], splat (i7 9)
218; CHECK-NEXT:    [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], splat (i7 1)
219; CHECK-NEXT:    ret <2 x i7> [[SH1]]
220;
221  %div = udiv <2 x i7> %X, <i7 9, i7 9>
222  %sh1 = shl nuw <2 x i7> %div, <i7 3, i7 3>
223  %sh2 = lshr exact <2 x i7> %sh1, <i7 2, i7 2>
224  ret <2 x i7> %sh2
225}
226
227define i23 @test11(i23 %x) {
228; CHECK-LABEL: @test11(
229; CHECK-NEXT:    [[TMP1:%.*]] = mul i23 [[X:%.*]], 6
230; CHECK-NEXT:    [[C:%.*]] = and i23 [[TMP1]], -4096
231; CHECK-NEXT:    ret i23 [[C]]
232;
233  %a = mul i23 %x, 3
234  %b = lshr i23 %a, 11
235  %c = shl i23 %b, 12
236  ret i23 %c
237}
238
239; shl (ashr X, C), C --> and X, C'
240
241define i47 @test12(i47 %X) {
242; CHECK-LABEL: @test12(
243; CHECK-NEXT:    [[SH1:%.*]] = and i47 [[X:%.*]], -256
244; CHECK-NEXT:    ret i47 [[SH1]]
245;
246  %sh1 = ashr i47 %X, 8
247  %sh2 = shl i47 %sh1, 8
248  ret i47 %sh2
249}
250
251define <2 x i47> @test12_splat_vec(<2 x i47> %X) {
252; CHECK-LABEL: @test12_splat_vec(
253; CHECK-NEXT:    [[SH1:%.*]] = and <2 x i47> [[X:%.*]], splat (i47 -256)
254; CHECK-NEXT:    ret <2 x i47> [[SH1]]
255;
256  %sh1 = ashr <2 x i47> %X, <i47 8, i47 8>
257  %sh2 = shl <2 x i47> %sh1, <i47 8, i47 8>
258  ret <2 x i47> %sh2
259}
260
261define i18 @test13(i18 %x) {
262; CHECK-LABEL: @test13(
263; CHECK-NEXT:    [[TMP1:%.*]] = mul i18 [[X:%.*]], 6
264; CHECK-NEXT:    [[C:%.*]] = and i18 [[TMP1]], -512
265; CHECK-NEXT:    ret i18 [[C]]
266;
267  %a = mul i18 %x, 3
268  %b = ashr i18 %a, 8
269  %c = shl i18 %b, 9
270  ret i18 %c
271}
272
273define i35 @test14(i35 %A) {
274; CHECK-LABEL: @test14(
275; CHECK-NEXT:    [[B:%.*]] = and i35 [[A:%.*]], -19760
276; CHECK-NEXT:    [[C:%.*]] = or disjoint i35 [[B]], 19744
277; CHECK-NEXT:    ret i35 [[C]]
278;
279  %B = lshr i35 %A, 4
280  %C = or i35 %B, 1234
281  %D = shl i35 %C, 4
282  ret i35 %D
283}
284
285define i79 @test14a(i79 %A) {
286; CHECK-LABEL: @test14a(
287; CHECK-NEXT:    [[C:%.*]] = and i79 [[A:%.*]], 77
288; CHECK-NEXT:    ret i79 [[C]]
289;
290  %B = shl i79 %A, 4
291  %C = and i79 %B, 1234
292  %D = lshr i79 %C, 4
293  ret i79 %D
294}
295
296define i45 @test15(i1 %C) {
297; CHECK-LABEL: @test15(
298; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], i45 12, i45 4
299; CHECK-NEXT:    ret i45 [[A]]
300;
301  %A = select i1 %C, i45 3, i45 1
302  %V = shl i45 %A, 2
303  ret i45 %V
304}
305
306define i53 @test15a(i1 %X) {
307; CHECK-LABEL: @test15a(
308; CHECK-NEXT:    [[V:%.*]] = select i1 [[X:%.*]], i53 512, i53 128
309; CHECK-NEXT:    ret i53 [[V]]
310;
311  %A = select i1 %X, i8 3, i8 1
312  %B = zext i8 %A to i53
313  %V = shl i53 64, %B
314  ret i53 %V
315}
316
317define i1 @test16(i84 %X) {
318; CHECK-LABEL: @test16(
319; CHECK-NEXT:    [[TMP1:%.*]] = and i84 [[X:%.*]], 16
320; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i84 [[TMP1]], 0
321; CHECK-NEXT:    ret i1 [[CMP]]
322;
323  %shr = ashr i84 %X, 4
324  %and = and i84 %shr, 1
325  %cmp = icmp ne i84 %and, 0
326  ret i1 %cmp
327}
328
329define <2 x i1> @test16vec(<2 x i84> %X) {
330; CHECK-LABEL: @test16vec(
331; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], splat (i84 16)
332; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer
333; CHECK-NEXT:    ret <2 x i1> [[CMP]]
334;
335  %shr = ashr <2 x i84> %X, <i84 4, i84 4>
336  %and = and <2 x i84> %shr, <i84 1, i84 1>
337  %cmp = icmp ne <2 x i84> %and, zeroinitializer
338  ret <2 x i1> %cmp
339}
340
341define <2 x i1> @test16vec_nonuniform(<2 x i84> %X) {
342; CHECK-LABEL: @test16vec_nonuniform(
343; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], <i84 16, i84 4>
344; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer
345; CHECK-NEXT:    ret <2 x i1> [[CMP]]
346;
347  %shr = ashr <2 x i84> %X, <i84 4, i84 2>
348  %and = and <2 x i84> %shr, <i84 1, i84 1>
349  %cmp = icmp ne <2 x i84> %and, zeroinitializer
350  ret <2 x i1> %cmp
351}
352
353define <2 x i1> @test16vec_undef(<2 x i84> %X) {
354; CHECK-LABEL: @test16vec_undef(
355; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i84> [[X:%.*]], <i84 16, i84 poison>
356; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i84> [[TMP1]], zeroinitializer
357; CHECK-NEXT:    ret <2 x i1> [[CMP]]
358;
359  %shr = ashr <2 x i84> %X, <i84 4, i84 undef>
360  %and = and <2 x i84> %shr, <i84 1, i84 1>
361  %cmp = icmp ne <2 x i84> %and, zeroinitializer
362  ret <2 x i1> %cmp
363}
364
365define i1 @test17(i106 %A) {
366; CHECK-LABEL: @test17(
367; CHECK-NEXT:    [[B_MASK:%.*]] = and i106 [[A:%.*]], -8
368; CHECK-NEXT:    [[C:%.*]] = icmp eq i106 [[B_MASK]], 9872
369; CHECK-NEXT:    ret i1 [[C]]
370;
371  %B = lshr i106 %A, 3
372  %C = icmp eq i106 %B, 1234
373  ret i1 %C
374}
375
376define <2 x i1> @test17vec(<2 x i106> %A) {
377; CHECK-LABEL: @test17vec(
378; CHECK-NEXT:    [[B_MASK:%.*]] = and <2 x i106> [[A:%.*]], splat (i106 -8)
379; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i106> [[B_MASK]], splat (i106 9872)
380; CHECK-NEXT:    ret <2 x i1> [[C]]
381;
382  %B = lshr <2 x i106> %A, <i106 3, i106 3>
383  %C = icmp eq <2 x i106> %B, <i106 1234, i106 1234>
384  ret <2 x i1> %C
385}
386
387define i1 @test18(i11 %A) {
388; CHECK-LABEL: @test18(
389; CHECK-NEXT:    ret i1 false
390;
391  %B = lshr i11 %A, 10
392  %C = icmp eq i11 %B, 123
393  ret i1 %C
394}
395
396define i1 @test19(i37 %A) {
397; CHECK-LABEL: @test19(
398; CHECK-NEXT:    [[C:%.*]] = icmp ult i37 [[A:%.*]], 4
399; CHECK-NEXT:    ret i1 [[C]]
400;
401  %B = ashr i37 %A, 2
402  %C = icmp eq i37 %B, 0
403  ret i1 %C
404}
405
406define <2 x i1> @test19vec(<2 x i37> %A) {
407; CHECK-LABEL: @test19vec(
408; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i37> [[A:%.*]], splat (i37 4)
409; CHECK-NEXT:    ret <2 x i1> [[C]]
410;
411  %B = ashr <2 x i37> %A, <i37 2, i37 2>
412  %C = icmp eq <2 x i37> %B, zeroinitializer
413  ret <2 x i1> %C
414}
415
416define i1 @test19a(i39 %A) {
417; CHECK-LABEL: @test19a(
418; CHECK-NEXT:    [[C:%.*]] = icmp ugt i39 [[A:%.*]], -5
419; CHECK-NEXT:    ret i1 [[C]]
420;
421  %B = ashr i39 %A, 2
422  %C = icmp eq i39 %B, -1
423  ret i1 %C
424}
425
426define <2 x i1> @test19a_vec(<2 x i39> %A) {
427; CHECK-LABEL: @test19a_vec(
428; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i39> [[A:%.*]], splat (i39 -5)
429; CHECK-NEXT:    ret <2 x i1> [[C]]
430;
431  %B = ashr <2 x i39> %A, <i39 2, i39 2>
432  %C = icmp eq <2 x i39> %B, <i39 -1, i39 -1>
433  ret <2 x i1> %C
434}
435
436define i1 @test20(i13 %A) {
437; CHECK-LABEL: @test20(
438; CHECK-NEXT:    ret i1 false
439;
440  %B = ashr i13 %A, 12
441  %C = icmp eq i13 %B, 123
442  ret i1 %C
443}
444
445define i1 @test21(i12 %A) {
446; CHECK-LABEL: @test21(
447; CHECK-NEXT:    [[B_MASK:%.*]] = and i12 [[A:%.*]], 63
448; CHECK-NEXT:    [[C:%.*]] = icmp eq i12 [[B_MASK]], 62
449; CHECK-NEXT:    ret i1 [[C]]
450;
451  %B = shl i12 %A, 6
452  %C = icmp eq i12 %B, -128
453  ret i1 %C
454}
455
456define i1 @test22(i14 %A) {
457; CHECK-LABEL: @test22(
458; CHECK-NEXT:    [[B_MASK:%.*]] = and i14 [[A:%.*]], 127
459; CHECK-NEXT:    [[C:%.*]] = icmp eq i14 [[B_MASK]], 0
460; CHECK-NEXT:    ret i1 [[C]]
461;
462  %B = shl i14 %A, 7
463  %C = icmp eq i14 %B, 0
464  ret i1 %C
465}
466
467define i11 @test23(i44 %A) {
468; CHECK-LABEL: @test23(
469; CHECK-NEXT:    [[D:%.*]] = trunc i44 [[A:%.*]] to i11
470; CHECK-NEXT:    ret i11 [[D]]
471;
472  %B = shl i44 %A, 33
473  %C = ashr i44 %B, 33
474  %D = trunc i44 %C to i11
475  ret i11 %D
476}
477
478; Fold lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
479
480define i44 @shl_lshr_eq_amt_multi_use(i44 %A) {
481; CHECK-LABEL: @shl_lshr_eq_amt_multi_use(
482; CHECK-NEXT:    [[B:%.*]] = shl i44 [[A:%.*]], 33
483; CHECK-NEXT:    [[C:%.*]] = and i44 [[A]], 2047
484; CHECK-NEXT:    [[D:%.*]] = or disjoint i44 [[B]], [[C]]
485; CHECK-NEXT:    ret i44 [[D]]
486;
487  %B = shl i44 %A, 33
488  %C = lshr i44 %B, 33
489  %D = add i44 %B, %C
490  ret i44 %D
491}
492
493; Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
494
495define <2 x i44> @shl_lshr_eq_amt_multi_use_splat_vec(<2 x i44> %A) {
496; CHECK-LABEL: @shl_lshr_eq_amt_multi_use_splat_vec(
497; CHECK-NEXT:    [[B:%.*]] = shl <2 x i44> [[A:%.*]], splat (i44 33)
498; CHECK-NEXT:    [[C:%.*]] = and <2 x i44> [[A]], splat (i44 2047)
499; CHECK-NEXT:    [[D:%.*]] = or disjoint <2 x i44> [[B]], [[C]]
500; CHECK-NEXT:    ret <2 x i44> [[D]]
501;
502  %B = shl <2 x i44> %A, <i44 33, i44 33>
503  %C = lshr <2 x i44> %B, <i44 33, i44 33>
504  %D = add <2 x i44> %B, %C
505  ret <2 x i44> %D
506}
507
508; Fold shl (lshr X, C), C -> and X, C' regardless of the number of uses of the lshr.
509
510define i43 @lshr_shl_eq_amt_multi_use(i43 %A) {
511; CHECK-LABEL: @lshr_shl_eq_amt_multi_use(
512; CHECK-NEXT:    [[B:%.*]] = lshr i43 [[A:%.*]], 23
513; CHECK-NEXT:    [[C:%.*]] = and i43 [[A]], -8388608
514; CHECK-NEXT:    [[D:%.*]] = mul i43 [[B]], [[C]]
515; CHECK-NEXT:    ret i43 [[D]]
516;
517  %B = lshr i43 %A, 23
518  %C = shl i43 %B, 23
519  %D = mul i43 %B, %C
520  ret i43 %D
521}
522
523; Fold vector shl (lshr X, C), C -> and X, C' regardless of the number of uses of the lshr.
524
525define <2 x i43> @lshr_shl_eq_amt_multi_use_splat_vec(<2 x i43> %A) {
526; CHECK-LABEL: @lshr_shl_eq_amt_multi_use_splat_vec(
527; CHECK-NEXT:    [[B:%.*]] = lshr <2 x i43> [[A:%.*]], splat (i43 23)
528; CHECK-NEXT:    [[C:%.*]] = and <2 x i43> [[A]], splat (i43 -8388608)
529; CHECK-NEXT:    [[D:%.*]] = mul <2 x i43> [[B]], [[C]]
530; CHECK-NEXT:    ret <2 x i43> [[D]]
531;
532  %B = lshr <2 x i43> %A, <i43 23, i43 23>
533  %C = shl <2 x i43> %B, <i43 23, i43 23>
534  %D = mul <2 x i43> %B, %C
535  ret <2 x i43> %D
536}
537
538define i37 @test25(i37 %AA, i37 %BB) {
539; CHECK-LABEL: @test25(
540; CHECK-NEXT:    [[D:%.*]] = and i37 [[AA:%.*]], -131072
541; CHECK-NEXT:    [[C2:%.*]] = add i37 [[BB:%.*]], [[D]]
542; CHECK-NEXT:    [[F:%.*]] = and i37 [[C2]], -131072
543; CHECK-NEXT:    ret i37 [[F]]
544;
545  %C = lshr i37 %BB, 17
546  %D = lshr i37 %AA, 17
547  %E = add i37 %D, %C
548  %F = shl i37 %E, 17
549  ret i37 %F
550}
551
552define i40 @test26(i40 %A) {
553; CHECK-LABEL: @test26(
554; CHECK-NEXT:    [[B:%.*]] = and i40 [[A:%.*]], -2
555; CHECK-NEXT:    ret i40 [[B]]
556;
557  %B = lshr i40 %A, 1
558  %C = bitcast i40 %B to i40
559  %D = shl i40 %C, 1
560  ret i40 %D
561}
562
563; OSS-Fuzz #9880
564; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9880
565define i177 @ossfuzz_9880(i177 %X) {
566; CHECK-LABEL: @ossfuzz_9880(
567; CHECK-NEXT:    ret i177 0
568;
569  %A = alloca i177
570  %L1 = load i177, ptr %A
571  %B = or i177 0, -1
572  %B5 = udiv i177 %L1, %B
573  %B4 = add i177 %B5, %B
574  %B2 = add i177 %B, %B4
575  %B6 = mul i177 %B5, %B2
576  %B20 = shl i177 %L1, %B6
577  %B14 = sub i177 %B20, %B5
578  %B1 = udiv i177 %B14, %B6
579  ret i177 %B1
580}
581