1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 define i8 @test0(i8 %a, i8 %b) {
6 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B:%.*]]
7 ; CHECK-NEXT: ret i8 [[SHL]]
13 define i8 @test1(i8 %a, i8 %b) {
14 ; CHECK-LABEL: @test1(
16 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 8
17 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
19 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
20 ; CHECK-NEXT: ret i8 [[SHL]]
22 ; CHECK-NEXT: ret i8 0
25 %cmp = icmp ult i8 %b, 8
26 br i1 %cmp, label %bb, label %exit
36 define i8 @test2(i8 %a, i8 %b) {
37 ; CHECK-LABEL: @test2(
39 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 9
40 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
42 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
43 ; CHECK-NEXT: ret i8 [[SHL]]
45 ; CHECK-NEXT: ret i8 0
48 %cmp = icmp ult i8 %b, 9
49 br i1 %cmp, label %bb, label %exit
59 define i8 @test3(i8 %a, i8 %b) {
60 ; CHECK-LABEL: @test3(
62 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 6
63 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
65 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]]
66 ; CHECK-NEXT: ret i8 [[SHL]]
68 ; CHECK-NEXT: ret i8 0
71 %cmp = icmp ugt i8 %b, 6
72 br i1 %cmp, label %bb, label %exit
82 define i8 @test4(i8 %a, i8 %b) {
83 ; CHECK-LABEL: @test4(
85 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 7
86 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
88 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 [[A:%.*]], [[B]]
89 ; CHECK-NEXT: ret i8 [[SHL]]
91 ; CHECK-NEXT: ret i8 0
94 %cmp = icmp ugt i8 %b, 7
95 br i1 %cmp, label %bb, label %exit
105 define i8 @test5(i8 %b) {
106 ; CHECK-LABEL: @test5(
107 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 0, [[B:%.*]]
108 ; CHECK-NEXT: ret i8 0
114 define i8 @test6(i8 %b) {
115 ; CHECK-LABEL: @test6(
116 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 1, [[B:%.*]]
117 ; CHECK-NEXT: ret i8 [[SHL]]
123 define i8 @test7(i8 %b) {
124 ; CHECK-LABEL: @test7(
126 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 7
127 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
129 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 1, [[B]]
130 ; CHECK-NEXT: ret i8 [[SHL]]
132 ; CHECK-NEXT: ret i8 0
135 %cmp = icmp ult i8 %b, 7
136 br i1 %cmp, label %bb, label %exit
146 define i8 @test8(i8 %b) {
147 ; CHECK-LABEL: @test8(
148 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[B:%.*]]
149 ; CHECK-NEXT: ret i8 [[SHL]]
155 define i8 @test9(i8 %b) {
156 ; CHECK-LABEL: @test9(
158 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B:%.*]], 0
159 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
161 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 -1, [[B]]
162 ; CHECK-NEXT: ret i8 -1
164 ; CHECK-NEXT: ret i8 0
167 %cmp = icmp eq i8 %b, 0
168 br i1 %cmp, label %bb, label %exit
178 define i8 @test10(i8 %b) {
179 ; CHECK-LABEL: @test10(
180 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B:%.*]]
181 ; CHECK-NEXT: ret i8 [[SHL]]
187 define i8 @test11(i8 %b) {
188 ; CHECK-LABEL: @test11(
190 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2
191 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
193 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 42, [[B]]
194 ; CHECK-NEXT: ret i8 [[SHL]]
196 ; CHECK-NEXT: ret i8 0
199 %cmp = icmp ult i8 %b, 2
200 br i1 %cmp, label %bb, label %exit
210 define i8 @test12(i8 %b) {
211 ; CHECK-LABEL: @test12(
213 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3
214 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
216 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 42, [[B]]
217 ; CHECK-NEXT: ret i8 [[SHL]]
219 ; CHECK-NEXT: ret i8 0
222 %cmp = icmp ult i8 %b, 3
223 br i1 %cmp, label %bb, label %exit
233 define i8 @test13(i8 %b) {
234 ; CHECK-LABEL: @test13(
236 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 4
237 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
239 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B]]
240 ; CHECK-NEXT: ret i8 [[SHL]]
242 ; CHECK-NEXT: ret i8 0
245 %cmp = icmp ult i8 %b, 4
246 br i1 %cmp, label %bb, label %exit
256 define i8 @test14(i8 %b) {
257 ; CHECK-LABEL: @test14(
258 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 -42, [[B:%.*]]
259 ; CHECK-NEXT: ret i8 [[SHL]]
261 %shl = shl i8 -42, %b
265 define i8 @test15(i8 %b) {
266 ; CHECK-LABEL: @test15(
268 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2
269 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
271 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -42, [[B]]
272 ; CHECK-NEXT: ret i8 [[SHL]]
274 ; CHECK-NEXT: ret i8 0
277 %cmp = icmp ult i8 %b, 2
278 br i1 %cmp, label %bb, label %exit
281 %shl = shl i8 -42, %b
288 define i8 @test16(i8 %b) {
289 ; CHECK-LABEL: @test16(
291 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3
292 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
294 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 -42, [[B]]
295 ; CHECK-NEXT: ret i8 [[SHL]]
297 ; CHECK-NEXT: ret i8 0
300 %cmp = icmp ult i8 %b, 3
301 br i1 %cmp, label %bb, label %exit
304 %shl = shl i8 -42, %b
311 define i8 @test17(i8 %b) {
312 ; CHECK-LABEL: @test17(
314 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 2
315 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
317 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 42, [[B]]
318 ; CHECK-NEXT: ret i8 [[SHL]]
320 ; CHECK-NEXT: ret i8 0
323 %cmp = icmp slt i8 %b, 2
324 br i1 %cmp, label %bb, label %exit
334 define i8 @test18(i8 %b) {
335 ; CHECK-LABEL: @test18(
337 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 3
338 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
340 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 42, [[B]]
341 ; CHECK-NEXT: ret i8 [[SHL]]
343 ; CHECK-NEXT: ret i8 0
346 %cmp = icmp slt i8 %b, 3
347 br i1 %cmp, label %bb, label %exit
357 define i8 @test19(i8 %b) {
358 ; CHECK-LABEL: @test19(
360 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 4
361 ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
363 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B]]
364 ; CHECK-NEXT: ret i8 [[SHL]]
366 ; CHECK-NEXT: ret i8 0
369 %cmp = icmp slt i8 %b, 4
370 br i1 %cmp, label %bb, label %exit
380 define i1 @nuw_range1(i8 %b) {
381 ; CHECK-LABEL: @nuw_range1(
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
388 %c = add nuw nsw i8 %b, 1
389 %shl = shl nuw i8 %c, 2
390 %cmp = icmp eq i8 %shl, 0
394 define i1 @nuw_range2(i8 %b) {
395 ; CHECK-LABEL: @nuw_range2(
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
402 %c = add nuw nsw i8 %b, 3
403 %shl = shl nuw i8 %c, 2
404 %cmp = icmp ult i8 %shl, 2
408 define i1 @nsw_range1(i8 %b) {
409 ; CHECK-LABEL: @nsw_range1(
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
416 %c = add nuw nsw i8 %b, -3
417 %shl = shl nsw i8 %c, 2
418 %cmp = icmp slt i8 %c, %shl
422 define 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]]
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
442 define 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
447 %shl = shl nsw i32 %x, 1
448 %smax = call i32 @llvm.smax.i32(i32 %shl, i32 200)
452 define 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]]
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)
464 define 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
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
478 define i1 @shl_nuw_nsw_test5(i32 %x) {
479 ; CHECK-LABEL: @shl_nuw_nsw_test5(
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
486 %shl = shl nuw nsw i32 768, %x
487 %add = add nuw i32 %shl, 1846
488 %cmp = icmp sgt i32 %add, 0