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