1cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2cee313d2SEric Christopher; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s 355bdb140SAnna Thomas; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s 4cee313d2SEric Christopher 5cee313d2SEric Christopherdeclare void @llvm.experimental.guard(i1, ...) 6cee313d2SEric Christopher 7cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 8cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check( 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:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 14cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 15cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 16cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 17cee313d2SEric Christopher; CHECK: loop: 18cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 19cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 20cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 21cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 22cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 23cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 24cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 25cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 26cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 27cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 28cee313d2SEric Christopher; CHECK: exit.loopexit: 29cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 30cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 31cee313d2SEric Christopher; CHECK: exit: 32cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 33cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 34cee313d2SEric Christopher; 35cee313d2SEric Christopherentry: 36cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 37cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 38cee313d2SEric Christopher 39cee313d2SEric Christopherloop.preheader: 40cee313d2SEric Christopher br label %loop 41cee313d2SEric Christopher 42cee313d2SEric Christopherloop: 43cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 44cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 45cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 46cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 47cee313d2SEric Christopher 48cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 49cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 50cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 51cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 52cee313d2SEric Christopher 53cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 54cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 55cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 56cee313d2SEric Christopher 57cee313d2SEric Christopherexit: 58cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 59cee313d2SEric Christopher ret i32 %result 60cee313d2SEric Christopher} 61cee313d2SEric Christopher 62cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) { 63cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check( 64cee313d2SEric Christopher; CHECK-NEXT: entry: 65cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 66cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 67cee313d2SEric Christopher; CHECK: loop.preheader: 68cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]] 69cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 70cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 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]] ], [ 0, [[LOOP_PREHEADER]] ] 75cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 76cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 77cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 78cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 79cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 80cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 81cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]] 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 ], [ 0, %loop.preheader ] 100cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 101cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 102cee313d2SEric Christopher 103cee313d2SEric Christopher %i.i64 = zext i32 %i 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 108cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 109cee313d2SEric Christopher %continue = icmp ule i32 %i.next, %n 110cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 111cee313d2SEric Christopher 112cee313d2SEric Christopherexit: 113cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 114cee313d2SEric Christopher ret i32 %result 115cee313d2SEric Christopher} 116cee313d2SEric Christopher 117cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) { 118cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check( 119cee313d2SEric Christopher; CHECK-NEXT: entry: 120cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 121cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 122cee313d2SEric Christopher; CHECK: loop.preheader: 123cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 124cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 125cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 126cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 127cee313d2SEric Christopher; CHECK: loop: 128cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 129cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 130cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 131cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 132cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 133cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 134cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 135cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 136cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 137cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 138cee313d2SEric Christopher; CHECK: exit.loopexit: 139cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 140cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 141cee313d2SEric Christopher; CHECK: exit: 142cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 143cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 144cee313d2SEric Christopher; 145cee313d2SEric Christopherentry: 146cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 147cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 148cee313d2SEric Christopher 149cee313d2SEric Christopherloop.preheader: 150cee313d2SEric Christopher br label %loop 151cee313d2SEric Christopher 152cee313d2SEric Christopherloop: 153cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 154cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 155cee313d2SEric Christopher %within.bounds = icmp ugt i32 %length, %i 156cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 157cee313d2SEric Christopher 158cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 159cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 160cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 161cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 162cee313d2SEric Christopher 163cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 164cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 165cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 166cee313d2SEric Christopher 167cee313d2SEric Christopherexit: 168cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 169cee313d2SEric Christopher ret i32 %result 170cee313d2SEric Christopher} 171cee313d2SEric Christopher 172cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 173cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_ult_check( 174cee313d2SEric Christopher; CHECK-NEXT: entry: 175cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 176cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 177cee313d2SEric Christopher; CHECK: loop.preheader: 178cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 179cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 180cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 181cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 182cee313d2SEric Christopher; CHECK: loop: 183cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 184cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 185cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 186cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] 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: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 190cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 191cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 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 sle 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 ], [ 0, %loop.preheader ] 210cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 211cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 212cee313d2SEric Christopher 213cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 214cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 215cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 216cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 217cee313d2SEric Christopher 218cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 219cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 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_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) { 228cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known( 229cee313d2SEric Christopher; CHECK-NEXT: entry: 230cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 2315a8a7b3bSRoman Lebedev; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]] 232cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 233cee313d2SEric Christopher; CHECK: loop.preheader: 234cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]] 235b2915971SRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]] 236cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 237cee313d2SEric Christopher; CHECK: loop: 238cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 239cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 240b2915971SRoman Lebedev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ] 241cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 242cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 243cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 244cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 245cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 246cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 247cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 248cee313d2SEric Christopher; CHECK: exit.loopexit: 249cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 250cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 251cee313d2SEric Christopher; CHECK: exit: 252cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 253cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 254cee313d2SEric Christopher; 255cee313d2SEric Christopherentry: 256cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 257cee313d2SEric Christopher %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648} 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 ], [ 0, %loop.preheader ] 266cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 267cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 268cee313d2SEric Christopher 269cee313d2SEric Christopher %i.i64 = zext i32 %i 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 274cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 275cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 276cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 277cee313d2SEric Christopher 278cee313d2SEric Christopherexit: 279cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 280cee313d2SEric Christopher ret i32 %result 281cee313d2SEric Christopher} 282cee313d2SEric Christopher 283cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) { 284cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate( 285cee313d2SEric Christopher; CHECK-NEXT: entry: 286cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 287cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 288cee313d2SEric Christopher; CHECK: loop.preheader: 289cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 290cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 291cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 292cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 293cee313d2SEric Christopher; CHECK: loop: 294cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 295cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 296cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 297cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] 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: [[I_NEXT]] = add nuw i32 [[I]], 1 302cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]] 303cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]] 304cee313d2SEric Christopher; CHECK: exit.loopexit: 305cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 306cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 307cee313d2SEric Christopher; CHECK: exit: 308cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 309cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 310cee313d2SEric Christopher; 311cee313d2SEric Christopherentry: 312cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 313cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 314cee313d2SEric Christopher 315cee313d2SEric Christopherloop.preheader: 316cee313d2SEric Christopher br label %loop 317cee313d2SEric Christopher 318cee313d2SEric Christopherloop: 319cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 320cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 321cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 322cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 323cee313d2SEric Christopher 324cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 325cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 326cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 327cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 328cee313d2SEric Christopher 329cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 330cee313d2SEric Christopher %continue = icmp sgt i32 %i.next, %n 331cee313d2SEric Christopher br i1 %continue, label %exit, label %loop 332cee313d2SEric Christopher 333cee313d2SEric Christopherexit: 334cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 335cee313d2SEric Christopher ret i32 %result 336cee313d2SEric Christopher} 337cee313d2SEric Christopher 338cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) { 339cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check( 340cee313d2SEric Christopher; CHECK-NEXT: entry: 341cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle 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:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 345cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 346cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 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]] ], [ 0, [[LOOP_PREHEADER]] ] 351cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 352cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 353cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 354cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 355cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 356cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 357cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 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 sle 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 ], [ 0, %loop.preheader ] 376cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 377cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 378cee313d2SEric Christopher 379cee313d2SEric Christopher %i.i64 = zext i32 %i 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 384cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 385cee313d2SEric Christopher %continue = icmp sle i32 %i.next, %n 386cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 387cee313d2SEric Christopher 388cee313d2SEric Christopherexit: 389cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 390cee313d2SEric Christopher ret i32 %result 391cee313d2SEric Christopher} 392cee313d2SEric Christopher 393cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) { 394cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check( 395cee313d2SEric Christopher; CHECK-NEXT: entry: 396cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 397cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 398cee313d2SEric Christopher; CHECK: loop.preheader: 399cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 400cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 401cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 402cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 403cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 404cee313d2SEric Christopher; CHECK: loop: 405cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 406cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 407cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 408cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 409cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 410cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 411cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 412cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 413cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 414cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 415cee313d2SEric Christopher; CHECK: exit.loopexit: 416cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 417cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 418cee313d2SEric Christopher; CHECK: exit: 419cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 420cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 421cee313d2SEric Christopher; 422cee313d2SEric Christopherentry: 423cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 424cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 425cee313d2SEric Christopher 426cee313d2SEric Christopherloop.preheader: 427cee313d2SEric Christopher br label %loop 428cee313d2SEric Christopher 429cee313d2SEric Christopherloop: 430cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 431cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 432cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 433cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 434cee313d2SEric Christopher 435cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 436cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 437cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 438cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 439cee313d2SEric Christopher 440cee313d2SEric Christopher %i.next = add i32 %i, 1 441cee313d2SEric Christopher %continue = icmp slt i32 %i, %n 442cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 443cee313d2SEric Christopher 444cee313d2SEric Christopherexit: 445cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 446cee313d2SEric Christopher ret i32 %result 447cee313d2SEric Christopher} 448cee313d2SEric Christopher 449cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) { 450cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check( 451cee313d2SEric Christopher; CHECK-NEXT: entry: 452cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 453cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 454cee313d2SEric Christopher; CHECK: loop.preheader: 455cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2 456cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 457cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 458cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 459cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 460cee313d2SEric Christopher; CHECK: loop: 461cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 462cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 463cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 464cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 465cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 466cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 467cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 468cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 469cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 470cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 471cee313d2SEric Christopher; CHECK: exit.loopexit: 472cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 473cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 474cee313d2SEric Christopher; CHECK: exit: 475cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 476cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 477cee313d2SEric Christopher; 478cee313d2SEric Christopherentry: 479cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 480cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 481cee313d2SEric Christopher 482cee313d2SEric Christopherloop.preheader: 483cee313d2SEric Christopher br label %loop 484cee313d2SEric Christopher 485cee313d2SEric Christopherloop: 486cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 487cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 488cee313d2SEric Christopher 489cee313d2SEric Christopher %i.next = add i32 %i, 1 490cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.next, %length 491cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 492cee313d2SEric Christopher 493cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 494cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 495cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 496cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 497cee313d2SEric Christopher 498cee313d2SEric Christopher %continue = icmp slt i32 %i, %n 499cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 500cee313d2SEric Christopher 501cee313d2SEric Christopherexit: 502cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 503cee313d2SEric Christopher ret i32 %result 504cee313d2SEric Christopher} 505cee313d2SEric Christopher 506cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 507cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check( 508cee313d2SEric Christopher; CHECK-NEXT: entry: 509cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 510cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 511cee313d2SEric Christopher; CHECK: loop.preheader: 512cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 513cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]] 514cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 515cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 516cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 517cee313d2SEric Christopher; CHECK: loop: 518cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 519cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 520cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 521cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 522cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 523cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 524cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 525cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 526cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 527cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 528cee313d2SEric Christopher; CHECK: exit.loopexit: 529cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 530cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 531cee313d2SEric Christopher; CHECK: exit: 532cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 533cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 534cee313d2SEric Christopher; 535cee313d2SEric Christopherentry: 536cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 537cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 538cee313d2SEric Christopher 539cee313d2SEric Christopherloop.preheader: 540cee313d2SEric Christopher br label %loop 541cee313d2SEric Christopher 542cee313d2SEric Christopherloop: 543cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 544cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 545cee313d2SEric Christopher %i.offset = add i32 %i, 1 546cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.offset, %length 547cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 548cee313d2SEric Christopher 549cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 550cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 551cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 552cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 553cee313d2SEric Christopher 554cee313d2SEric Christopher %i.next = add i32 %i, 1 555cee313d2SEric Christopher %continue = icmp sle i32 %i.next, %n 556cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 557cee313d2SEric Christopher 558cee313d2SEric Christopherexit: 559cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 560cee313d2SEric Christopher ret i32 %result 561cee313d2SEric Christopher} 562cee313d2SEric Christopher 563cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 564cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check( 565cee313d2SEric Christopher; CHECK-NEXT: entry: 566cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 567cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 568cee313d2SEric Christopher; CHECK: loop.preheader: 569cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 570cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]] 571cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 572cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 573cee313d2SEric Christopher; CHECK: loop: 574cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 575cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 576cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 577cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 578cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 579cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 580cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 581cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 582cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1 583cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]] 584cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 585cee313d2SEric Christopher; CHECK: exit.loopexit: 586cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 587cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 588cee313d2SEric Christopher; CHECK: exit: 589cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 590cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 591cee313d2SEric Christopher; 592cee313d2SEric Christopherentry: 593cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 594cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 595cee313d2SEric Christopher 596cee313d2SEric Christopherloop.preheader: 597cee313d2SEric Christopher br label %loop 598cee313d2SEric Christopher 599cee313d2SEric Christopherloop: 600cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 601cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 602cee313d2SEric Christopher %i.offset = add i32 %i, 1 603cee313d2SEric Christopher %within.bounds = icmp ult i32 %i.offset, %length 604cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 605cee313d2SEric Christopher 606cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 607cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 608cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 609cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 610cee313d2SEric Christopher 611cee313d2SEric Christopher %i.next = add i32 %i, 1 612cee313d2SEric Christopher %i.next.offset = add i32 %i.next, 1 613cee313d2SEric Christopher %continue = icmp sle i32 %i.next.offset, %n 614cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 615cee313d2SEric Christopher 616cee313d2SEric Christopherexit: 617cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 618cee313d2SEric Christopher ret i32 %result 619cee313d2SEric Christopher} 620cee313d2SEric Christopher 621cee313d2SEric Christopherdefine i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) { 622cee313d2SEric Christopher; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n( 623cee313d2SEric Christopher; CHECK-NEXT: entry: 624cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 625cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 626cee313d2SEric Christopher; CHECK: loop.preheader: 627cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 628cee313d2SEric Christopher; CHECK: loop: 629cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 630cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 631cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 632cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 633cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 634cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 635cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 636cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 637cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 638cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]] 639cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 640cee313d2SEric Christopher; CHECK: exit.loopexit: 641cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 642cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 643cee313d2SEric Christopher; CHECK: exit: 644cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 645cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 646cee313d2SEric Christopher; 647cee313d2SEric Christopherentry: 648cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 649cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 650cee313d2SEric Christopher 651cee313d2SEric Christopherloop.preheader: 652cee313d2SEric Christopher br label %loop 653cee313d2SEric Christopher 654cee313d2SEric Christopherloop: 655cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 656cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 657cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 658cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 659cee313d2SEric Christopher 660cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 661cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 662cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 663cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 664cee313d2SEric Christopher 665cee313d2SEric Christopher %i.next = add nsw i32 %i, 1 666cee313d2SEric Christopher %continue = icmp ne i32 %i.next, %n 667cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 668cee313d2SEric Christopher 669cee313d2SEric Christopherexit: 670cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 671cee313d2SEric Christopher ret i32 %result 672cee313d2SEric Christopher} 673cee313d2SEric Christopher 674cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) { 675cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step( 676cee313d2SEric Christopher; CHECK-NEXT: entry: 677cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 678cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 679cee313d2SEric Christopher; CHECK: loop.preheader: 680cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 681cee313d2SEric Christopher; CHECK: loop: 682cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 683cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 684cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 685cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 686cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 687cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 688cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 689cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 690cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2 691cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 692cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 693cee313d2SEric Christopher; CHECK: exit.loopexit: 694cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 695cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 696cee313d2SEric Christopher; CHECK: exit: 697cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 698cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 699cee313d2SEric Christopher; 700cee313d2SEric Christopherentry: 701cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 702cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 703cee313d2SEric Christopher 704cee313d2SEric Christopherloop.preheader: 705cee313d2SEric Christopher br label %loop 706cee313d2SEric Christopher 707cee313d2SEric Christopherloop: 708cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 709cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 710cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 711cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 712cee313d2SEric Christopher 713cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 714cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 715cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 716cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 717cee313d2SEric Christopher 718cee313d2SEric Christopher %i.next = add nsw i32 %i, 2 719cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 720cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 721cee313d2SEric Christopher 722cee313d2SEric Christopherexit: 723cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 724cee313d2SEric Christopher ret i32 %result 725cee313d2SEric Christopher} 726cee313d2SEric Christopher 727cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) { 728cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check( 729cee313d2SEric Christopher; CHECK-NEXT: entry: 730cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 731cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 732cee313d2SEric Christopher; CHECK: loop.preheader: 733cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 734cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 735cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 736cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 737cee313d2SEric Christopher; CHECK: loop: 738cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 739cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 740cee313d2SEric Christopher; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 741cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 742cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 743cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 744cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 745cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 746cee313d2SEric Christopher; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1 747cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 748cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 749cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 750cee313d2SEric Christopher; CHECK: exit.loopexit: 751cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 752cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 753cee313d2SEric Christopher; CHECK: exit: 754cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 755cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 756cee313d2SEric Christopher; 757cee313d2SEric Christopherentry: 758cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 759cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 760cee313d2SEric Christopher 761cee313d2SEric Christopherloop.preheader: 762cee313d2SEric Christopher br label %loop 763cee313d2SEric Christopher 764cee313d2SEric Christopherloop: 765cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 766cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 767cee313d2SEric Christopher %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 768cee313d2SEric Christopher 769cee313d2SEric Christopher %within.bounds = icmp ult i32 %j, %length 770cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 771cee313d2SEric Christopher 772cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 773cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 774cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 775cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 776cee313d2SEric Christopher 777cee313d2SEric Christopher %j.next = add nsw i32 %j, 1 778cee313d2SEric Christopher %i.next = add nsw i32 %i, 1 779cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 780cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 781cee313d2SEric Christopher 782cee313d2SEric Christopherexit: 783cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 784cee313d2SEric Christopher ret i32 %result 785cee313d2SEric Christopher} 786cee313d2SEric Christopher 787cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, 788cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check( 789cee313d2SEric Christopher; CHECK-NEXT: entry: 790cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 791cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 792cee313d2SEric Christopher; CHECK: loop.preheader: 793cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]] 794cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]] 795cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]] 796cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]] 797cee313d2SEric Christopher; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]] 798cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 799cee313d2SEric Christopher; CHECK: loop: 800cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 801cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ] 802cee313d2SEric Christopher; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ] 803cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ] 804cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 805cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 806cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 807cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 808cee313d2SEric Christopher; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 809cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 810cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 811cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 812cee313d2SEric Christopher; CHECK: exit.loopexit: 813cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 814cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 815cee313d2SEric Christopher; CHECK: exit: 816cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 817cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 818cee313d2SEric Christopher; 819cee313d2SEric Christopher i32 %start.j, i32 %length, 820cee313d2SEric Christopher i32 %n) { 821cee313d2SEric Christopherentry: 822cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 823cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 824cee313d2SEric Christopher 825cee313d2SEric Christopherloop.preheader: 826cee313d2SEric Christopher br label %loop 827cee313d2SEric Christopher 828cee313d2SEric Christopherloop: 829cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 830cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ] 831cee313d2SEric Christopher %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ] 832cee313d2SEric Christopher 833cee313d2SEric Christopher %within.bounds = icmp ult i32 %j, %length 834cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 835cee313d2SEric Christopher 836cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 837cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 838cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 839cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 840cee313d2SEric Christopher 841cee313d2SEric Christopher %j.next = add i32 %j, 1 842cee313d2SEric Christopher %i.next = add i32 %i, 1 843cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 844cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 845cee313d2SEric Christopher 846cee313d2SEric Christopherexit: 847cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 848cee313d2SEric Christopher ret i32 %result 849cee313d2SEric Christopher} 850cee313d2SEric Christopher 851cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) { 852cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types( 853cee313d2SEric Christopher; CHECK-NEXT: entry: 854cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 855cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 856cee313d2SEric Christopher; CHECK: loop.preheader: 857cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 858cee313d2SEric Christopher; CHECK: loop: 859cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 860cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 861cee313d2SEric Christopher; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 862cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]] 863cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 864cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 865cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 866cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 867cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 868cee313d2SEric Christopher; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1 869cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 870cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 871cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 872cee313d2SEric Christopher; CHECK: exit.loopexit: 873cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 874cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 875cee313d2SEric Christopher; CHECK: exit: 876cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 877cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 878cee313d2SEric Christopher; 879cee313d2SEric Christopherentry: 880cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 881cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 882cee313d2SEric Christopher 883cee313d2SEric Christopherloop.preheader: 884cee313d2SEric Christopher br label %loop 885cee313d2SEric Christopher 886cee313d2SEric Christopherloop: 887cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 888cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 889cee313d2SEric Christopher %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ] 890cee313d2SEric Christopher 891cee313d2SEric Christopher %within.bounds = icmp ult i16 %j, %length 892cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 893cee313d2SEric Christopher 894cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 895cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 896cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 897cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 898cee313d2SEric Christopher 899cee313d2SEric Christopher %j.next = add i16 %j, 1 900cee313d2SEric Christopher %i.next = add i32 %i, 1 901cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 902cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 903cee313d2SEric Christopher 904cee313d2SEric Christopherexit: 905cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 906cee313d2SEric Christopher ret i32 %result 907cee313d2SEric Christopher} 908cee313d2SEric Christopher 909cee313d2SEric Christopherdefine i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) { 910cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides( 911cee313d2SEric Christopher; CHECK-NEXT: entry: 912cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 913cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 914cee313d2SEric Christopher; CHECK: loop.preheader: 915cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 916cee313d2SEric Christopher; CHECK: loop: 917cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 918cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 919cee313d2SEric Christopher; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 920cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]] 921cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 922cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 923cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 924cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 925cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 926cee313d2SEric Christopher; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2 927cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 928cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 929cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 930cee313d2SEric Christopher; CHECK: exit.loopexit: 931cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 932cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 933cee313d2SEric Christopher; CHECK: exit: 934cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 935cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 936cee313d2SEric Christopher; 937cee313d2SEric Christopherentry: 938cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 939cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 940cee313d2SEric Christopher 941cee313d2SEric Christopherloop.preheader: 942cee313d2SEric Christopher br label %loop 943cee313d2SEric Christopher 944cee313d2SEric Christopherloop: 945cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 946cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 947cee313d2SEric Christopher %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 948cee313d2SEric Christopher 949cee313d2SEric Christopher %within.bounds = icmp ult i32 %j, %length 950cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 951cee313d2SEric Christopher 952cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 953cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 954cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 955cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 956cee313d2SEric Christopher 957cee313d2SEric Christopher %j.next = add nsw i32 %j, 2 958cee313d2SEric Christopher %i.next = add nsw i32 %i, 1 959cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 960cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 961cee313d2SEric Christopher 962cee313d2SEric Christopherexit: 963cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 964cee313d2SEric Christopher ret i32 %result 965cee313d2SEric Christopher} 966cee313d2SEric Christopher 967cee313d2SEric Christopherdefine i32 @two_range_checks(i32* %array.1, i32 %length.1, 968cee313d2SEric Christopher; CHECK-LABEL: @two_range_checks( 969cee313d2SEric Christopher; CHECK-NEXT: entry: 970cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 971cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 972cee313d2SEric Christopher; CHECK: loop.preheader: 973cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 974cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]] 975cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 976cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 977cee313d2SEric Christopher; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]] 978cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 979cee313d2SEric Christopher; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]] 980cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 981cee313d2SEric Christopher; CHECK: loop: 982cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 983cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 984cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ] 985cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 986cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 987cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 988cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 989cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 990cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 991cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 992cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 993cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 994cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 995cee313d2SEric Christopher; CHECK: exit.loopexit: 996cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 997cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 998cee313d2SEric Christopher; CHECK: exit: 999cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1000cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1001cee313d2SEric Christopher; 1002cee313d2SEric Christopher i32* %array.2, i32 %length.2, i32 %n) { 1003cee313d2SEric Christopherentry: 1004cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1005cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1006cee313d2SEric Christopher 1007cee313d2SEric Christopherloop.preheader: 1008cee313d2SEric Christopher br label %loop 1009cee313d2SEric Christopher 1010cee313d2SEric Christopherloop: 1011cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1012cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1013cee313d2SEric Christopher %within.bounds.1 = icmp ult i32 %i, %length.1 1014cee313d2SEric Christopher %within.bounds.2 = icmp ult i32 %i, %length.2 1015cee313d2SEric Christopher %within.bounds = and i1 %within.bounds.1, %within.bounds.2 1016cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1017cee313d2SEric Christopher 1018cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1019cee313d2SEric Christopher %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1020cee313d2SEric Christopher %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1021cee313d2SEric Christopher %loop.acc.1 = add i32 %loop.acc, %array.1.i 1022cee313d2SEric Christopher 1023cee313d2SEric Christopher %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1024cee313d2SEric Christopher %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1025cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc.1, %array.2.i 1026cee313d2SEric Christopher 1027cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1028cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1029cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1030cee313d2SEric Christopher 1031cee313d2SEric Christopherexit: 1032cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1033cee313d2SEric Christopher ret i32 %result 1034cee313d2SEric Christopher} 1035cee313d2SEric Christopher 1036cee313d2SEric Christopherdefine i32 @three_range_checks(i32* %array.1, i32 %length.1, 1037cee313d2SEric Christopher; CHECK-LABEL: @three_range_checks( 1038cee313d2SEric Christopher; CHECK-NEXT: entry: 1039cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1040cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1041cee313d2SEric Christopher; CHECK: loop.preheader: 1042cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1043cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1044cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1045cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1046cee313d2SEric Christopher; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1047cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 1048cee313d2SEric Christopher; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1049cee313d2SEric Christopher; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1050cee313d2SEric Christopher; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] 1051cee313d2SEric Christopher; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]] 1052cee313d2SEric Christopher; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]] 1053cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1054cee313d2SEric Christopher; CHECK: loop: 1055cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1056cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1057cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP10]], i32 9) [ "deopt"() ] 1058cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1059cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 1060cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 1061cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1062cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 1063cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 1064cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1065cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]] 1066cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4 1067cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1068cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1069cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1070cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1071cee313d2SEric Christopher; CHECK: exit.loopexit: 1072cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1073cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1074cee313d2SEric Christopher; CHECK: exit: 1075cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1076cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1077cee313d2SEric Christopher; 1078cee313d2SEric Christopher i32* %array.2, i32 %length.2, 1079cee313d2SEric Christopher i32* %array.3, i32 %length.3, i32 %n) { 1080cee313d2SEric Christopherentry: 1081cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1082cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1083cee313d2SEric Christopher 1084cee313d2SEric Christopherloop.preheader: 1085cee313d2SEric Christopher br label %loop 1086cee313d2SEric Christopher 1087cee313d2SEric Christopherloop: 1088cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1089cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1090cee313d2SEric Christopher %within.bounds.1 = icmp ult i32 %i, %length.1 1091cee313d2SEric Christopher %within.bounds.2 = icmp ult i32 %i, %length.2 1092cee313d2SEric Christopher %within.bounds.3 = icmp ult i32 %i, %length.3 1093cee313d2SEric Christopher %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2 1094cee313d2SEric Christopher %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3 1095cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1096cee313d2SEric Christopher 1097cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1098cee313d2SEric Christopher %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1099cee313d2SEric Christopher %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1100cee313d2SEric Christopher %loop.acc.1 = add i32 %loop.acc, %array.1.i 1101cee313d2SEric Christopher 1102cee313d2SEric Christopher %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1103cee313d2SEric Christopher %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1104cee313d2SEric Christopher %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1105cee313d2SEric Christopher 1106cee313d2SEric Christopher %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 1107cee313d2SEric Christopher %array.3.i = load i32, i32* %array.3.i.ptr, align 4 1108cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1109cee313d2SEric Christopher 1110cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1111cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1112cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1113cee313d2SEric Christopher 1114cee313d2SEric Christopherexit: 1115cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1116cee313d2SEric Christopher ret i32 %result 1117cee313d2SEric Christopher} 1118cee313d2SEric Christopher 1119cee313d2SEric Christopherdefine i32 @three_guards(i32* %array.1, i32 %length.1, 1120cee313d2SEric Christopher; CHECK-LABEL: @three_guards( 1121cee313d2SEric Christopher; CHECK-NEXT: entry: 1122cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1123cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1124cee313d2SEric Christopher; CHECK: loop.preheader: 1125cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1126cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1127cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1128cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1129cee313d2SEric Christopher; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1130cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 1131cee313d2SEric Christopher; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1132cee313d2SEric Christopher; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1133cee313d2SEric Christopher; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] 1134cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1135cee313d2SEric Christopher; CHECK: loop: 1136cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1137cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1138cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 1139cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1140cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 1141cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 1142cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1143cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ] 1144cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 1145cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 1146cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1147cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ] 1148cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]] 1149cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4 1150cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1151cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1152cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1153cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1154cee313d2SEric Christopher; CHECK: exit.loopexit: 1155cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1156cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1157cee313d2SEric Christopher; CHECK: exit: 1158cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1159cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1160cee313d2SEric Christopher; 1161cee313d2SEric Christopher i32* %array.2, i32 %length.2, 1162cee313d2SEric Christopher i32* %array.3, i32 %length.3, i32 %n) { 1163cee313d2SEric Christopherentry: 1164cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1165cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1166cee313d2SEric Christopher 1167cee313d2SEric Christopherloop.preheader: 1168cee313d2SEric Christopher br label %loop 1169cee313d2SEric Christopher 1170cee313d2SEric Christopherloop: 1171cee313d2SEric Christopher 1172cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1173cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1174cee313d2SEric Christopher 1175cee313d2SEric Christopher %within.bounds.1 = icmp ult i32 %i, %length.1 1176cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ] 1177cee313d2SEric Christopher 1178cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1179cee313d2SEric Christopher %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1180cee313d2SEric Christopher %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1181cee313d2SEric Christopher %loop.acc.1 = add i32 %loop.acc, %array.1.i 1182cee313d2SEric Christopher 1183cee313d2SEric Christopher %within.bounds.2 = icmp ult i32 %i, %length.2 1184cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ] 1185cee313d2SEric Christopher 1186cee313d2SEric Christopher %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1187cee313d2SEric Christopher %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1188cee313d2SEric Christopher %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1189cee313d2SEric Christopher 1190cee313d2SEric Christopher %within.bounds.3 = icmp ult i32 %i, %length.3 1191cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ] 1192cee313d2SEric Christopher 1193cee313d2SEric Christopher %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 1194cee313d2SEric Christopher %array.3.i = load i32, i32* %array.3.i.ptr, align 4 1195cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1196cee313d2SEric Christopher 1197cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1198cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1199cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1200cee313d2SEric Christopher 1201cee313d2SEric Christopherexit: 1202cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1203cee313d2SEric Christopher ret i32 %result 1204cee313d2SEric Christopher} 1205cee313d2SEric Christopher 1206cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) { 1207cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition( 1208cee313d2SEric Christopher; CHECK-NEXT: entry: 1209cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1210cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1211cee313d2SEric Christopher; CHECK: loop.preheader: 1212cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 1213cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 1214cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1215cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1216cee313d2SEric Christopher; CHECK: loop: 1217cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1218cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1219cee313d2SEric Christopher; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]] 1220cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]] 1221cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1222cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1223cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1224cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1225cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1226cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1227cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1228cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1229cee313d2SEric Christopher; CHECK: exit.loopexit: 1230cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1231cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1232cee313d2SEric Christopher; CHECK: exit: 1233cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1234cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1235cee313d2SEric Christopher; 1236cee313d2SEric Christopherentry: 1237cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1238cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1239cee313d2SEric Christopher 1240cee313d2SEric Christopherloop.preheader: 1241cee313d2SEric Christopher br label %loop 1242cee313d2SEric Christopher 1243cee313d2SEric Christopherloop: 1244cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1245cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1246cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 1247cee313d2SEric Christopher %unrelated.cond = icmp ult i32 %x, %length 1248cee313d2SEric Christopher %guard.cond = and i1 %within.bounds, %unrelated.cond 1249cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1250cee313d2SEric Christopher 1251cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1252cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1253cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1254cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1255cee313d2SEric Christopher 1256cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1257cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1258cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1259cee313d2SEric Christopher 1260cee313d2SEric Christopherexit: 1261cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1262cee313d2SEric Christopher ret i32 %result 1263cee313d2SEric Christopher} 1264cee313d2SEric Christopher 1265cee313d2SEric Christopher; Don't change the guard condition if there were no widened subconditions 1266cee313d2SEric Christopherdefine i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) { 1267cee313d2SEric Christopher; CHECK-LABEL: @test_no_widened_conditions( 1268cee313d2SEric Christopher; CHECK-NEXT: entry: 1269cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1270cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1271cee313d2SEric Christopher; CHECK: loop.preheader: 1272cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1273cee313d2SEric Christopher; CHECK: loop: 1274cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1275cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1276cee313d2SEric Christopher; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]] 1277cee313d2SEric Christopher; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]] 1278cee313d2SEric Christopher; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]] 1279cee313d2SEric Christopher; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]] 1280cee313d2SEric Christopher; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]] 1281cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ] 1282cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1283cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1284cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1285cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1286cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1287cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1288cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1289cee313d2SEric Christopher; CHECK: exit.loopexit: 1290cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1291cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1292cee313d2SEric Christopher; CHECK: exit: 1293cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1294cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1295cee313d2SEric Christopher; 1296cee313d2SEric Christopherentry: 1297cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1298cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1299cee313d2SEric Christopher 1300cee313d2SEric Christopherloop.preheader: 1301cee313d2SEric Christopher br label %loop 1302cee313d2SEric Christopher 1303cee313d2SEric Christopherloop: 1304cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1305cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1306cee313d2SEric Christopher %unrelated.cond.1 = icmp eq i32 %x1, %i 1307cee313d2SEric Christopher %unrelated.cond.2 = icmp eq i32 %x2, %i 1308cee313d2SEric Christopher %unrelated.cond.3 = icmp eq i32 %x3, %i 1309cee313d2SEric Christopher %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2 1310cee313d2SEric Christopher %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3 1311cee313d2SEric Christopher 1312cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1313cee313d2SEric Christopher 1314cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1315cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1316cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1317cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1318cee313d2SEric Christopher 1319cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1320cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1321cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1322cee313d2SEric Christopher 1323cee313d2SEric Christopherexit: 1324cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1325cee313d2SEric Christopher ret i32 %result 1326cee313d2SEric Christopher} 1327cee313d2SEric Christopher 1328cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) { 1329cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound( 1330cee313d2SEric Christopher; CHECK-NEXT: entry: 1331cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1332cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1333cee313d2SEric Christopher; CHECK: loop.preheader: 1334cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1335cee313d2SEric Christopher; CHECK: loop: 1336cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1337cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1338cee313d2SEric Christopher; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]] 1339cee313d2SEric Christopher; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]] 1340cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 1341cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1342cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1343cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1344cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1345cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1346cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1347cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1348cee313d2SEric Christopher; CHECK: exit.loopexit: 1349cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1350cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1351cee313d2SEric Christopher; CHECK: exit: 1352cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1353cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1354cee313d2SEric Christopher; 1355cee313d2SEric Christopherentry: 1356cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 1357cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1358cee313d2SEric Christopher 1359cee313d2SEric Christopherloop.preheader: 1360cee313d2SEric Christopher br label %loop 1361cee313d2SEric Christopher 1362cee313d2SEric Christopherloop: 1363cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1364cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 1365cee313d2SEric Christopher %bound = add i32 %i, %x 1366cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %bound 1367cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1368cee313d2SEric Christopher 1369cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1370cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1371cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1372cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1373cee313d2SEric Christopher 1374cee313d2SEric Christopher %i.next = add nsw i32 %i, 1 1375cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 1376cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1377cee313d2SEric Christopher 1378cee313d2SEric Christopherexit: 1379cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1380cee313d2SEric Christopher ret i32 %result 1381cee313d2SEric Christopher} 1382cee313d2SEric Christopher 1383cee313d2SEric Christopherdefine i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) { 1384cee313d2SEric Christopher; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate( 1385cee313d2SEric Christopher; CHECK-NEXT: entry: 1386cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1387cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1388cee313d2SEric Christopher; CHECK: loop.preheader: 1389cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1390cee313d2SEric Christopher; CHECK: loop: 1391cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1392cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1393cee313d2SEric Christopher; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]] 1394cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ] 1395cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1396cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1397cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1398cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1399cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1400cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1401cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1402cee313d2SEric Christopher; CHECK: exit.loopexit: 1403cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1404cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1405cee313d2SEric Christopher; CHECK: exit: 1406cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1407cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1408cee313d2SEric Christopher; 1409cee313d2SEric Christopherentry: 1410cee313d2SEric Christopher %tmp5 = icmp sle i32 %n, 0 1411cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1412cee313d2SEric Christopher 1413cee313d2SEric Christopherloop.preheader: 1414cee313d2SEric Christopher br label %loop 1415cee313d2SEric Christopher 1416cee313d2SEric Christopherloop: 1417cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1418cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 1419cee313d2SEric Christopher %guard.cond = icmp eq i32 %i, %x 1420cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1421cee313d2SEric Christopher 1422cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1423cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1424cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1425cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1426cee313d2SEric Christopher 1427cee313d2SEric Christopher %i.next = add nsw i32 %i, 1 1428cee313d2SEric Christopher %continue = icmp slt i32 %i.next, %n 1429cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1430cee313d2SEric Christopher 1431cee313d2SEric Christopherexit: 1432cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1433cee313d2SEric Christopher ret i32 %result 1434cee313d2SEric Christopher} 1435cee313d2SEric Christopher 1436cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) { 1437cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length( 1438cee313d2SEric Christopher; CHECK-NEXT: entry: 1439cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1440cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1441cee313d2SEric Christopher; CHECK: loop.preheader: 1442cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32 1443cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 1444cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]] 1445cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 1446cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1447cee313d2SEric Christopher; CHECK: loop: 1448cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1449cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1450cee313d2SEric Christopher; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1451cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1452cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1453cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1454cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1455cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1456cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1457cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1458cee313d2SEric Christopher; CHECK: exit.loopexit: 1459cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1460cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1461cee313d2SEric Christopher; CHECK: exit: 1462cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1463cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1464cee313d2SEric Christopher; 1465cee313d2SEric Christopherentry: 1466cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1467cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1468cee313d2SEric Christopher 1469cee313d2SEric Christopherloop.preheader: 1470cee313d2SEric Christopher br label %loop 1471cee313d2SEric Christopher 1472cee313d2SEric Christopherloop: 1473cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1474cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1475cee313d2SEric Christopher %length = zext i16 %length.i16 to i32 1476cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 1477cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1478cee313d2SEric Christopher 1479cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1480cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1481cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1482cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1483cee313d2SEric Christopher 1484cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1485cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1486cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1487cee313d2SEric Christopher 1488cee313d2SEric Christopherexit: 1489cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1490cee313d2SEric Christopher ret i32 %result 1491cee313d2SEric Christopher} 1492cee313d2SEric Christopher 1493cee313d2SEric Christopherdefine i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) { 1494cee313d2SEric Christopher; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length( 1495cee313d2SEric Christopher; CHECK-NEXT: entry: 1496cee313d2SEric Christopher; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1497cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1498cee313d2SEric Christopher; CHECK: loop.preheader: 1499cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1500cee313d2SEric Christopher; CHECK: loop: 1501cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1502cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1503cee313d2SEric Christopher; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]] 150492a7177eSPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]] 150592a7177eSPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]] 150692a7177eSPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 150792a7177eSPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 1508cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1509cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1510cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1511cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1512cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1513cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1514cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1515cee313d2SEric Christopher; CHECK: exit.loopexit: 1516cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1517cee313d2SEric Christopher; CHECK-NEXT: br label [[EXIT]] 1518cee313d2SEric Christopher; CHECK: exit: 1519cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1520cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1521cee313d2SEric Christopher; 1522cee313d2SEric Christopherentry: 1523cee313d2SEric Christopher %tmp5 = icmp eq i32 %n, 0 1524cee313d2SEric Christopher br i1 %tmp5, label %exit, label %loop.preheader 1525cee313d2SEric Christopher 1526cee313d2SEric Christopherloop.preheader: 1527cee313d2SEric Christopher br label %loop 1528cee313d2SEric Christopher 1529cee313d2SEric Christopherloop: 1530cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1531cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1532cee313d2SEric Christopher %length.udiv = udiv i32 %length, %divider 1533cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length.udiv 1534cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1535cee313d2SEric Christopher 1536cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1537cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1538cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1539cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1540cee313d2SEric Christopher 1541cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1542cee313d2SEric Christopher %continue = icmp ult i32 %i.next, %n 1543cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1544cee313d2SEric Christopher 1545cee313d2SEric Christopherexit: 1546cee313d2SEric Christopher %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1547cee313d2SEric Christopher ret i32 %result 1548cee313d2SEric Christopher} 1549cee313d2SEric Christopher 1550cee313d2SEric Christopher 1551cee313d2SEric Christopher; This is a case where the length information tells us that the guard 1552cee313d2SEric Christopher; must trigger on some iteration. 1553cee313d2SEric Christopherdefine i32 @provably_taken(i32* %array, i32* %length.ptr) { 1554cee313d2SEric Christopher; CHECK-LABEL: @provably_taken( 1555cee313d2SEric Christopher; CHECK-NEXT: loop.preheader: 15565a8a7b3bSRoman Lebedev; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG1:![0-9]+]] 1557cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[LENGTH]] 1558b2915971SRoman Lebedev; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], false 1559cee313d2SEric Christopher; CHECK-NEXT: br label [[LOOP:%.*]] 1560cee313d2SEric Christopher; CHECK: loop: 1561cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ] 1562cee313d2SEric Christopher; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1563b2915971SRoman Lebedev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ] 1564cee313d2SEric Christopher; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1565cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1566cee313d2SEric Christopher; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1567cee313d2SEric Christopher; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1568cee313d2SEric Christopher; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1569cee313d2SEric Christopher; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], 200 1570cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 1571cee313d2SEric Christopher; CHECK: exit: 1572cee313d2SEric Christopher; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1573cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RESULT]] 1574cee313d2SEric Christopher; 1575cee313d2SEric Christopherloop.preheader: 1576cee313d2SEric Christopher %length = load i32, i32* %length.ptr, !range !{i32 0, i32 50} 1577cee313d2SEric Christopher br label %loop 1578cee313d2SEric Christopher 1579cee313d2SEric Christopherloop: 1580cee313d2SEric Christopher %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1581cee313d2SEric Christopher %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1582cee313d2SEric Christopher %within.bounds = icmp ult i32 %i, %length 1583cee313d2SEric Christopher call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1584cee313d2SEric Christopher 1585cee313d2SEric Christopher %i.i64 = zext i32 %i to i64 1586cee313d2SEric Christopher %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1587cee313d2SEric Christopher %array.i = load i32, i32* %array.i.ptr, align 4 1588cee313d2SEric Christopher %loop.acc.next = add i32 %loop.acc, %array.i 1589cee313d2SEric Christopher 1590cee313d2SEric Christopher %i.next = add nuw i32 %i, 1 1591cee313d2SEric Christopher %continue = icmp slt i32 %i.next, 200 1592cee313d2SEric Christopher br i1 %continue, label %loop, label %exit 1593cee313d2SEric Christopher 1594cee313d2SEric Christopherexit: 1595cee313d2SEric Christopher %result = phi i32 [ %loop.acc.next, %loop ] 1596cee313d2SEric Christopher ret i32 %result 1597cee313d2SEric Christopher} 15988dda4a16SPhilip Reames 15998dda4a16SPhilip Reames; NE Check (as produced by LFTR) where we can prove Start < End via simple 16008dda4a16SPhilip Reames; instruction analysis 16018dda4a16SPhilip Reamesdefine i32 @ne_latch_zext(i32* %array, i32 %length, i16 %n16) { 16028dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_zext( 16038dda4a16SPhilip Reames; CHECK-NEXT: loop.preheader: 16048dda4a16SPhilip Reames; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i32 1605*8906a0feSPhilip Reames; CHECK-NEXT: [[NPLUS1:%.*]] = add i32 [[N]], 1 1606099eca83SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[NPLUS1]], [[LENGTH:%.*]] 1607099eca83SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 1608099eca83SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 16098dda4a16SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 16108dda4a16SPhilip Reames; CHECK: loop: 16118dda4a16SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ] 1612099eca83SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 1613fa6bcd0bSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 1614fa6bcd0bSPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]] 16158dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 16168dda4a16SPhilip Reames; CHECK: exit: 16178dda4a16SPhilip Reames; CHECK-NEXT: ret i32 0 16188dda4a16SPhilip Reames; 16198dda4a16SPhilip Reamesloop.preheader: 16208dda4a16SPhilip Reames %n = zext i16 %n16 to i32 1621fa6bcd0bSPhilip Reames %nplus1 = add nsw nuw i32 %n, 1 16228dda4a16SPhilip Reames br label %loop 16238dda4a16SPhilip Reames 16248dda4a16SPhilip Reamesloop: 16258dda4a16SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 16268dda4a16SPhilip Reames %within.bounds = icmp ult i32 %i, %length 16278dda4a16SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 16288dda4a16SPhilip Reames 1629fa6bcd0bSPhilip Reames %i.next = add nsw nuw i32 %i, 1 1630fa6bcd0bSPhilip Reames %continue = icmp ne i32 %i.next, %nplus1 16318dda4a16SPhilip Reames br i1 %continue, label %loop, label %exit 16328dda4a16SPhilip Reames 16338dda4a16SPhilip Reamesexit: 16348dda4a16SPhilip Reames ret i32 0 16358dda4a16SPhilip Reames} 16368dda4a16SPhilip Reames 1637f711d594SPhilip Reames; Same as previous, but with a pre-increment test since this is easier to match 1638f711d594SPhilip Reamesdefine i32 @ne_latch_zext_preinc(i32* %array, i32 %length, i16 %n16) { 1639f711d594SPhilip Reames; CHECK-LABEL: @ne_latch_zext_preinc( 1640f711d594SPhilip Reames; CHECK-NEXT: loop.preheader: 1641f711d594SPhilip Reames; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i32 1642099eca83SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 1643099eca83SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 1644099eca83SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 1645099eca83SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 1646f711d594SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 1647f711d594SPhilip Reames; CHECK: loop: 1648f711d594SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ] 1649099eca83SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1650f711d594SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1651f711d594SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]] 1652f711d594SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 1653f711d594SPhilip Reames; CHECK: exit: 1654f711d594SPhilip Reames; CHECK-NEXT: ret i32 0 1655f711d594SPhilip Reames; 1656f711d594SPhilip Reamesloop.preheader: 1657f711d594SPhilip Reames %n = zext i16 %n16 to i32 1658f711d594SPhilip Reames br label %loop 1659f711d594SPhilip Reames 1660f711d594SPhilip Reamesloop: 1661f711d594SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1662f711d594SPhilip Reames %within.bounds = icmp ult i32 %i, %length 1663f711d594SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1664f711d594SPhilip Reames 1665f711d594SPhilip Reames %i.next = add nuw i32 %i, 1 1666f711d594SPhilip Reames %continue = icmp ne i32 %i, %n 1667f711d594SPhilip Reames br i1 %continue, label %loop, label %exit 1668f711d594SPhilip Reames 1669f711d594SPhilip Reamesexit: 1670f711d594SPhilip Reames ret i32 0 1671f711d594SPhilip Reames} 1672f711d594SPhilip Reames 16738dda4a16SPhilip Reames; NE Check (as produced by LFTR) where we can prove Start < End via the 16748dda4a16SPhilip Reames; condition guarding the loop entry. 16758dda4a16SPhilip Reamesdefine i32 @ne_latch_dom_check(i32* %array, i32 %length, i32 %n) { 16768dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_dom_check( 16778dda4a16SPhilip Reames; CHECK-NEXT: entry: 16788dda4a16SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1679fa6bcd0bSPhilip Reames; CHECK-NEXT: [[NPLUS1:%.*]] = add nuw i32 [[N]], 1 16808dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 16818dda4a16SPhilip Reames; CHECK: loop.preheader: 16828dda4a16SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 16838dda4a16SPhilip Reames; CHECK: loop: 16848dda4a16SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 16858dda4a16SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 16868dda4a16SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 1687fa6bcd0bSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 1688fa6bcd0bSPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]] 16898dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 16908dda4a16SPhilip Reames; CHECK: exit.loopexit: 16918dda4a16SPhilip Reames; CHECK-NEXT: br label [[EXIT]] 16928dda4a16SPhilip Reames; CHECK: exit: 16938dda4a16SPhilip Reames; CHECK-NEXT: ret i32 0 16948dda4a16SPhilip Reames; 16958dda4a16SPhilip Reamesentry: 16968dda4a16SPhilip Reames %tmp5 = icmp sle i32 %n, 0 1697fa6bcd0bSPhilip Reames %nplus1 = add nuw i32 %n, 1 16988dda4a16SPhilip Reames br i1 %tmp5, label %exit, label %loop.preheader 16998dda4a16SPhilip Reames 17008dda4a16SPhilip Reamesloop.preheader: 17018dda4a16SPhilip Reames br label %loop 17028dda4a16SPhilip Reames 17038dda4a16SPhilip Reamesloop: 17048dda4a16SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 17058dda4a16SPhilip Reames %within.bounds = icmp ult i32 %i, %length 17068dda4a16SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 17078dda4a16SPhilip Reames 1708fa6bcd0bSPhilip Reames %i.next = add nsw nuw i32 %i, 1 1709fa6bcd0bSPhilip Reames %continue = icmp ne i32 %i.next, %nplus1 17108dda4a16SPhilip Reames br i1 %continue, label %loop, label %exit 17118dda4a16SPhilip Reames 17128dda4a16SPhilip Reamesexit: 17138dda4a16SPhilip Reames ret i32 0 17148dda4a16SPhilip Reames} 17158dda4a16SPhilip Reames 1716f711d594SPhilip Reames; Same as previous, but easier to match 1717f711d594SPhilip Reamesdefine i32 @ne_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) { 1718f711d594SPhilip Reames; CHECK-LABEL: @ne_latch_dom_check_preinc( 1719f711d594SPhilip Reames; CHECK-NEXT: entry: 1720f711d594SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1721f711d594SPhilip Reames; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1722f711d594SPhilip Reames; CHECK: loop.preheader: 1723099eca83SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 1724099eca83SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 1725099eca83SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 1726099eca83SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 1727f711d594SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 1728f711d594SPhilip Reames; CHECK: loop: 1729f711d594SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1730099eca83SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1731f711d594SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1732f711d594SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]] 1733f711d594SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1734f711d594SPhilip Reames; CHECK: exit.loopexit: 1735f711d594SPhilip Reames; CHECK-NEXT: br label [[EXIT]] 1736f711d594SPhilip Reames; CHECK: exit: 1737f711d594SPhilip Reames; CHECK-NEXT: ret i32 0 1738f711d594SPhilip Reames; 1739f711d594SPhilip Reamesentry: 1740f711d594SPhilip Reames %tmp5 = icmp sle i32 %n, 0 1741f711d594SPhilip Reames br i1 %tmp5, label %exit, label %loop.preheader 1742f711d594SPhilip Reames 1743f711d594SPhilip Reamesloop.preheader: 1744f711d594SPhilip Reames br label %loop 1745f711d594SPhilip Reames 1746f711d594SPhilip Reamesloop: 1747f711d594SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1748f711d594SPhilip Reames %within.bounds = icmp ult i32 %i, %length 1749f711d594SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1750f711d594SPhilip Reames 1751f711d594SPhilip Reames %i.next = add nuw i32 %i, 1 1752f711d594SPhilip Reames %continue = icmp ne i32 %i, %n 1753f711d594SPhilip Reames br i1 %continue, label %loop, label %exit 1754f711d594SPhilip Reames 1755f711d594SPhilip Reamesexit: 1756f711d594SPhilip Reames ret i32 0 1757f711d594SPhilip Reames} 1758f711d594SPhilip Reames 17595a637cbdSPhilip Reames; Same as previous, except swapped br/cmp 17605a637cbdSPhilip Reamesdefine i32 @eq_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) { 17615a637cbdSPhilip Reames; CHECK-LABEL: @eq_latch_dom_check_preinc( 17625a637cbdSPhilip Reames; CHECK-NEXT: entry: 17635a637cbdSPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 17645a637cbdSPhilip Reames; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 17655a637cbdSPhilip Reames; CHECK: loop.preheader: 17665a637cbdSPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 17675a637cbdSPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 17685a637cbdSPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 17695a637cbdSPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 17705a637cbdSPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 17715a637cbdSPhilip Reames; CHECK: loop: 17725a637cbdSPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 17735a637cbdSPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 17745a637cbdSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 17755a637cbdSPhilip Reames; CHECK-NEXT: [[DONE:%.*]] = icmp eq i32 [[I]], [[N]] 17765a637cbdSPhilip Reames; CHECK-NEXT: br i1 [[DONE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]] 17775a637cbdSPhilip Reames; CHECK: exit.loopexit: 17785a637cbdSPhilip Reames; CHECK-NEXT: br label [[EXIT]] 17795a637cbdSPhilip Reames; CHECK: exit: 17805a637cbdSPhilip Reames; CHECK-NEXT: ret i32 0 17815a637cbdSPhilip Reames; 17825a637cbdSPhilip Reamesentry: 17835a637cbdSPhilip Reames %tmp5 = icmp sle i32 %n, 0 17845a637cbdSPhilip Reames br i1 %tmp5, label %exit, label %loop.preheader 17855a637cbdSPhilip Reames 17865a637cbdSPhilip Reamesloop.preheader: 17875a637cbdSPhilip Reames br label %loop 17885a637cbdSPhilip Reames 17895a637cbdSPhilip Reamesloop: 17905a637cbdSPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 17915a637cbdSPhilip Reames %within.bounds = icmp ult i32 %i, %length 17925a637cbdSPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 17935a637cbdSPhilip Reames 17945a637cbdSPhilip Reames %i.next = add nuw i32 %i, 1 17955a637cbdSPhilip Reames %done = icmp eq i32 %i, %n 17965a637cbdSPhilip Reames br i1 %done, label %exit, label %loop 17975a637cbdSPhilip Reames 17985a637cbdSPhilip Reamesexit: 17995a637cbdSPhilip Reames ret i32 0 18005a637cbdSPhilip Reames} 18015a637cbdSPhilip Reames 1802f711d594SPhilip Reames 18038dda4a16SPhilip Reames; NE latch - can't prove (end-start) mod step == 0 (i.e. might wrap 18048dda4a16SPhilip Reames; around several times or even be infinite) 18058dda4a16SPhilip Reamesdefine i32 @neg_ne_latch_mod_step(i32* %array, i32 %length, i16 %n16) { 18068dda4a16SPhilip Reames; CHECK-LABEL: @neg_ne_latch_mod_step( 18078dda4a16SPhilip Reames; CHECK-NEXT: loop.preheader: 18088dda4a16SPhilip Reames; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i32 18098dda4a16SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 18108dda4a16SPhilip Reames; CHECK: loop: 18118dda4a16SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ] 18128dda4a16SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 18138dda4a16SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 18148dda4a16SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 3 1815f711d594SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]] 18168dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 18178dda4a16SPhilip Reames; CHECK: exit: 18188dda4a16SPhilip Reames; CHECK-NEXT: ret i32 0 18198dda4a16SPhilip Reames; 18208dda4a16SPhilip Reamesloop.preheader: 18218dda4a16SPhilip Reames %n = zext i16 %n16 to i32 18228dda4a16SPhilip Reames br label %loop 18238dda4a16SPhilip Reames 18248dda4a16SPhilip Reamesloop: 18258dda4a16SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 18268dda4a16SPhilip Reames %within.bounds = icmp ult i32 %i, %length 18278dda4a16SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 18288dda4a16SPhilip Reames 18298dda4a16SPhilip Reames %i.next = add i32 %i, 3 1830f711d594SPhilip Reames %continue = icmp ne i32 %i, %n 18318dda4a16SPhilip Reames br i1 %continue, label %loop, label %exit 18328dda4a16SPhilip Reames 18338dda4a16SPhilip Reamesexit: 18348dda4a16SPhilip Reames ret i32 0 18358dda4a16SPhilip Reames} 18368dda4a16SPhilip Reames 18378dda4a16SPhilip Reames; NE latch - TODO: could prove (end-start) mod step == 0 18388dda4a16SPhilip Reamesdefine i32 @ne_latch_mod_step(i32* %array, i32 %length) { 18398dda4a16SPhilip Reames; CHECK-LABEL: @ne_latch_mod_step( 18408dda4a16SPhilip Reames; CHECK-NEXT: loop.preheader: 18418dda4a16SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 18428dda4a16SPhilip Reames; CHECK: loop: 18438dda4a16SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ] 18448dda4a16SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 18458dda4a16SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 18468dda4a16SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 2 1847f711d594SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], 400 18488dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 18498dda4a16SPhilip Reames; CHECK: exit: 18508dda4a16SPhilip Reames; CHECK-NEXT: ret i32 0 18518dda4a16SPhilip Reames; 18528dda4a16SPhilip Reamesloop.preheader: 18538dda4a16SPhilip Reames br label %loop 18548dda4a16SPhilip Reames 18558dda4a16SPhilip Reamesloop: 18568dda4a16SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 18578dda4a16SPhilip Reames %within.bounds = icmp ult i32 %i, %length 18588dda4a16SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 18598dda4a16SPhilip Reames 18608dda4a16SPhilip Reames %i.next = add nuw i32 %i, 2 1861f711d594SPhilip Reames %continue = icmp ne i32 %i, 400 18628dda4a16SPhilip Reames br i1 %continue, label %loop, label %exit 18638dda4a16SPhilip Reames 18648dda4a16SPhilip Reamesexit: 18658dda4a16SPhilip Reames ret i32 0 18668dda4a16SPhilip Reames} 18678dda4a16SPhilip Reames 18688dda4a16SPhilip Reames; NE Latch - but end > start so wraps around and not equivelent to a ult 18698dda4a16SPhilip Reamesdefine i32 @neg_ne_latch_swapped_order(i32* %array, i32 %length) { 18708dda4a16SPhilip Reames; CHECK-LABEL: @neg_ne_latch_swapped_order( 18718dda4a16SPhilip Reames; CHECK-NEXT: loop.preheader: 18728dda4a16SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 18738dda4a16SPhilip Reames; CHECK: loop: 18748dda4a16SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ] 18758dda4a16SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 18768dda4a16SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 18778dda4a16SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 1878f711d594SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], 0 18798dda4a16SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 18808dda4a16SPhilip Reames; CHECK: exit: 18818dda4a16SPhilip Reames; CHECK-NEXT: ret i32 0 18828dda4a16SPhilip Reames; 18838dda4a16SPhilip Reamesloop.preheader: 18848dda4a16SPhilip Reames br label %loop 18858dda4a16SPhilip Reames 18868dda4a16SPhilip Reamesloop: 18878dda4a16SPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ] 18888dda4a16SPhilip Reames %within.bounds = icmp ult i32 %i, %length 18898dda4a16SPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 18908dda4a16SPhilip Reames 18918dda4a16SPhilip Reames %i.next = add i32 %i, 1 1892f711d594SPhilip Reames %continue = icmp ne i32 %i, 0 18938dda4a16SPhilip Reames br i1 %continue, label %loop, label %exit 18948dda4a16SPhilip Reames 18958dda4a16SPhilip Reamesexit: 18968dda4a16SPhilip Reames ret i32 0 18978dda4a16SPhilip Reames} 18988dda4a16SPhilip Reames 1899101915cfSPhilip Reames; Negative test, make sure we don't crash on unconditional latches 1900101915cfSPhilip Reames; TODO: there's no reason we shouldn't be able to predicate the 1901101915cfSPhilip Reames; condition for an statically infinite loop. 1902101915cfSPhilip Reamesdefine i32 @unconditional_latch(i32* %a, i32 %length) { 1903101915cfSPhilip Reames; CHECK-LABEL: @unconditional_latch( 1904101915cfSPhilip Reames; CHECK-NEXT: loop.preheader: 1905101915cfSPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 1906101915cfSPhilip Reames; CHECK: loop: 1907101915cfSPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ] 1908101915cfSPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 1909101915cfSPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 19105a8a7b3bSRoman Lebedev; CHECK-NEXT: store volatile i32 0, i32* [[A:%.*]], align 4 1911101915cfSPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 1912101915cfSPhilip Reames; CHECK-NEXT: br label [[LOOP]] 1913101915cfSPhilip Reames; 1914101915cfSPhilip Reamesloop.preheader: 1915101915cfSPhilip Reames br label %loop 1916101915cfSPhilip Reames 1917101915cfSPhilip Reamesloop: 1918101915cfSPhilip Reames %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ] 1919101915cfSPhilip Reames %within.bounds = icmp ult i32 %i, %length 1920101915cfSPhilip Reames call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1921101915cfSPhilip Reames store volatile i32 0, i32* %a 1922101915cfSPhilip Reames %i.next = add i32 %i, 1 1923101915cfSPhilip Reames br label %loop 1924101915cfSPhilip Reames} 1925