1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=indvars < %s | FileCheck %s 3 4; We must NOT replace check against IV with check against invariant 0. It should fail. 5define i32 @test_01() { 6; CHECK-LABEL: @test_01( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: br label [[OUTER_LOOP:%.*]] 9; CHECK: outer.loop: 10; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] 11; CHECK-NEXT: [[CHECK_1:%.*]] = icmp ult i32 [[IV]], 2 12; CHECK-NEXT: br label [[INNER_LOOP:%.*]] 13; CHECK: inner.loop: 14; CHECK-NEXT: [[STOREMERGE611_I:%.*]] = phi i64 [ 0, [[OUTER_LOOP]] ], [ [[ADD_I:%.*]], [[INNER_LATCH:%.*]] ] 15; CHECK-NEXT: br i1 [[CHECK_1]], label [[INNER_LATCH]], label [[EXIT:%.*]] 16; CHECK: inner.latch: 17; CHECK-NEXT: [[ADD_I]] = add nuw nsw i64 [[STOREMERGE611_I]], 1 18; CHECK-NEXT: [[CMP5_I:%.*]] = icmp ult i64 [[STOREMERGE611_I]], 11 19; CHECK-NEXT: br i1 [[CMP5_I]], label [[INNER_LOOP]], label [[OUTER_LATCH]] 20; CHECK: outer.latch: 21; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1 22; CHECK-NEXT: br label [[OUTER_LOOP]] 23; CHECK: exit: 24; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[INNER_LOOP]] ] 25; CHECK-NEXT: ret i32 [[IV_LCSSA]] 26; 27entry: 28 br label %outer.loop 29 30outer.loop: ; preds = %outer.latch, %entry 31 %iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.latch ] 32 %check_1 = icmp ult i32 %iv, 2 33 br label %inner.loop 34 35inner.loop: ; preds = %inner.latch, %outer.loop 36 %storemerge611.i = phi i64 [ 0, %outer.loop ], [ %add.i, %inner.latch ] 37 br i1 %check_1, label %inner.latch, label %exit 38 39inner.latch: ; preds = %inner.loop 40 %add.i = add i64 %storemerge611.i, 1 41 %cmp5.i = icmp ult i64 %storemerge611.i, 11 42 br i1 %cmp5.i, label %inner.loop, label %outer.latch 43 44outer.latch: ; preds = %inner.latch 45 %iv.next = add i32 %iv, -1 46 br label %outer.loop 47 48exit: ; preds = %inner.loop 49 ret i32 %iv 50} 51 52define i32 @test_02() { 53; CHECK-LABEL: @test_02( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: br label [[OUTER_LOOP:%.*]] 56; CHECK: outer.loop: 57; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] 58; CHECK-NEXT: [[CHECK_1:%.*]] = icmp ult i32 [[IV]], 2147483640 59; CHECK-NEXT: br label [[INNER_LOOP:%.*]] 60; CHECK: inner.loop: 61; CHECK-NEXT: [[STOREMERGE611_I:%.*]] = phi i64 [ 0, [[OUTER_LOOP]] ], [ [[ADD_I:%.*]], [[INNER_LATCH:%.*]] ] 62; CHECK-NEXT: br i1 [[CHECK_1]], label [[INNER_LATCH]], label [[EXIT:%.*]] 63; CHECK: inner.latch: 64; CHECK-NEXT: [[ADD_I]] = add nuw nsw i64 [[STOREMERGE611_I]], 1 65; CHECK-NEXT: [[CMP5_I:%.*]] = icmp ult i64 [[STOREMERGE611_I]], 11 66; CHECK-NEXT: br i1 [[CMP5_I]], label [[INNER_LOOP]], label [[OUTER_LATCH]] 67; CHECK: outer.latch: 68; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 10 69; CHECK-NEXT: br label [[OUTER_LOOP]] 70; CHECK: exit: 71; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[INNER_LOOP]] ] 72; CHECK-NEXT: ret i32 [[IV_LCSSA]] 73; 74entry: 75 br label %outer.loop 76 77outer.loop: ; preds = %outer.latch, %entry 78 %iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.latch ] 79 %check_1 = icmp ult i32 %iv, 2147483640 80 br label %inner.loop 81 82inner.loop: ; preds = %inner.latch, %outer.loop 83 %storemerge611.i = phi i64 [ 0, %outer.loop ], [ %add.i, %inner.latch ] 84 br i1 %check_1, label %inner.latch, label %exit 85 86inner.latch: ; preds = %inner.loop 87 %add.i = add i64 %storemerge611.i, 1 88 %cmp5.i = icmp ult i64 %storemerge611.i, 11 89 br i1 %cmp5.i, label %inner.loop, label %outer.latch 90 91outer.latch: ; preds = %inner.latch 92 %iv.next = add i32 %iv, 10 93 br label %outer.loop 94 95exit: ; preds = %inner.loop 96 ret i32 %iv 97} 98 99define i32 @test_03() { 100; CHECK-LABEL: @test_03( 101; CHECK-NEXT: entry: 102; CHECK-NEXT: br label [[OUTER_LOOP:%.*]] 103; CHECK: outer.loop: 104; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 2147483640, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] 105; CHECK-NEXT: [[CHECK_1:%.*]] = icmp ult i32 [[IV]], 2147483647 106; CHECK-NEXT: br label [[INNER_LOOP:%.*]] 107; CHECK: inner.loop: 108; CHECK-NEXT: [[STOREMERGE611_I:%.*]] = phi i64 [ 0, [[OUTER_LOOP]] ], [ [[ADD_I:%.*]], [[INNER_LATCH:%.*]] ] 109; CHECK-NEXT: br i1 [[CHECK_1]], label [[INNER_LATCH]], label [[EXIT:%.*]] 110; CHECK: inner.latch: 111; CHECK-NEXT: [[ADD_I]] = add nuw nsw i64 [[STOREMERGE611_I]], 1 112; CHECK-NEXT: [[CMP5_I:%.*]] = icmp ult i64 [[STOREMERGE611_I]], 11 113; CHECK-NEXT: br i1 [[CMP5_I]], label [[INNER_LOOP]], label [[OUTER_LATCH]] 114; CHECK: outer.latch: 115; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 10 116; CHECK-NEXT: br label [[OUTER_LOOP]] 117; CHECK: exit: 118; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[INNER_LOOP]] ] 119; CHECK-NEXT: ret i32 [[IV_LCSSA]] 120; 121entry: 122 br label %outer.loop 123 124outer.loop: ; preds = %outer.latch, %entry 125 %iv = phi i32 [ 2147483640, %entry ], [ %iv.next, %outer.latch ] 126 %check_1 = icmp ult i32 %iv, 2147483647 127 br label %inner.loop 128 129inner.loop: ; preds = %inner.latch, %outer.loop 130 %storemerge611.i = phi i64 [ 0, %outer.loop ], [ %add.i, %inner.latch ] 131 br i1 %check_1, label %inner.latch, label %exit 132 133inner.latch: ; preds = %inner.loop 134 %add.i = add i64 %storemerge611.i, 1 135 %cmp5.i = icmp ult i64 %storemerge611.i, 11 136 br i1 %cmp5.i, label %inner.loop, label %outer.latch 137 138outer.latch: ; preds = %inner.latch 139 %iv.next = add i32 %iv, 10 140 br label %outer.loop 141 142exit: ; preds = %inner.loop 143 ret i32 %iv 144} 145