1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -indvars -S < %s | FileCheck %s 3; RUN: opt -passes=indvars -S < %s | FileCheck %s 4 5; FIXME: In all cases, x is from [0; 1000) and we cannot prove that x + 1 > x. 6 7define void @test_sgt(i32 %x) { 8; CHECK-LABEL: @test_sgt( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[PRECONDITION:%.*]] = icmp ult i32 [[X:%.*]], 1000 11; CHECK-NEXT: br i1 [[PRECONDITION]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] 12; CHECK: loop.preheader: 13; CHECK-NEXT: br label [[LOOP:%.*]] 14; CHECK: loop: 15; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] 16; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 17; CHECK-NEXT: [[GUARD:%.*]] = icmp sgt i32 [[TMP]], [[IV]] 18; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] 19; CHECK: guarded: 20; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 21; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 22; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 23; CHECK: exit.loopexit: 24; CHECK-NEXT: br label [[EXIT]] 25; CHECK: exit: 26; CHECK-NEXT: ret void 27; CHECK: fail: 28; CHECK-NEXT: unreachable 29; 30entry: 31 %precondition = icmp ult i32 %x, 1000 32 br i1 %precondition, label %loop, label %exit 33 34loop: 35 %iv = phi i32 [%x, %entry], [%iv.next, %guarded] 36 %tmp = add i32 %iv, 1 37 %guard = icmp sgt i32 %tmp, %iv 38 br i1 %guard, label %guarded, label %fail 39 40guarded: 41 %iv.next = add i32 %iv, -1 42 %cond = icmp eq i32 %iv, 0 43 br i1 %cond, label %loop, label %exit 44 45exit: 46 ret void 47 48fail: 49 unreachable 50} 51 52define void @test_sge(i32 %x) { 53; CHECK-LABEL: @test_sge( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: [[PRECONDITION:%.*]] = icmp ult i32 [[X:%.*]], 1000 56; CHECK-NEXT: br i1 [[PRECONDITION]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] 57; CHECK: loop.preheader: 58; CHECK-NEXT: br label [[LOOP:%.*]] 59; CHECK: loop: 60; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] 61; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 62; CHECK-NEXT: [[GUARD:%.*]] = icmp sge i32 [[TMP]], [[IV]] 63; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] 64; CHECK: guarded: 65; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 66; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 67; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 68; CHECK: exit.loopexit: 69; CHECK-NEXT: br label [[EXIT]] 70; CHECK: exit: 71; CHECK-NEXT: ret void 72; CHECK: fail: 73; CHECK-NEXT: unreachable 74; 75entry: 76 %precondition = icmp ult i32 %x, 1000 77 br i1 %precondition, label %loop, label %exit 78 79loop: 80 %iv = phi i32 [%x, %entry], [%iv.next, %guarded] 81 %tmp = add i32 %iv, 1 82 %guard = icmp sge i32 %tmp, %iv 83 br i1 %guard, label %guarded, label %fail 84 85guarded: 86 %iv.next = add i32 %iv, -1 87 %cond = icmp eq i32 %iv, 0 88 br i1 %cond, label %loop, label %exit 89 90exit: 91 ret void 92 93fail: 94 unreachable 95} 96 97define void @test_ugt(i32 %x) { 98; CHECK-LABEL: @test_ugt( 99; CHECK-NEXT: entry: 100; CHECK-NEXT: [[PRECONDITION:%.*]] = icmp ult i32 [[X:%.*]], 1000 101; CHECK-NEXT: br i1 [[PRECONDITION]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] 102; CHECK: loop.preheader: 103; CHECK-NEXT: br label [[LOOP:%.*]] 104; CHECK: loop: 105; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] 106; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 107; CHECK-NEXT: [[GUARD:%.*]] = icmp ugt i32 [[TMP]], [[IV]] 108; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] 109; CHECK: guarded: 110; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 111; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 112; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 113; CHECK: exit.loopexit: 114; CHECK-NEXT: br label [[EXIT]] 115; CHECK: exit: 116; CHECK-NEXT: ret void 117; CHECK: fail: 118; CHECK-NEXT: unreachable 119; 120entry: 121 %precondition = icmp ult i32 %x, 1000 122 br i1 %precondition, label %loop, label %exit 123 124loop: 125 %iv = phi i32 [%x, %entry], [%iv.next, %guarded] 126 %tmp = add i32 %iv, 1 127 %guard = icmp ugt i32 %tmp, %iv 128 br i1 %guard, label %guarded, label %fail 129 130guarded: 131 %iv.next = add i32 %iv, -1 132 %cond = icmp eq i32 %iv, 0 133 br i1 %cond, label %loop, label %exit 134 135exit: 136 ret void 137 138fail: 139 unreachable 140} 141 142 143define void @test_uge(i32 %x) { 144; CHECK-LABEL: @test_uge( 145; CHECK-NEXT: entry: 146; CHECK-NEXT: [[PRECONDITION:%.*]] = icmp ult i32 [[X:%.*]], 1000 147; CHECK-NEXT: br i1 [[PRECONDITION]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] 148; CHECK: loop.preheader: 149; CHECK-NEXT: br label [[LOOP:%.*]] 150; CHECK: loop: 151; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] 152; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 153; CHECK-NEXT: [[GUARD:%.*]] = icmp uge i32 [[TMP]], [[IV]] 154; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] 155; CHECK: guarded: 156; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 157; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 158; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 159; CHECK: exit.loopexit: 160; CHECK-NEXT: br label [[EXIT]] 161; CHECK: exit: 162; CHECK-NEXT: ret void 163; CHECK: fail: 164; CHECK-NEXT: unreachable 165; 166entry: 167 %precondition = icmp ult i32 %x, 1000 168 br i1 %precondition, label %loop, label %exit 169 170loop: 171 %iv = phi i32 [%x, %entry], [%iv.next, %guarded] 172 %tmp = add i32 %iv, 1 173 %guard = icmp uge i32 %tmp, %iv 174 br i1 %guard, label %guarded, label %fail 175 176guarded: 177 %iv.next = add i32 %iv, -1 178 %cond = icmp eq i32 %iv, 0 179 br i1 %cond, label %loop, label %exit 180 181exit: 182 ret void 183 184fail: 185 unreachable 186} 187