1cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2cee313d2SEric Christopher; RUN: opt -S -loop-predication -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s 355bdb140SAnna Thomas; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s 4cee313d2SEric Christopher 5cee313d2SEric Christopherdeclare void @llvm.experimental.guard(i1, ...) 6cee313d2SEric Christopher 7cee313d2SEric Christopherdefine i32 @signed_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 8cee313d2SEric Christopher; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit( 9cee313d2SEric Christopher; CHECK-NEXT: entry: 10cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 11cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 12cee313d2SEric Christopher; CHECK: loop.preheader: 13cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 14cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 15cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[LOWERLIMIT:%.*]], 1 16cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 17cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 18cee313d2SEric Christopher; CHECK: loop: 19cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 20cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 21cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 22cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 23cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 24cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 25cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 26cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 27cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I]], [[LOWERLIMIT]] 28cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 29cee313d2SEric Christopher; CHECK: exit.loopexit: 30cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 31cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 32cee313d2SEric Christopher; CHECK: exit: 33cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 34cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 35cee313d2SEric Christopher; 36cee313d2SEric Christopherentry: 37cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 38cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 39cee313d2SEric Christopher 40cee313d2SEric Christopherloop.preheader: 41cee313d2SEric Christopher br label %loop 42cee313d2SEric Christopher 43cee313d2SEric Christopherloop: 44cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 45cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 46cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 47cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 48cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 49cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 50cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 51cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 52cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 53cee313d2SEric Christopher %continue = icmp sgt i32 %i, %lowerlimit 54cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 55cee313d2SEric Christopher 56cee313d2SEric Christopherexit: 57cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 58cee313d2SEric Christopher ret i32 %result 59cee313d2SEric Christopher} 60cee313d2SEric Christopher 61cee313d2SEric Christopherdefine i32 @unsigned_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 62cee313d2SEric Christopher; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit( 63cee313d2SEric Christopher; CHECK-NEXT: entry: 64cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 65cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 66cee313d2SEric Christopher; CHECK: loop.preheader: 67cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 68cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 69cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[LOWERLIMIT:%.*]], 1 70cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 71cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 72cee313d2SEric Christopher; CHECK: loop: 73cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 74cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 75cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 76cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 77cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 78cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 79cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 80cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 81cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], [[LOWERLIMIT]] 82cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 83cee313d2SEric Christopher; CHECK: exit.loopexit: 84cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 85cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 86cee313d2SEric Christopher; CHECK: exit: 87cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 88cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 89cee313d2SEric Christopher; 90cee313d2SEric Christopherentry: 91cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 92cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 93cee313d2SEric Christopher 94cee313d2SEric Christopherloop.preheader: 95cee313d2SEric Christopher br label %loop 96cee313d2SEric Christopher 97cee313d2SEric Christopherloop: 98cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 99cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 100cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 101cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 102cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 103cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 104cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 105cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 106cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 107cee313d2SEric Christopher %continue = icmp ugt i32 %i, %lowerlimit 108cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 109cee313d2SEric Christopher 110cee313d2SEric Christopherexit: 111cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 112cee313d2SEric Christopher ret i32 %result 113cee313d2SEric Christopher} 114cee313d2SEric Christopher 115cee313d2SEric Christopher 116cee313d2SEric Christopher; if we predicated the loop, the guard will definitely fail and we will 117cee313d2SEric Christopher; deoptimize early on. 118cee313d2SEric Christopherdefine i32 @unsigned_reverse_loop_n_to_0(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 119cee313d2SEric Christopher; CHECK-LABEL: @unsigned_reverse_loop_n_to_0( 120cee313d2SEric Christopher; CHECK-NEXT: entry: 121cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 122cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 123cee313d2SEric Christopher; CHECK: loop.preheader: 124cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 125cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 126*b2915971SRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], false 127cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 128cee313d2SEric Christopher; CHECK: loop: 129cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 130cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 131cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 132*b2915971SRoman Lebedev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 133cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 134cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 135cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 136cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 137cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], 0 138cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 139cee313d2SEric Christopher; CHECK: exit.loopexit: 140cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 141cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 142cee313d2SEric Christopher; CHECK: exit: 143cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 144cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 145cee313d2SEric Christopher; 146cee313d2SEric Christopherentry: 147cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 148cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 149cee313d2SEric Christopher 150cee313d2SEric Christopherloop.preheader: 151cee313d2SEric Christopher br label %loop 152cee313d2SEric Christopher 153cee313d2SEric Christopherloop: 154cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 155cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 156cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 157cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 158cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 159cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 160cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 161cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 162cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 163cee313d2SEric Christopher %continue = icmp ugt i32 %i, 0 164cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 165cee313d2SEric Christopher 166cee313d2SEric Christopherexit: 167cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 168cee313d2SEric Christopher ret i32 %result 169cee313d2SEric Christopher} 170cee313d2SEric Christopher 171cee313d2SEric Christopher; do not loop predicate when the range has step -1 and latch has step 1. 172cee313d2SEric Christopherdefine i32 @reverse_loop_range_step_increment(i32 %n, i32* %array, i32 %length) { 173cee313d2SEric Christopher; CHECK-LABEL: @reverse_loop_range_step_increment( 174cee313d2SEric Christopher; CHECK-NEXT: entry: 175cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 176cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 177cee313d2SEric Christopher; CHECK: loop.preheader: 178cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 179cee313d2SEric Christopher; CHECK: loop: 180cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 181cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 182cee313d2SEric Christopher; CHECK-NEXT: [[IRC:%.*]] = phi i32 [ [[I_INC:%.*]], [[LOOP]] ], [ 1, [[LOOP_PREHEADER]] ] 183cee313d2SEric Christopher; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[IRC]], 1 184cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[IRC]], [[LENGTH:%.*]] 185cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 186cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[IRC]] to i64 187cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 188cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 189cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 190cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 191cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ugt i32 [[I]], 65534 192cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 193cee313d2SEric Christopher; CHECK: exit.loopexit: 194cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 195cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 196cee313d2SEric Christopher; CHECK: exit: 197cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 198cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 199cee313d2SEric Christopher; 200cee313d2SEric Christopherentry: 201cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 202cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 203cee313d2SEric Christopher 204cee313d2SEric Christopherloop.preheader: 205cee313d2SEric Christopher br label %loop 206cee313d2SEric Christopher 207cee313d2SEric Christopherloop: 208cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 209cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 210cee313d2SEric Christopher %irc = phi i32 [ %i.inc, %loop ], [ 1, %loop.preheader ] 211cee313d2SEric Christopher %i.inc = add nuw nsw i32 %irc, 1 212cee313d2SEric Christopher %within.bounds = icmp ult i32 %irc, %length 213cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 214cee313d2SEric Christopher %i.i64 = zext i32 %irc to i64 215cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 216cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 217cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 218cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 219cee313d2SEric Christopher %continue = icmp ugt i32 %i, 65534 220cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 221cee313d2SEric Christopher 222cee313d2SEric Christopherexit: 223cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 224cee313d2SEric Christopher ret i32 %result 225cee313d2SEric Christopher} 226cee313d2SEric Christopher 227cee313d2SEric Christopherdefine i32 @signed_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 228cee313d2SEric Christopher; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit_equal( 229cee313d2SEric Christopher; CHECK-NEXT: entry: 230cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 231cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 232cee313d2SEric Christopher; CHECK: loop.preheader: 233cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 234cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 235cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[LOWERLIMIT:%.*]], 1 236cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 237cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 238cee313d2SEric Christopher; CHECK: loop: 239cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 240cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 241cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 242cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 243cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 244cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 245cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 246cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 247cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sge i32 [[I]], [[LOWERLIMIT]] 248cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 249cee313d2SEric Christopher; CHECK: exit.loopexit: 250cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 251cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 252cee313d2SEric Christopher; CHECK: exit: 253cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 254cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 255cee313d2SEric Christopher; 256cee313d2SEric Christopherentry: 257cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 258cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 259cee313d2SEric Christopher 260cee313d2SEric Christopherloop.preheader: 261cee313d2SEric Christopher br label %loop 262cee313d2SEric Christopher 263cee313d2SEric Christopherloop: 264cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 265cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 266cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 267cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 268cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 269cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 270cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 271cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 272cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 273cee313d2SEric Christopher %continue = icmp sge i32 %i, %lowerlimit 274cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 275cee313d2SEric Christopher 276cee313d2SEric Christopherexit: 277cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 278cee313d2SEric Christopher ret i32 %result 279cee313d2SEric Christopher} 280cee313d2SEric Christopher 281cee313d2SEric Christopherdefine i32 @unsigned_reverse_loop_n_to_lower_limit_equal(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 282cee313d2SEric Christopher; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit_equal( 283cee313d2SEric Christopher; CHECK-NEXT: entry: 284cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 285cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 286cee313d2SEric Christopher; CHECK: loop.preheader: 287cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 288cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 289cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[LOWERLIMIT:%.*]], 1 290cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]] 291cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 292cee313d2SEric Christopher; CHECK: loop: 293cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 294cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 295cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 296cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 297cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 298cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 299cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 300cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 301cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp uge i32 [[I]], [[LOWERLIMIT]] 302cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 303cee313d2SEric Christopher; CHECK: exit.loopexit: 304cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 305cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 306cee313d2SEric Christopher; CHECK: exit: 307cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 308cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 309cee313d2SEric Christopher; 310cee313d2SEric Christopherentry: 311cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 312cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 313cee313d2SEric Christopher 314cee313d2SEric Christopherloop.preheader: 315cee313d2SEric Christopher br label %loop 316cee313d2SEric Christopher 317cee313d2SEric Christopherloop: 318cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 319cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 320cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 321cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 322cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 323cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 324cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 325cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 326cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 327cee313d2SEric Christopher %continue = icmp uge i32 %i, %lowerlimit 328cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 329cee313d2SEric Christopher 330cee313d2SEric Christopherexit: 331cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 332cee313d2SEric Christopher ret i32 %result 333cee313d2SEric Christopher} 334cee313d2SEric Christopher 335cee313d2SEric Christopher 336cee313d2SEric Christopher; if we predicated the loop, the guard will definitely fail and we will 337cee313d2SEric Christopher; deoptimize early on. 338cee313d2SEric Christopherdefine i32 @unsigned_reverse_loop_n_to_1(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) { 339cee313d2SEric Christopher; CHECK-LABEL: @unsigned_reverse_loop_n_to_1( 340cee313d2SEric Christopher; CHECK-NEXT: entry: 341cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 342cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 343cee313d2SEric Christopher; CHECK: loop.preheader: 344cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 345cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], [[LENGTH:%.*]] 346*b2915971SRoman Lebedev; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], false 347cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 348cee313d2SEric Christopher; CHECK: loop: 349cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 350cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[N]], [[LOOP_PREHEADER]] ] 351cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], -1 352*b2915971SRoman Lebedev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 353cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I_NEXT]] to i64 354cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 355cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 356cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 357cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp uge i32 [[I]], 1 358cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 359cee313d2SEric Christopher; CHECK: exit.loopexit: 360cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 361cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 362cee313d2SEric Christopher; CHECK: exit: 363cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 364cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 365cee313d2SEric Christopher; 366cee313d2SEric Christopherentry: 367cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 368cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 369cee313d2SEric Christopher 370cee313d2SEric Christopherloop.preheader: 371cee313d2SEric Christopher br label %loop 372cee313d2SEric Christopher 373cee313d2SEric Christopherloop: 374cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 375cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ] 376cee313d2SEric Christopher %i.next = add nsw i32 %i, -1 377cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 378cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 379cee313d2SEric Christopher %i.i64 = zext i32 %i.next to i64 380cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 381cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 382cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 383cee313d2SEric Christopher %continue = icmp uge i32 %i, 1 384cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 385cee313d2SEric Christopher 386cee313d2SEric Christopherexit: 387cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 388cee313d2SEric Christopher ret i32 %result 389cee313d2SEric Christopher} 390cee313d2SEric Christopher 391