1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s 3; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s 4 5declare void @llvm.experimental.guard(i1, ...) 6 7define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 8; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 11; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 12; CHECK: loop.preheader: 13; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 14; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 15; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 16; CHECK-NEXT: br label [[LOOP:%.*]] 17; CHECK: loop: 18; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 19; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 20; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 21; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 22; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 23; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 24; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 25; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 26; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 27; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 28; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 29; CHECK: exit.loopexit: 30; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 31; CHECK-NEXT: br label [[EXIT]] 32; CHECK: exit: 33; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 34; CHECK-NEXT: ret i32 [[RESULT]] 35; 36entry: 37 %tmp5 = icmp eq i32 %n, 0 38 br i1 %tmp5, label %exit, label %loop.preheader 39 40loop.preheader: 41 br label %loop 42 43loop: 44 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 45 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 46 %within.bounds = icmp ult i32 %i, %length 47 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 48 49 %i.i64 = zext i32 %i to i64 50 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 51 %array.i = load i32, i32* %array.i.ptr, align 4 52 %loop.acc.next = add i32 %loop.acc, %array.i 53 54 %i.next = add nuw i32 %i, 1 55 %continue = icmp ult i32 %i.next, %n 56 br i1 %continue, label %loop, label %exit 57 58exit: 59 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 60 ret i32 %result 61} 62 63define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) { 64; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check( 65; CHECK-NEXT: entry: 66; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 67; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 68; CHECK: loop.preheader: 69; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]] 70; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 71; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 72; CHECK-NEXT: br label [[LOOP:%.*]] 73; CHECK: loop: 74; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 75; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 76; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 77; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 78; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 79; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 80; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 81; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 82; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 83; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]] 84; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 85; CHECK: exit.loopexit: 86; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 87; CHECK-NEXT: br label [[EXIT]] 88; CHECK: exit: 89; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 90; CHECK-NEXT: ret i32 [[RESULT]] 91; 92entry: 93 %tmp5 = icmp eq i32 %n, 0 94 br i1 %tmp5, label %exit, label %loop.preheader 95 96loop.preheader: 97 br label %loop 98 99loop: 100 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 101 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 102 %within.bounds = icmp ult i32 %i, %length 103 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 104 105 %i.i64 = zext i32 %i to i64 106 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 107 %array.i = load i32, i32* %array.i.ptr, align 4 108 %loop.acc.next = add i32 %loop.acc, %array.i 109 110 %i.next = add nuw i32 %i, 1 111 %continue = icmp ule i32 %i.next, %n 112 br i1 %continue, label %loop, label %exit 113 114exit: 115 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 116 ret i32 %result 117} 118 119define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) { 120; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check( 121; CHECK-NEXT: entry: 122; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 123; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 124; CHECK: loop.preheader: 125; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 126; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 127; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 128; CHECK-NEXT: br label [[LOOP:%.*]] 129; CHECK: loop: 130; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 131; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 132; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]] 133; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 134; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 135; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 136; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 137; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 138; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 139; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 140; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 141; CHECK: exit.loopexit: 142; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 143; CHECK-NEXT: br label [[EXIT]] 144; CHECK: exit: 145; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 146; CHECK-NEXT: ret i32 [[RESULT]] 147; 148entry: 149 %tmp5 = icmp eq i32 %n, 0 150 br i1 %tmp5, label %exit, label %loop.preheader 151 152loop.preheader: 153 br label %loop 154 155loop: 156 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 157 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 158 %within.bounds = icmp ugt i32 %length, %i 159 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 160 161 %i.i64 = zext i32 %i to i64 162 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 163 %array.i = load i32, i32* %array.i.ptr, align 4 164 %loop.acc.next = add i32 %loop.acc, %array.i 165 166 %i.next = add nuw i32 %i, 1 167 %continue = icmp ult i32 %i.next, %n 168 br i1 %continue, label %loop, label %exit 169 170exit: 171 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 172 ret i32 %result 173} 174 175define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 176; CHECK-LABEL: @signed_loop_0_to_n_ult_check( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 179; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 180; CHECK: loop.preheader: 181; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 182; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 183; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 184; CHECK-NEXT: br label [[LOOP:%.*]] 185; CHECK: loop: 186; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 187; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 188; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 189; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 190; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 191; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 192; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 193; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 194; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 195; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 196; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 197; CHECK: exit.loopexit: 198; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 199; CHECK-NEXT: br label [[EXIT]] 200; CHECK: exit: 201; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 202; CHECK-NEXT: ret i32 [[RESULT]] 203; 204entry: 205 %tmp5 = icmp sle i32 %n, 0 206 br i1 %tmp5, label %exit, label %loop.preheader 207 208loop.preheader: 209 br label %loop 210 211loop: 212 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 213 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 214 %within.bounds = icmp ult i32 %i, %length 215 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 216 217 %i.i64 = zext i32 %i to i64 218 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 219 %array.i = load i32, i32* %array.i.ptr, align 4 220 %loop.acc.next = add i32 %loop.acc, %array.i 221 222 %i.next = add nuw i32 %i, 1 223 %continue = icmp slt i32 %i.next, %n 224 br i1 %continue, label %loop, label %exit 225 226exit: 227 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 228 ret i32 %result 229} 230 231define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) { 232; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known( 233; CHECK-NEXT: entry: 234; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 235; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], !range !0 236; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 237; CHECK: loop.preheader: 238; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]] 239; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]] 240; CHECK-NEXT: br label [[LOOP:%.*]] 241; CHECK: loop: 242; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 243; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 244; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 245; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ] 246; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 247; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 248; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 249; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 250; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 251; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 252; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 253; CHECK: exit.loopexit: 254; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 255; CHECK-NEXT: br label [[EXIT]] 256; CHECK: exit: 257; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 258; CHECK-NEXT: ret i32 [[RESULT]] 259; 260entry: 261 %tmp5 = icmp sle i32 %n, 0 262 %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648} 263 br i1 %tmp5, label %exit, label %loop.preheader 264 265loop.preheader: 266 br label %loop 267 268loop: 269 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 270 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 271 %within.bounds = icmp ult i32 %i, %length 272 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 273 274 %i.i64 = zext i32 %i to i64 275 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 276 %array.i = load i32, i32* %array.i.ptr, align 4 277 %loop.acc.next = add i32 %loop.acc, %array.i 278 279 %i.next = add nuw i32 %i, 1 280 %continue = icmp slt i32 %i.next, %n 281 br i1 %continue, label %loop, label %exit 282 283exit: 284 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 285 ret i32 %result 286} 287 288define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) { 289; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate( 290; CHECK-NEXT: entry: 291; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 292; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 293; CHECK: loop.preheader: 294; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 295; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 296; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 297; CHECK-NEXT: br label [[LOOP:%.*]] 298; CHECK: loop: 299; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 300; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 301; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 302; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 303; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 304; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 305; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 306; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 307; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 308; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]] 309; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]] 310; CHECK: exit.loopexit: 311; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 312; CHECK-NEXT: br label [[EXIT]] 313; CHECK: exit: 314; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 315; CHECK-NEXT: ret i32 [[RESULT]] 316; 317entry: 318 %tmp5 = icmp sle i32 %n, 0 319 br i1 %tmp5, label %exit, label %loop.preheader 320 321loop.preheader: 322 br label %loop 323 324loop: 325 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 326 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 327 %within.bounds = icmp ult i32 %i, %length 328 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 329 330 %i.i64 = zext i32 %i to i64 331 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 332 %array.i = load i32, i32* %array.i.ptr, align 4 333 %loop.acc.next = add i32 %loop.acc, %array.i 334 335 %i.next = add nuw i32 %i, 1 336 %continue = icmp sgt i32 %i.next, %n 337 br i1 %continue, label %exit, label %loop 338 339exit: 340 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 341 ret i32 %result 342} 343 344define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) { 345; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check( 346; CHECK-NEXT: entry: 347; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 348; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 349; CHECK: loop.preheader: 350; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 351; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 352; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 353; CHECK-NEXT: br label [[LOOP:%.*]] 354; CHECK: loop: 355; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 356; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 357; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 358; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 359; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 360; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 361; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 362; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 363; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 364; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 365; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 366; CHECK: exit.loopexit: 367; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 368; CHECK-NEXT: br label [[EXIT]] 369; CHECK: exit: 370; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 371; CHECK-NEXT: ret i32 [[RESULT]] 372; 373entry: 374 %tmp5 = icmp sle i32 %n, 0 375 br i1 %tmp5, label %exit, label %loop.preheader 376 377loop.preheader: 378 br label %loop 379 380loop: 381 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 382 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 383 %within.bounds = icmp ult i32 %i, %length 384 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 385 386 %i.i64 = zext i32 %i to i64 387 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 388 %array.i = load i32, i32* %array.i.ptr, align 4 389 %loop.acc.next = add i32 %loop.acc, %array.i 390 391 %i.next = add nuw i32 %i, 1 392 %continue = icmp sle i32 %i.next, %n 393 br i1 %continue, label %loop, label %exit 394 395exit: 396 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 397 ret i32 %result 398} 399 400define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) { 401; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check( 402; CHECK-NEXT: entry: 403; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 404; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 405; CHECK: loop.preheader: 406; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 407; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 408; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 409; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 410; CHECK-NEXT: br label [[LOOP:%.*]] 411; CHECK: loop: 412; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 413; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 414; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 415; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 416; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 417; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 418; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 419; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 420; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 421; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 422; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 423; CHECK: exit.loopexit: 424; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 425; CHECK-NEXT: br label [[EXIT]] 426; CHECK: exit: 427; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 428; CHECK-NEXT: ret i32 [[RESULT]] 429; 430entry: 431 %tmp5 = icmp sle i32 %n, 0 432 br i1 %tmp5, label %exit, label %loop.preheader 433 434loop.preheader: 435 br label %loop 436 437loop: 438 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 439 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 440 %within.bounds = icmp ult i32 %i, %length 441 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 442 443 %i.i64 = zext i32 %i to i64 444 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 445 %array.i = load i32, i32* %array.i.ptr, align 4 446 %loop.acc.next = add i32 %loop.acc, %array.i 447 448 %i.next = add i32 %i, 1 449 %continue = icmp slt i32 %i, %n 450 br i1 %continue, label %loop, label %exit 451 452exit: 453 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 454 ret i32 %result 455} 456 457define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) { 458; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check( 459; CHECK-NEXT: entry: 460; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 461; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 462; CHECK: loop.preheader: 463; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2 464; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 465; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 466; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 467; CHECK-NEXT: br label [[LOOP:%.*]] 468; CHECK: loop: 469; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 470; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 471; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 472; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] 473; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 474; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 475; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 476; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 477; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 478; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 479; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 480; CHECK: exit.loopexit: 481; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 482; CHECK-NEXT: br label [[EXIT]] 483; CHECK: exit: 484; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 485; CHECK-NEXT: ret i32 [[RESULT]] 486; 487entry: 488 %tmp5 = icmp sle i32 %n, 0 489 br i1 %tmp5, label %exit, label %loop.preheader 490 491loop.preheader: 492 br label %loop 493 494loop: 495 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 496 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 497 498 %i.next = add i32 %i, 1 499 %within.bounds = icmp ult i32 %i.next, %length 500 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 501 502 %i.i64 = zext i32 %i to i64 503 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 504 %array.i = load i32, i32* %array.i.ptr, align 4 505 %loop.acc.next = add i32 %loop.acc, %array.i 506 507 %continue = icmp slt i32 %i, %n 508 br i1 %continue, label %loop, label %exit 509 510exit: 511 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 512 ret i32 %result 513} 514 515define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 516; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check( 517; CHECK-NEXT: entry: 518; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 519; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 520; CHECK: loop.preheader: 521; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 522; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]] 523; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 524; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 525; CHECK-NEXT: br label [[LOOP:%.*]] 526; CHECK: loop: 527; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 528; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 529; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 530; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] 531; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 532; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 533; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 534; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 535; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 536; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 537; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 538; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 539; CHECK: exit.loopexit: 540; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 541; CHECK-NEXT: br label [[EXIT]] 542; CHECK: exit: 543; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 544; CHECK-NEXT: ret i32 [[RESULT]] 545; 546entry: 547 %tmp5 = icmp sle i32 %n, 0 548 br i1 %tmp5, label %exit, label %loop.preheader 549 550loop.preheader: 551 br label %loop 552 553loop: 554 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 555 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 556 %i.offset = add i32 %i, 1 557 %within.bounds = icmp ult i32 %i.offset, %length 558 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 559 560 %i.i64 = zext i32 %i to i64 561 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 562 %array.i = load i32, i32* %array.i.ptr, align 4 563 %loop.acc.next = add i32 %loop.acc, %array.i 564 565 %i.next = add i32 %i, 1 566 %continue = icmp sle i32 %i.next, %n 567 br i1 %continue, label %loop, label %exit 568 569exit: 570 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 571 ret i32 %result 572} 573 574define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 575; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check( 576; CHECK-NEXT: entry: 577; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 578; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 579; CHECK: loop.preheader: 580; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 581; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]] 582; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 583; CHECK-NEXT: br label [[LOOP:%.*]] 584; CHECK: loop: 585; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 586; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 587; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 588; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] 589; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 590; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 591; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 592; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 593; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 594; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 595; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1 596; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]] 597; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 598; CHECK: exit.loopexit: 599; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 600; CHECK-NEXT: br label [[EXIT]] 601; CHECK: exit: 602; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 603; CHECK-NEXT: ret i32 [[RESULT]] 604; 605entry: 606 %tmp5 = icmp sle i32 %n, 0 607 br i1 %tmp5, label %exit, label %loop.preheader 608 609loop.preheader: 610 br label %loop 611 612loop: 613 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 614 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 615 %i.offset = add i32 %i, 1 616 %within.bounds = icmp ult i32 %i.offset, %length 617 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 618 619 %i.i64 = zext i32 %i to i64 620 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 621 %array.i = load i32, i32* %array.i.ptr, align 4 622 %loop.acc.next = add i32 %loop.acc, %array.i 623 624 %i.next = add i32 %i, 1 625 %i.next.offset = add i32 %i.next, 1 626 %continue = icmp sle i32 %i.next.offset, %n 627 br i1 %continue, label %loop, label %exit 628 629exit: 630 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 631 ret i32 %result 632} 633 634define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) { 635; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n( 636; CHECK-NEXT: entry: 637; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 638; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 639; CHECK: loop.preheader: 640; CHECK-NEXT: br label [[LOOP:%.*]] 641; CHECK: loop: 642; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 643; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 644; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 645; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 646; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 647; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 648; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 649; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 650; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 651; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]] 652; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 653; CHECK: exit.loopexit: 654; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 655; CHECK-NEXT: br label [[EXIT]] 656; CHECK: exit: 657; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 658; CHECK-NEXT: ret i32 [[RESULT]] 659; 660entry: 661 %tmp5 = icmp sle i32 %n, 0 662 br i1 %tmp5, label %exit, label %loop.preheader 663 664loop.preheader: 665 br label %loop 666 667loop: 668 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 669 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 670 %within.bounds = icmp ult i32 %i, %length 671 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 672 673 %i.i64 = zext i32 %i to i64 674 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 675 %array.i = load i32, i32* %array.i.ptr, align 4 676 %loop.acc.next = add i32 %loop.acc, %array.i 677 678 %i.next = add nsw i32 %i, 1 679 %continue = icmp ne i32 %i.next, %n 680 br i1 %continue, label %loop, label %exit 681 682exit: 683 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 684 ret i32 %result 685} 686 687define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) { 688; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step( 689; CHECK-NEXT: entry: 690; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 691; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 692; CHECK: loop.preheader: 693; CHECK-NEXT: br label [[LOOP:%.*]] 694; CHECK: loop: 695; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 696; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 697; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 698; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 699; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 700; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 701; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 702; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 703; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2 704; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 705; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 706; CHECK: exit.loopexit: 707; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 708; CHECK-NEXT: br label [[EXIT]] 709; CHECK: exit: 710; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 711; CHECK-NEXT: ret i32 [[RESULT]] 712; 713entry: 714 %tmp5 = icmp sle i32 %n, 0 715 br i1 %tmp5, label %exit, label %loop.preheader 716 717loop.preheader: 718 br label %loop 719 720loop: 721 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 722 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 723 %within.bounds = icmp ult i32 %i, %length 724 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 725 726 %i.i64 = zext i32 %i to i64 727 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 728 %array.i = load i32, i32* %array.i.ptr, align 4 729 %loop.acc.next = add i32 %loop.acc, %array.i 730 731 %i.next = add nsw i32 %i, 2 732 %continue = icmp slt i32 %i.next, %n 733 br i1 %continue, label %loop, label %exit 734 735exit: 736 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 737 ret i32 %result 738} 739 740define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) { 741; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check( 742; CHECK-NEXT: entry: 743; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 744; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 745; CHECK: loop.preheader: 746; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 747; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 748; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 749; CHECK-NEXT: br label [[LOOP:%.*]] 750; CHECK: loop: 751; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 752; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 753; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 754; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] 755; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 756; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 757; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 758; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 759; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 760; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1 761; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 762; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 763; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 764; CHECK: exit.loopexit: 765; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 766; CHECK-NEXT: br label [[EXIT]] 767; CHECK: exit: 768; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 769; CHECK-NEXT: ret i32 [[RESULT]] 770; 771entry: 772 %tmp5 = icmp sle i32 %n, 0 773 br i1 %tmp5, label %exit, label %loop.preheader 774 775loop.preheader: 776 br label %loop 777 778loop: 779 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 780 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 781 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 782 783 %within.bounds = icmp ult i32 %j, %length 784 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 785 786 %i.i64 = zext i32 %i to i64 787 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 788 %array.i = load i32, i32* %array.i.ptr, align 4 789 %loop.acc.next = add i32 %loop.acc, %array.i 790 791 %j.next = add nsw i32 %j, 1 792 %i.next = add nsw i32 %i, 1 793 %continue = icmp slt i32 %i.next, %n 794 br i1 %continue, label %loop, label %exit 795 796exit: 797 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 798 ret i32 %result 799} 800 801define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, 802; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check( 803; CHECK-NEXT: entry: 804; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 805; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 806; CHECK: loop.preheader: 807; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]] 808; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]] 809; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]] 810; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]] 811; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]] 812; CHECK-NEXT: br label [[LOOP:%.*]] 813; CHECK: loop: 814; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 815; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ] 816; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ] 817; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] 818; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ] 819; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 820; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 821; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 822; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 823; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 824; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 825; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 826; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 827; CHECK: exit.loopexit: 828; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 829; CHECK-NEXT: br label [[EXIT]] 830; CHECK: exit: 831; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 832; CHECK-NEXT: ret i32 [[RESULT]] 833; 834 i32 %start.j, i32 %length, 835 i32 %n) { 836entry: 837 %tmp5 = icmp sle i32 %n, 0 838 br i1 %tmp5, label %exit, label %loop.preheader 839 840loop.preheader: 841 br label %loop 842 843loop: 844 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 845 %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ] 846 %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ] 847 848 %within.bounds = icmp ult i32 %j, %length 849 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 850 851 %i.i64 = zext i32 %i to i64 852 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 853 %array.i = load i32, i32* %array.i.ptr, align 4 854 %loop.acc.next = add i32 %loop.acc, %array.i 855 856 %j.next = add i32 %j, 1 857 %i.next = add i32 %i, 1 858 %continue = icmp slt i32 %i.next, %n 859 br i1 %continue, label %loop, label %exit 860 861exit: 862 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 863 ret i32 %result 864} 865 866define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) { 867; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types( 868; CHECK-NEXT: entry: 869; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 870; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 871; CHECK: loop.preheader: 872; CHECK-NEXT: br label [[LOOP:%.*]] 873; CHECK: loop: 874; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 875; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 876; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 877; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]] 878; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 879; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 880; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 881; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 882; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 883; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1 884; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 885; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 886; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 887; CHECK: exit.loopexit: 888; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 889; CHECK-NEXT: br label [[EXIT]] 890; CHECK: exit: 891; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 892; CHECK-NEXT: ret i32 [[RESULT]] 893; 894entry: 895 %tmp5 = icmp sle i32 %n, 0 896 br i1 %tmp5, label %exit, label %loop.preheader 897 898loop.preheader: 899 br label %loop 900 901loop: 902 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 903 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 904 %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ] 905 906 %within.bounds = icmp ult i16 %j, %length 907 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 908 909 %i.i64 = zext i32 %i to i64 910 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 911 %array.i = load i32, i32* %array.i.ptr, align 4 912 %loop.acc.next = add i32 %loop.acc, %array.i 913 914 %j.next = add i16 %j, 1 915 %i.next = add i32 %i, 1 916 %continue = icmp slt i32 %i.next, %n 917 br i1 %continue, label %loop, label %exit 918 919exit: 920 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 921 ret i32 %result 922} 923 924define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) { 925; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides( 926; CHECK-NEXT: entry: 927; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 928; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 929; CHECK: loop.preheader: 930; CHECK-NEXT: br label [[LOOP:%.*]] 931; CHECK: loop: 932; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 933; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 934; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 935; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]] 936; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 937; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 938; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 939; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 940; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 941; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2 942; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 943; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 944; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 945; CHECK: exit.loopexit: 946; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 947; CHECK-NEXT: br label [[EXIT]] 948; CHECK: exit: 949; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 950; CHECK-NEXT: ret i32 [[RESULT]] 951; 952entry: 953 %tmp5 = icmp sle i32 %n, 0 954 br i1 %tmp5, label %exit, label %loop.preheader 955 956loop.preheader: 957 br label %loop 958 959loop: 960 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 961 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 962 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 963 964 %within.bounds = icmp ult i32 %j, %length 965 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 966 967 %i.i64 = zext i32 %i to i64 968 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 969 %array.i = load i32, i32* %array.i.ptr, align 4 970 %loop.acc.next = add i32 %loop.acc, %array.i 971 972 %j.next = add nsw i32 %j, 2 973 %i.next = add nsw i32 %i, 1 974 %continue = icmp slt i32 %i.next, %n 975 br i1 %continue, label %loop, label %exit 976 977exit: 978 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 979 ret i32 %result 980} 981 982define i32 @two_range_checks(i32* %array.1, i32 %length.1, 983; CHECK-LABEL: @two_range_checks( 984; CHECK-NEXT: entry: 985; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 986; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 987; CHECK: loop.preheader: 988; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 989; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]] 990; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 991; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 992; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]] 993; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 994; CHECK-NEXT: br label [[LOOP:%.*]] 995; CHECK: loop: 996; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 997; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 998; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 999; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1000; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]] 1001; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]] 1002; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ] 1003; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1004; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 1005; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 1006; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1007; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 1008; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 1009; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1010; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1011; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1012; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1013; CHECK: exit.loopexit: 1014; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1015; CHECK-NEXT: br label [[EXIT]] 1016; CHECK: exit: 1017; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1018; CHECK-NEXT: ret i32 [[RESULT]] 1019; 1020 i32* %array.2, i32 %length.2, i32 %n) { 1021entry: 1022 %tmp5 = icmp eq i32 %n, 0 1023 br i1 %tmp5, label %exit, label %loop.preheader 1024 1025loop.preheader: 1026 br label %loop 1027 1028loop: 1029 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1030 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1031 %within.bounds.1 = icmp ult i32 %i, %length.1 1032 %within.bounds.2 = icmp ult i32 %i, %length.2 1033 %within.bounds = and i1 %within.bounds.1, %within.bounds.2 1034 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1035 1036 %i.i64 = zext i32 %i to i64 1037 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1038 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1039 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1040 1041 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1042 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1043 %loop.acc.next = add i32 %loop.acc.1, %array.2.i 1044 1045 %i.next = add nuw i32 %i, 1 1046 %continue = icmp ult i32 %i.next, %n 1047 br i1 %continue, label %loop, label %exit 1048 1049exit: 1050 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1051 ret i32 %result 1052} 1053 1054define i32 @three_range_checks(i32* %array.1, i32 %length.1, 1055; CHECK-LABEL: @three_range_checks( 1056; CHECK-NEXT: entry: 1057; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1058; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1059; CHECK: loop.preheader: 1060; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1061; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1062; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1063; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1064; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1065; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 1066; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1067; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1068; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] 1069; CHECK-NEXT: br label [[LOOP:%.*]] 1070; CHECK: loop: 1071; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1072; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1073; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 1074; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1075; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] 1076; CHECK-NEXT: [[WITHIN_BOUNDS_1_AND_2:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]] 1077; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1_AND_2]], [[WITHIN_BOUNDS_3]] 1078; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]] 1079; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]] 1080; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP10]], i32 9) [ "deopt"() ] 1081; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1082; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 1083; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 1084; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1085; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 1086; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 1087; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1088; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]] 1089; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4 1090; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1091; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1092; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1093; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1094; CHECK: exit.loopexit: 1095; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1096; CHECK-NEXT: br label [[EXIT]] 1097; CHECK: exit: 1098; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1099; CHECK-NEXT: ret i32 [[RESULT]] 1100; 1101 i32* %array.2, i32 %length.2, 1102 i32* %array.3, i32 %length.3, i32 %n) { 1103entry: 1104 %tmp5 = icmp eq i32 %n, 0 1105 br i1 %tmp5, label %exit, label %loop.preheader 1106 1107loop.preheader: 1108 br label %loop 1109 1110loop: 1111 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1112 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1113 %within.bounds.1 = icmp ult i32 %i, %length.1 1114 %within.bounds.2 = icmp ult i32 %i, %length.2 1115 %within.bounds.3 = icmp ult i32 %i, %length.3 1116 %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2 1117 %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3 1118 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1119 1120 %i.i64 = zext i32 %i to i64 1121 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1122 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1123 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1124 1125 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1126 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1127 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1128 1129 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 1130 %array.3.i = load i32, i32* %array.3.i.ptr, align 4 1131 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1132 1133 %i.next = add nuw i32 %i, 1 1134 %continue = icmp ult i32 %i.next, %n 1135 br i1 %continue, label %loop, label %exit 1136 1137exit: 1138 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1139 ret i32 %result 1140} 1141 1142define i32 @three_guards(i32* %array.1, i32 %length.1, 1143; CHECK-LABEL: @three_guards( 1144; CHECK-NEXT: entry: 1145; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1146; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1147; CHECK: loop.preheader: 1148; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1149; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1150; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1151; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1152; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1153; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]] 1154; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1155; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1156; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]] 1157; CHECK-NEXT: br label [[LOOP:%.*]] 1158; CHECK: loop: 1159; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1160; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1161; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 1162; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ] 1163; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1164; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]] 1165; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4 1166; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1167; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1168; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ] 1169; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]] 1170; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4 1171; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1172; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] 1173; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ] 1174; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]] 1175; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4 1176; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1177; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1178; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1179; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1180; CHECK: exit.loopexit: 1181; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1182; CHECK-NEXT: br label [[EXIT]] 1183; CHECK: exit: 1184; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1185; CHECK-NEXT: ret i32 [[RESULT]] 1186; 1187 i32* %array.2, i32 %length.2, 1188 i32* %array.3, i32 %length.3, i32 %n) { 1189entry: 1190 %tmp5 = icmp eq i32 %n, 0 1191 br i1 %tmp5, label %exit, label %loop.preheader 1192 1193loop.preheader: 1194 br label %loop 1195 1196loop: 1197 1198 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1199 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1200 1201 %within.bounds.1 = icmp ult i32 %i, %length.1 1202 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ] 1203 1204 %i.i64 = zext i32 %i to i64 1205 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 1206 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 1207 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1208 1209 %within.bounds.2 = icmp ult i32 %i, %length.2 1210 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ] 1211 1212 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 1213 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 1214 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1215 1216 %within.bounds.3 = icmp ult i32 %i, %length.3 1217 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ] 1218 1219 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 1220 %array.3.i = load i32, i32* %array.3.i.ptr, align 4 1221 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1222 1223 %i.next = add nuw i32 %i, 1 1224 %continue = icmp ult i32 %i.next, %n 1225 br i1 %continue, label %loop, label %exit 1226 1227exit: 1228 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1229 ret i32 %result 1230} 1231 1232define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) { 1233; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition( 1234; CHECK-NEXT: entry: 1235; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1236; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1237; CHECK: loop.preheader: 1238; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 1239; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 1240; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1241; CHECK-NEXT: br label [[LOOP:%.*]] 1242; CHECK: loop: 1243; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1244; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1245; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1246; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]] 1247; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED_COND]] 1248; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]] 1249; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1250; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1251; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1252; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1253; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1254; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1255; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1256; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1257; CHECK: exit.loopexit: 1258; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1259; CHECK-NEXT: br label [[EXIT]] 1260; CHECK: exit: 1261; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1262; CHECK-NEXT: ret i32 [[RESULT]] 1263; 1264entry: 1265 %tmp5 = icmp eq i32 %n, 0 1266 br i1 %tmp5, label %exit, label %loop.preheader 1267 1268loop.preheader: 1269 br label %loop 1270 1271loop: 1272 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1273 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1274 %within.bounds = icmp ult i32 %i, %length 1275 %unrelated.cond = icmp ult i32 %x, %length 1276 %guard.cond = and i1 %within.bounds, %unrelated.cond 1277 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1278 1279 %i.i64 = zext i32 %i to i64 1280 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1281 %array.i = load i32, i32* %array.i.ptr, align 4 1282 %loop.acc.next = add i32 %loop.acc, %array.i 1283 1284 %i.next = add nuw i32 %i, 1 1285 %continue = icmp ult i32 %i.next, %n 1286 br i1 %continue, label %loop, label %exit 1287 1288exit: 1289 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1290 ret i32 %result 1291} 1292 1293; Don't change the guard condition if there were no widened subconditions 1294define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) { 1295; CHECK-LABEL: @test_no_widened_conditions( 1296; CHECK-NEXT: entry: 1297; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1298; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1299; CHECK: loop.preheader: 1300; CHECK-NEXT: br label [[LOOP:%.*]] 1301; CHECK: loop: 1302; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1303; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1304; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]] 1305; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]] 1306; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]] 1307; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]] 1308; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]] 1309; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ] 1310; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1311; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1312; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1313; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1314; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1315; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1316; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1317; CHECK: exit.loopexit: 1318; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1319; CHECK-NEXT: br label [[EXIT]] 1320; CHECK: exit: 1321; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1322; CHECK-NEXT: ret i32 [[RESULT]] 1323; 1324entry: 1325 %tmp5 = icmp eq i32 %n, 0 1326 br i1 %tmp5, label %exit, label %loop.preheader 1327 1328loop.preheader: 1329 br label %loop 1330 1331loop: 1332 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1333 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1334 %unrelated.cond.1 = icmp eq i32 %x1, %i 1335 %unrelated.cond.2 = icmp eq i32 %x2, %i 1336 %unrelated.cond.3 = icmp eq i32 %x3, %i 1337 %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2 1338 %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3 1339 1340 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1341 1342 %i.i64 = zext i32 %i to i64 1343 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1344 %array.i = load i32, i32* %array.i.ptr, align 4 1345 %loop.acc.next = add i32 %loop.acc, %array.i 1346 1347 %i.next = add nuw i32 %i, 1 1348 %continue = icmp ult i32 %i.next, %n 1349 br i1 %continue, label %loop, label %exit 1350 1351exit: 1352 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1353 ret i32 %result 1354} 1355 1356define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) { 1357; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound( 1358; CHECK-NEXT: entry: 1359; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1360; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1361; CHECK: loop.preheader: 1362; CHECK-NEXT: br label [[LOOP:%.*]] 1363; CHECK: loop: 1364; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1365; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1366; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]] 1367; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]] 1368; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 1369; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1370; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1371; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1372; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1373; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1374; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1375; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1376; CHECK: exit.loopexit: 1377; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1378; CHECK-NEXT: br label [[EXIT]] 1379; CHECK: exit: 1380; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1381; CHECK-NEXT: ret i32 [[RESULT]] 1382; 1383entry: 1384 %tmp5 = icmp sle i32 %n, 0 1385 br i1 %tmp5, label %exit, label %loop.preheader 1386 1387loop.preheader: 1388 br label %loop 1389 1390loop: 1391 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1392 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 1393 %bound = add i32 %i, %x 1394 %within.bounds = icmp ult i32 %i, %bound 1395 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1396 1397 %i.i64 = zext i32 %i to i64 1398 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1399 %array.i = load i32, i32* %array.i.ptr, align 4 1400 %loop.acc.next = add i32 %loop.acc, %array.i 1401 1402 %i.next = add nsw i32 %i, 1 1403 %continue = icmp slt i32 %i.next, %n 1404 br i1 %continue, label %loop, label %exit 1405 1406exit: 1407 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1408 ret i32 %result 1409} 1410 1411define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) { 1412; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate( 1413; CHECK-NEXT: entry: 1414; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1415; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1416; CHECK: loop.preheader: 1417; CHECK-NEXT: br label [[LOOP:%.*]] 1418; CHECK: loop: 1419; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1420; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1421; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]] 1422; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ] 1423; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1424; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1425; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1426; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1427; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1428; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1429; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1430; CHECK: exit.loopexit: 1431; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1432; CHECK-NEXT: br label [[EXIT]] 1433; CHECK: exit: 1434; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1435; CHECK-NEXT: ret i32 [[RESULT]] 1436; 1437entry: 1438 %tmp5 = icmp sle i32 %n, 0 1439 br i1 %tmp5, label %exit, label %loop.preheader 1440 1441loop.preheader: 1442 br label %loop 1443 1444loop: 1445 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1446 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 1447 %guard.cond = icmp eq i32 %i, %x 1448 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 1449 1450 %i.i64 = zext i32 %i to i64 1451 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1452 %array.i = load i32, i32* %array.i.ptr, align 4 1453 %loop.acc.next = add i32 %loop.acc, %array.i 1454 1455 %i.next = add nsw i32 %i, 1 1456 %continue = icmp slt i32 %i.next, %n 1457 br i1 %continue, label %loop, label %exit 1458 1459exit: 1460 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1461 ret i32 %result 1462} 1463 1464define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) { 1465; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length( 1466; CHECK-NEXT: entry: 1467; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1468; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1469; CHECK: loop.preheader: 1470; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32 1471; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 1472; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]] 1473; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 1474; CHECK-NEXT: br label [[LOOP:%.*]] 1475; CHECK: loop: 1476; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1477; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1478; CHECK-NEXT: [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32 1479; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1480; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ] 1481; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1482; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1483; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1484; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1485; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1486; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1487; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1488; CHECK: exit.loopexit: 1489; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1490; CHECK-NEXT: br label [[EXIT]] 1491; CHECK: exit: 1492; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1493; CHECK-NEXT: ret i32 [[RESULT]] 1494; 1495entry: 1496 %tmp5 = icmp eq i32 %n, 0 1497 br i1 %tmp5, label %exit, label %loop.preheader 1498 1499loop.preheader: 1500 br label %loop 1501 1502loop: 1503 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1504 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1505 %length = zext i16 %length.i16 to i32 1506 %within.bounds = icmp ult i32 %i, %length 1507 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1508 1509 %i.i64 = zext i32 %i to i64 1510 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1511 %array.i = load i32, i32* %array.i.ptr, align 4 1512 %loop.acc.next = add i32 %loop.acc, %array.i 1513 1514 %i.next = add nuw i32 %i, 1 1515 %continue = icmp ult i32 %i.next, %n 1516 br i1 %continue, label %loop, label %exit 1517 1518exit: 1519 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1520 ret i32 %result 1521} 1522 1523define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) { 1524; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length( 1525; CHECK-NEXT: entry: 1526; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1527; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1528; CHECK: loop.preheader: 1529; CHECK-NEXT: br label [[LOOP:%.*]] 1530; CHECK: loop: 1531; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1532; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] 1533; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]] 1534; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]] 1535; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ] 1536; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1537; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1538; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1539; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1540; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1541; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1542; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] 1543; CHECK: exit.loopexit: 1544; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ] 1545; CHECK-NEXT: br label [[EXIT]] 1546; CHECK: exit: 1547; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1548; CHECK-NEXT: ret i32 [[RESULT]] 1549; 1550entry: 1551 %tmp5 = icmp eq i32 %n, 0 1552 br i1 %tmp5, label %exit, label %loop.preheader 1553 1554loop.preheader: 1555 br label %loop 1556 1557loop: 1558 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1559 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1560 %length.udiv = udiv i32 %length, %divider 1561 %within.bounds = icmp ult i32 %i, %length.udiv 1562 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1563 1564 %i.i64 = zext i32 %i to i64 1565 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1566 %array.i = load i32, i32* %array.i.ptr, align 4 1567 %loop.acc.next = add i32 %loop.acc, %array.i 1568 1569 %i.next = add nuw i32 %i, 1 1570 %continue = icmp ult i32 %i.next, %n 1571 br i1 %continue, label %loop, label %exit 1572 1573exit: 1574 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1575 ret i32 %result 1576} 1577