xref: /llvm-project/llvm/test/Transforms/CorrelatedValuePropagation/shl.ll (revision 07b29fc808ca0842d02cf4e973381b974bfdf19f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3
4define i8 @test0(i8 %a, i8 %b) {
5; CHECK-LABEL: @test0(
6; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[A:%.*]], [[B:%.*]]
7; CHECK-NEXT:    ret i8 [[SHL]]
8;
9  %shl = shl i8 %a, %b
10  ret i8 %shl
11}
12
13define i8 @test1(i8 %a, i8 %b) {
14; CHECK-LABEL: @test1(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 8
17; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
18; CHECK:       bb:
19; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
20; CHECK-NEXT:    ret i8 [[SHL]]
21; CHECK:       exit:
22; CHECK-NEXT:    ret i8 0
23;
24entry:
25  %cmp = icmp ult i8 %b, 8
26  br i1 %cmp, label %bb, label %exit
27
28bb:
29  %shl = shl i8 %a, %b
30  ret i8 %shl
31
32exit:
33  ret i8 0
34}
35
36define i8 @test2(i8 %a, i8 %b) {
37; CHECK-LABEL: @test2(
38; CHECK-NEXT:  entry:
39; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 9
40; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
41; CHECK:       bb:
42; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
43; CHECK-NEXT:    ret i8 [[SHL]]
44; CHECK:       exit:
45; CHECK-NEXT:    ret i8 0
46;
47entry:
48  %cmp = icmp ult i8 %b, 9
49  br i1 %cmp, label %bb, label %exit
50
51bb:
52  %shl = shl i8 %a, %b
53  ret i8 %shl
54
55exit:
56  ret i8 0
57}
58
59define i8 @test3(i8 %a, i8 %b) {
60; CHECK-LABEL: @test3(
61; CHECK-NEXT:  entry:
62; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 6
63; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
64; CHECK:       bb:
65; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
66; CHECK-NEXT:    ret i8 [[SHL]]
67; CHECK:       exit:
68; CHECK-NEXT:    ret i8 0
69;
70entry:
71  %cmp = icmp ugt i8 %b, 6
72  br i1 %cmp, label %bb, label %exit
73
74bb:
75  %shl = shl i8 %a, %b
76  ret i8 %shl
77
78exit:
79  ret i8 0
80}
81
82define i8 @test4(i8 %a, i8 %b) {
83; CHECK-LABEL: @test4(
84; CHECK-NEXT:  entry:
85; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 7
86; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
87; CHECK:       bb:
88; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 [[A:%.*]], [[B]]
89; CHECK-NEXT:    ret i8 [[SHL]]
90; CHECK:       exit:
91; CHECK-NEXT:    ret i8 0
92;
93entry:
94  %cmp = icmp ugt i8 %b, 7
95  br i1 %cmp, label %bb, label %exit
96
97bb:
98  %shl = shl i8 %a, %b
99  ret i8 %shl
100
101exit:
102  ret i8 0
103}
104
105define i8 @test5(i8 %b) {
106; CHECK-LABEL: @test5(
107; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 0, [[B:%.*]]
108; CHECK-NEXT:    ret i8 0
109;
110  %shl = shl i8 0, %b
111  ret i8 %shl
112}
113
114define i8 @test6(i8 %b) {
115; CHECK-LABEL: @test6(
116; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 1, [[B:%.*]]
117; CHECK-NEXT:    ret i8 [[SHL]]
118;
119  %shl = shl i8 1, %b
120  ret i8 %shl
121}
122
123define i8 @test7(i8 %b) {
124; CHECK-LABEL: @test7(
125; CHECK-NEXT:  entry:
126; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 7
127; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
128; CHECK:       bb:
129; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 1, [[B]]
130; CHECK-NEXT:    ret i8 [[SHL]]
131; CHECK:       exit:
132; CHECK-NEXT:    ret i8 0
133;
134entry:
135  %cmp = icmp ult i8 %b, 7
136  br i1 %cmp, label %bb, label %exit
137
138bb:
139  %shl = shl i8 1, %b
140  ret i8 %shl
141
142exit:
143  ret i8 0
144}
145
146define i8 @test8(i8 %b) {
147; CHECK-LABEL: @test8(
148; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i8 -1, [[B:%.*]]
149; CHECK-NEXT:    ret i8 [[SHL]]
150;
151  %shl = shl i8 -1, %b
152  ret i8 %shl
153}
154
155define i8 @test9(i8 %b) {
156; CHECK-LABEL: @test9(
157; CHECK-NEXT:  entry:
158; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[B:%.*]], 0
159; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
160; CHECK:       bb:
161; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 -1, [[B]]
162; CHECK-NEXT:    ret i8 -1
163; CHECK:       exit:
164; CHECK-NEXT:    ret i8 0
165;
166entry:
167  %cmp = icmp eq i8 %b, 0
168  br i1 %cmp, label %bb, label %exit
169
170bb:
171  %shl = shl i8 -1, %b
172  ret i8 %shl
173
174exit:
175  ret i8 0
176}
177
178define i8 @test10(i8 %b) {
179; CHECK-LABEL: @test10(
180; CHECK-NEXT:    [[SHL:%.*]] = shl i8 42, [[B:%.*]]
181; CHECK-NEXT:    ret i8 [[SHL]]
182;
183  %shl = shl i8 42, %b
184  ret i8 %shl
185}
186
187define i8 @test11(i8 %b) {
188; CHECK-LABEL: @test11(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2
191; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
192; CHECK:       bb:
193; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 42, [[B]]
194; CHECK-NEXT:    ret i8 [[SHL]]
195; CHECK:       exit:
196; CHECK-NEXT:    ret i8 0
197;
198entry:
199  %cmp = icmp ult i8 %b, 2
200  br i1 %cmp, label %bb, label %exit
201
202bb:
203  %shl = shl i8 42, %b
204  ret i8 %shl
205
206exit:
207  ret i8 0
208}
209
210define i8 @test12(i8 %b) {
211; CHECK-LABEL: @test12(
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3
214; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
215; CHECK:       bb:
216; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 42, [[B]]
217; CHECK-NEXT:    ret i8 [[SHL]]
218; CHECK:       exit:
219; CHECK-NEXT:    ret i8 0
220;
221entry:
222  %cmp = icmp ult i8 %b, 3
223  br i1 %cmp, label %bb, label %exit
224
225bb:
226  %shl = shl i8 42, %b
227  ret i8 %shl
228
229exit:
230  ret i8 0
231}
232
233define i8 @test13(i8 %b) {
234; CHECK-LABEL: @test13(
235; CHECK-NEXT:  entry:
236; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 4
237; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
238; CHECK:       bb:
239; CHECK-NEXT:    [[SHL:%.*]] = shl i8 42, [[B]]
240; CHECK-NEXT:    ret i8 [[SHL]]
241; CHECK:       exit:
242; CHECK-NEXT:    ret i8 0
243;
244entry:
245  %cmp = icmp ult i8 %b, 4
246  br i1 %cmp, label %bb, label %exit
247
248bb:
249  %shl = shl i8 42, %b
250  ret i8 %shl
251
252exit:
253  ret i8 0
254}
255
256define i8 @test14(i8 %b) {
257; CHECK-LABEL: @test14(
258; CHECK-NEXT:    [[SHL:%.*]] = shl i8 -42, [[B:%.*]]
259; CHECK-NEXT:    ret i8 [[SHL]]
260;
261  %shl = shl i8 -42, %b
262  ret i8 %shl
263}
264
265define i8 @test15(i8 %b) {
266; CHECK-LABEL: @test15(
267; CHECK-NEXT:  entry:
268; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2
269; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
270; CHECK:       bb:
271; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i8 -42, [[B]]
272; CHECK-NEXT:    ret i8 [[SHL]]
273; CHECK:       exit:
274; CHECK-NEXT:    ret i8 0
275;
276entry:
277  %cmp = icmp ult i8 %b, 2
278  br i1 %cmp, label %bb, label %exit
279
280bb:
281  %shl = shl i8 -42, %b
282  ret i8 %shl
283
284exit:
285  ret i8 0
286}
287
288define i8 @test16(i8 %b) {
289; CHECK-LABEL: @test16(
290; CHECK-NEXT:  entry:
291; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3
292; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
293; CHECK:       bb:
294; CHECK-NEXT:    [[SHL:%.*]] = shl i8 -42, [[B]]
295; CHECK-NEXT:    ret i8 [[SHL]]
296; CHECK:       exit:
297; CHECK-NEXT:    ret i8 0
298;
299entry:
300  %cmp = icmp ult i8 %b, 3
301  br i1 %cmp, label %bb, label %exit
302
303bb:
304  %shl = shl i8 -42, %b
305  ret i8 %shl
306
307exit:
308  ret i8 0
309}
310
311define i8 @test17(i8 %b) {
312; CHECK-LABEL: @test17(
313; CHECK-NEXT:  entry:
314; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 2
315; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
316; CHECK:       bb:
317; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i8 42, [[B]]
318; CHECK-NEXT:    ret i8 [[SHL]]
319; CHECK:       exit:
320; CHECK-NEXT:    ret i8 0
321;
322entry:
323  %cmp = icmp slt i8 %b, 2
324  br i1 %cmp, label %bb, label %exit
325
326bb:
327  %shl = shl i8 42, %b
328  ret i8 %shl
329
330exit:
331  ret i8 0
332}
333
334define i8 @test18(i8 %b) {
335; CHECK-LABEL: @test18(
336; CHECK-NEXT:  entry:
337; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 3
338; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
339; CHECK:       bb:
340; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 42, [[B]]
341; CHECK-NEXT:    ret i8 [[SHL]]
342; CHECK:       exit:
343; CHECK-NEXT:    ret i8 0
344;
345entry:
346  %cmp = icmp slt i8 %b, 3
347  br i1 %cmp, label %bb, label %exit
348
349bb:
350  %shl = shl i8 42, %b
351  ret i8 %shl
352
353exit:
354  ret i8 0
355}
356
357define i8 @test19(i8 %b) {
358; CHECK-LABEL: @test19(
359; CHECK-NEXT:  entry:
360; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 4
361; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
362; CHECK:       bb:
363; CHECK-NEXT:    [[SHL:%.*]] = shl i8 42, [[B]]
364; CHECK-NEXT:    ret i8 [[SHL]]
365; CHECK:       exit:
366; CHECK-NEXT:    ret i8 0
367;
368entry:
369  %cmp = icmp slt i8 %b, 4
370  br i1 %cmp, label %bb, label %exit
371
372bb:
373  %shl = shl i8 42, %b
374  ret i8 %shl
375
376exit:
377  ret i8 0
378}
379
380define i1 @nuw_range1(i8 %b) {
381; CHECK-LABEL: @nuw_range1(
382; CHECK-NEXT:  entry:
383; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 1
384; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[C]], 2
385; CHECK-NEXT:    ret i1 false
386;
387entry:
388  %c = add nuw nsw i8 %b, 1
389  %shl = shl nuw i8 %c, 2
390  %cmp = icmp eq i8 %shl, 0
391  ret i1 %cmp
392}
393
394define i1 @nuw_range2(i8 %b) {
395; CHECK-LABEL: @nuw_range2(
396; CHECK-NEXT:  entry:
397; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 3
398; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[C]], 2
399; CHECK-NEXT:    ret i1 false
400;
401entry:
402  %c = add nuw nsw i8 %b, 3
403  %shl = shl nuw i8 %c, 2
404  %cmp = icmp ult i8 %shl, 2
405  ret i1 %cmp
406}
407
408define i1 @nsw_range1(i8 %b) {
409; CHECK-LABEL: @nsw_range1(
410; CHECK-NEXT:  entry:
411; CHECK-NEXT:    [[C:%.*]] = add nuw nsw i8 [[B:%.*]], -3
412; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i8 [[C]], 2
413; CHECK-NEXT:    ret i1 false
414;
415entry:
416  %c = add nuw nsw i8 %b, -3
417  %shl = shl nsw i8 %c, 2
418  %cmp = icmp slt i8 %c, %shl
419  ret i1 %cmp
420}
421
422define i64 @shl_nuw_nsw_test1(i32 %x) {
423; CHECK-LABEL: @shl_nuw_nsw_test1(
424; CHECK-NEXT:    [[SHL1:%.*]] = shl nuw nsw i32 1, [[X:%.*]]
425; CHECK-NEXT:    [[ADD1:%.*]] = add nsw i32 [[SHL1]], -1
426; CHECK-NEXT:    [[EXT:%.*]] = zext nneg i32 [[ADD1]] to i64
427; CHECK-NEXT:    [[SHL2:%.*]] = shl nuw nsw i64 [[EXT]], 2
428; CHECK-NEXT:    [[ADD2:%.*]] = add nuw nsw i64 [[SHL2]], 39
429; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 [[ADD2]], 3
430; CHECK-NEXT:    ret i64 [[LSHR]]
431;
432  %shl1 = shl nuw nsw i32 1, %x
433  %add1 = add nsw i32 %shl1, -1
434  %ext = sext i32 %add1 to i64
435  %shl2 = shl nsw i64 %ext, 2
436  %add2 = add nsw i64 %shl2, 39
437  %lshr = lshr i64 %add2, 3
438  %and = and i64 %lshr, 4294967295
439  ret i64 %and
440}
441
442define i32 @shl_nuw_nsw_test2(i32 range(i32 -2147483248, 1) %x) {
443; CHECK-LABEL: @shl_nuw_nsw_test2(
444; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i32 [[X:%.*]], 1
445; CHECK-NEXT:    ret i32 200
446;
447  %shl = shl nsw i32 %x, 1
448  %smax = call i32 @llvm.smax.i32(i32 %shl, i32 200)
449  ret i32 %smax
450}
451
452define i64 @shl_nuw_nsw_test3(i1 %cond, i64 range(i64 1, 0) %x, i64 range(i64 3, 0) %y) {
453; CHECK-LABEL: @shl_nuw_nsw_test3(
454; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i64 1, [[X:%.*]]
455; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i64 [[Y:%.*]], i64 [[SHL]]
456; CHECK-NEXT:    ret i64 [[SEL]]
457;
458  %shl = shl nuw i64 1, %x
459  %sel = select i1 %cond, i64 %y, i64 %shl
460  %umax = call i64 @llvm.umax.i64(i64 %sel, i64 2)
461  ret i64 %umax
462}
463
464define i1 @shl_nuw_nsw_test4(i32 %x, i32 range(i32 0, 32) %k) {
465; CHECK-LABEL: @shl_nuw_nsw_test4(
466; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[X:%.*]] to i64
467; CHECK-NEXT:    [[SH_PROM:%.*]] = zext nneg i32 [[K:%.*]] to i64
468; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i64 [[CONV]], [[SH_PROM]]
469; CHECK-NEXT:    ret i1 false
470;
471  %conv = sext i32 %x to i64
472  %sh_prom = zext nneg i32 %k to i64
473  %shl = shl nsw i64 %conv, %sh_prom
474  %cmp = icmp eq i64 %shl, -9223372036854775808
475  ret i1 %cmp
476}
477
478define i1 @shl_nuw_nsw_test5(i32 %x) {
479; CHECK-LABEL: @shl_nuw_nsw_test5(
480; CHECK-NEXT:  entry:
481; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i32 768, [[X:%.*]]
482; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[SHL]], 1846
483; CHECK-NEXT:    ret i1 true
484;
485entry:
486  %shl = shl nuw nsw i32 768, %x
487  %add = add nuw i32 %shl, 1846
488  %cmp = icmp sgt i32 %add, 0
489  ret i1 %cmp
490}
491