2016 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=loop-predication < %s 2>&1 | FileCheck %s3; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s4 5declare void @llvm.experimental.guard(i1, ...)6 7define i32 @unsigned_loop_0_to_n_ult_check(ptr %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:%.*]], 011; 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: [[TMP3:%.*]] = freeze i1 [[TMP2]]17; CHECK-NEXT: br label [[LOOP:%.*]]18; CHECK: loop:19; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]20; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]21; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]22; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]23; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])24; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i6425; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]26; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 427; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]28; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 129; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]30; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]31; CHECK: exit.loopexit:32; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]33; CHECK-NEXT: br label [[EXIT]]34; CHECK: exit:35; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]36; CHECK-NEXT: ret i32 [[RESULT]]37;38entry:39 %tmp5 = icmp eq i32 %n, 040 br i1 %tmp5, label %exit, label %loop.preheader41 42loop.preheader:43 br label %loop44 45loop:46 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]47 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]48 %within.bounds = icmp ult i32 %i, %length49 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]50 51 %i.i64 = zext i32 %i to i6452 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i6453 %array.i = load i32, ptr %array.i.ptr, align 454 %loop.acc.next = add i32 %loop.acc, %array.i55 56 %i.next = add nuw i32 %i, 157 %continue = icmp ult i32 %i.next, %n58 br i1 %continue, label %loop, label %exit59 60exit:61 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]62 ret i32 %result63}64 65define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(ptr %array, i32 %length, i32 %n) {66; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(67; CHECK-NEXT: entry:68; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 069; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]70; CHECK: loop.preheader:71; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]72; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]73; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]74; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]75; CHECK-NEXT: br label [[LOOP:%.*]]76; CHECK: loop:77; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]78; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]79; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]80; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]81; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])82; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i6483; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]84; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 485; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]86; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 187; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]88; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]89; CHECK: exit.loopexit:90; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]91; CHECK-NEXT: br label [[EXIT]]92; CHECK: exit:93; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]94; CHECK-NEXT: ret i32 [[RESULT]]95;96entry:97 %tmp5 = icmp eq i32 %n, 098 br i1 %tmp5, label %exit, label %loop.preheader99 100loop.preheader:101 br label %loop102 103loop:104 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]105 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]106 %within.bounds = icmp ult i32 %i, %length107 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]108 109 %i.i64 = zext i32 %i to i64110 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64111 %array.i = load i32, ptr %array.i.ptr, align 4112 %loop.acc.next = add i32 %loop.acc, %array.i113 114 %i.next = add nuw i32 %i, 1115 %continue = icmp ule i32 %i.next, %n116 br i1 %continue, label %loop, label %exit117 118exit:119 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]120 ret i32 %result121}122 123define i32 @unsigned_loop_0_to_n_ugt_check(ptr %array, i32 %length, i32 %n) {124; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(125; CHECK-NEXT: entry:126; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0127; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]128; CHECK: loop.preheader:129; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]130; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]131; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]132; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]133; CHECK-NEXT: br label [[LOOP:%.*]]134; CHECK: loop:135; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]136; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]137; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]]138; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]139; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])140; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64141; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]142; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4143; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]144; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1145; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]146; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]147; CHECK: exit.loopexit:148; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]149; CHECK-NEXT: br label [[EXIT]]150; CHECK: exit:151; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]152; CHECK-NEXT: ret i32 [[RESULT]]153;154entry:155 %tmp5 = icmp eq i32 %n, 0156 br i1 %tmp5, label %exit, label %loop.preheader157 158loop.preheader:159 br label %loop160 161loop:162 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]163 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]164 %within.bounds = icmp ugt i32 %length, %i165 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]166 167 %i.i64 = zext i32 %i to i64168 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64169 %array.i = load i32, ptr %array.i.ptr, align 4170 %loop.acc.next = add i32 %loop.acc, %array.i171 172 %i.next = add nuw i32 %i, 1173 %continue = icmp ult i32 %i.next, %n174 br i1 %continue, label %loop, label %exit175 176exit:177 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]178 ret i32 %result179}180 181define i32 @signed_loop_0_to_n_ult_check(ptr %array, i32 %length, i32 %n) {182; CHECK-LABEL: @signed_loop_0_to_n_ult_check(183; CHECK-NEXT: entry:184; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0185; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]186; CHECK: loop.preheader:187; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]188; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]189; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]190; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]191; CHECK-NEXT: br label [[LOOP:%.*]]192; CHECK: loop:193; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]194; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]195; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]196; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]197; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])198; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64199; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]200; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4201; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]202; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1203; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]204; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]205; CHECK: exit.loopexit:206; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]207; CHECK-NEXT: br label [[EXIT]]208; CHECK: exit:209; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]210; CHECK-NEXT: ret i32 [[RESULT]]211;212entry:213 %tmp5 = icmp sle i32 %n, 0214 br i1 %tmp5, label %exit, label %loop.preheader215 216loop.preheader:217 br label %loop218 219loop:220 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]221 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]222 %within.bounds = icmp ult i32 %i, %length223 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]224 225 %i.i64 = zext i32 %i to i64226 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64227 %array.i = load i32, ptr %array.i.ptr, align 4228 %loop.acc.next = add i32 %loop.acc, %array.i229 230 %i.next = add nuw i32 %i, 1231 %continue = icmp slt i32 %i.next, %n232 br i1 %continue, label %loop, label %exit233 234exit:235 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]236 ret i32 %result237}238 239define i32 @signed_loop_0_to_n_ult_check_length_range_known(ptr %array, ptr %length.ptr, i32 %n) {240; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(241; CHECK-NEXT: entry:242; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0243; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]]244; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]245; CHECK: loop.preheader:246; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]247; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]248; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]249; CHECK-NEXT: br label [[LOOP:%.*]]250; CHECK: loop:251; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]252; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]253; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]254; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]255; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])256; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64257; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]258; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4259; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]260; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1261; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]262; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]263; CHECK: exit.loopexit:264; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]265; CHECK-NEXT: br label [[EXIT]]266; CHECK: exit:267; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]268; CHECK-NEXT: ret i32 [[RESULT]]269;270entry:271 %tmp5 = icmp sle i32 %n, 0272 %length = load i32, ptr %length.ptr, !range !{i32 1, i32 2147483648}273 br i1 %tmp5, label %exit, label %loop.preheader274 275loop.preheader:276 br label %loop277 278loop:279 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]280 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]281 %within.bounds = icmp ult i32 %i, %length282 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]283 284 %i.i64 = zext i32 %i to i64285 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64286 %array.i = load i32, ptr %array.i.ptr, align 4287 %loop.acc.next = add i32 %loop.acc, %array.i288 289 %i.next = add nuw i32 %i, 1290 %continue = icmp slt i32 %i.next, %n291 br i1 %continue, label %loop, label %exit292 293exit:294 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]295 ret i32 %result296}297 298define i32 @signed_loop_0_to_n_inverse_latch_predicate(ptr %array, i32 %length, i32 %n) {299; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(300; CHECK-NEXT: entry:301; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0302; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]303; CHECK: loop.preheader:304; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]305; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]306; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]307; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]308; CHECK-NEXT: br label [[LOOP:%.*]]309; CHECK: loop:310; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]311; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]312; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]313; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]314; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])315; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64316; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]317; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4318; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]319; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1320; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]321; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]322; CHECK: exit.loopexit:323; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]324; CHECK-NEXT: br label [[EXIT]]325; CHECK: exit:326; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]327; CHECK-NEXT: ret i32 [[RESULT]]328;329entry:330 %tmp5 = icmp sle i32 %n, 0331 br i1 %tmp5, label %exit, label %loop.preheader332 333loop.preheader:334 br label %loop335 336loop:337 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]338 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]339 %within.bounds = icmp ult i32 %i, %length340 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]341 342 %i.i64 = zext i32 %i to i64343 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64344 %array.i = load i32, ptr %array.i.ptr, align 4345 %loop.acc.next = add i32 %loop.acc, %array.i346 347 %i.next = add nuw i32 %i, 1348 %continue = icmp sgt i32 %i.next, %n349 br i1 %continue, label %exit, label %loop350 351exit:352 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]353 ret i32 %result354}355 356define i32 @signed_loop_0_to_n_sle_latch_ult_check(ptr %array, i32 %length, i32 %n) {357; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(358; CHECK-NEXT: entry:359; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0360; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]361; CHECK: loop.preheader:362; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]363; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]364; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]365; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]366; CHECK-NEXT: br label [[LOOP:%.*]]367; CHECK: loop:368; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]369; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]370; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]371; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]372; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])373; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64374; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]375; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4376; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]377; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1378; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]379; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]380; CHECK: exit.loopexit:381; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]382; CHECK-NEXT: br label [[EXIT]]383; CHECK: exit:384; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]385; CHECK-NEXT: ret i32 [[RESULT]]386;387entry:388 %tmp5 = icmp sle i32 %n, 0389 br i1 %tmp5, label %exit, label %loop.preheader390 391loop.preheader:392 br label %loop393 394loop:395 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]396 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]397 %within.bounds = icmp ult i32 %i, %length398 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]399 400 %i.i64 = zext i32 %i to i64401 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64402 %array.i = load i32, ptr %array.i.ptr, align 4403 %loop.acc.next = add i32 %loop.acc, %array.i404 405 %i.next = add nuw i32 %i, 1406 %continue = icmp sle i32 %i.next, %n407 br i1 %continue, label %loop, label %exit408 409exit:410 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]411 ret i32 %result412}413 414define i32 @signed_loop_0_to_n_preincrement_latch_check(ptr %array, i32 %length, i32 %n) {415; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(416; CHECK-NEXT: entry:417; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0418; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]419; CHECK: loop.preheader:420; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1421; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]422; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]423; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]424; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]425; CHECK-NEXT: br label [[LOOP:%.*]]426; CHECK: loop:427; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]428; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]429; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]430; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]431; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])432; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64433; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]434; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4435; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]436; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1437; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]438; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]439; CHECK: exit.loopexit:440; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]441; CHECK-NEXT: br label [[EXIT]]442; CHECK: exit:443; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]444; CHECK-NEXT: ret i32 [[RESULT]]445;446entry:447 %tmp5 = icmp sle i32 %n, 0448 br i1 %tmp5, label %exit, label %loop.preheader449 450loop.preheader:451 br label %loop452 453loop:454 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]455 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]456 %within.bounds = icmp ult i32 %i, %length457 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]458 459 %i.i64 = zext i32 %i to i64460 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64461 %array.i = load i32, ptr %array.i.ptr, align 4462 %loop.acc.next = add i32 %loop.acc, %array.i463 464 %i.next = add i32 %i, 1465 %continue = icmp slt i32 %i, %n466 br i1 %continue, label %loop, label %exit467 468exit:469 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]470 ret i32 %result471}472 473define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(ptr %array, i32 %length, i32 %n) {474; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(475; CHECK-NEXT: entry:476; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0477; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]478; CHECK: loop.preheader:479; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2480; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]481; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]482; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]483; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]484; CHECK-NEXT: br label [[LOOP:%.*]]485; CHECK: loop:486; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]487; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]488; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1489; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]490; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]491; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])492; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64493; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]494; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4495; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]496; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]497; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]498; CHECK: exit.loopexit:499; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]500; CHECK-NEXT: br label [[EXIT]]501; CHECK: exit:502; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]503; CHECK-NEXT: ret i32 [[RESULT]]504;505entry:506 %tmp5 = icmp sle i32 %n, 0507 br i1 %tmp5, label %exit, label %loop.preheader508 509loop.preheader:510 br label %loop511 512loop:513 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]514 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]515 516 %i.next = add i32 %i, 1517 %within.bounds = icmp ult i32 %i.next, %length518 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]519 520 %i.i64 = zext i32 %i to i64521 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64522 %array.i = load i32, ptr %array.i.ptr, align 4523 %loop.acc.next = add i32 %loop.acc, %array.i524 525 %continue = icmp slt i32 %i, %n526 br i1 %continue, label %loop, label %exit527 528exit:529 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]530 ret i32 %result531}532 533define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) {534; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(535; CHECK-NEXT: entry:536; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0537; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]538; CHECK: loop.preheader:539; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1540; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]541; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]542; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]543; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]544; CHECK-NEXT: br label [[LOOP:%.*]]545; CHECK: loop:546; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]547; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]548; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1549; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]550; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]551; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])552; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64553; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]554; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4555; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]556; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1557; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]558; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]559; CHECK: exit.loopexit:560; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]561; CHECK-NEXT: br label [[EXIT]]562; CHECK: exit:563; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]564; CHECK-NEXT: ret i32 [[RESULT]]565;566entry:567 %tmp5 = icmp sle i32 %n, 0568 br i1 %tmp5, label %exit, label %loop.preheader569 570loop.preheader:571 br label %loop572 573loop:574 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]575 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]576 %i.offset = add i32 %i, 1577 %within.bounds = icmp ult i32 %i.offset, %length578 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]579 580 %i.i64 = zext i32 %i to i64581 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64582 %array.i = load i32, ptr %array.i.ptr, align 4583 %loop.acc.next = add i32 %loop.acc, %array.i584 585 %i.next = add i32 %i, 1586 %continue = icmp sle i32 %i.next, %n587 br i1 %continue, label %loop, label %exit588 589exit:590 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]591 ret i32 %result592}593 594define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) {595; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(596; CHECK-NEXT: entry:597; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0598; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]599; CHECK: loop.preheader:600; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]601; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]602; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]603; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]604; CHECK-NEXT: br label [[LOOP:%.*]]605; CHECK: loop:606; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]607; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]608; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1609; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]610; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]611; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])612; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64613; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]614; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4615; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]616; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1617; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1618; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]619; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]620; CHECK: exit.loopexit:621; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]622; CHECK-NEXT: br label [[EXIT]]623; CHECK: exit:624; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]625; CHECK-NEXT: ret i32 [[RESULT]]626;627entry:628 %tmp5 = icmp sle i32 %n, 0629 br i1 %tmp5, label %exit, label %loop.preheader630 631loop.preheader:632 br label %loop633 634loop:635 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]636 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]637 %i.offset = add i32 %i, 1638 %within.bounds = icmp ult i32 %i.offset, %length639 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]640 641 %i.i64 = zext i32 %i to i64642 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64643 %array.i = load i32, ptr %array.i.ptr, align 4644 %loop.acc.next = add i32 %loop.acc, %array.i645 646 %i.next = add i32 %i, 1647 %i.next.offset = add i32 %i.next, 1648 %continue = icmp sle i32 %i.next.offset, %n649 br i1 %continue, label %loop, label %exit650 651exit:652 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]653 ret i32 %result654}655 656define i32 @unsupported_latch_pred_loop_0_to_n(ptr %array, i32 %length, i32 %n) {657; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(658; CHECK-NEXT: entry:659; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0660; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]661; CHECK: loop.preheader:662; CHECK-NEXT: br label [[LOOP:%.*]]663; CHECK: loop:664; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]665; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]666; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]667; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]668; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64669; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]670; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4671; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]672; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1673; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]674; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]675; CHECK: exit.loopexit:676; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]677; CHECK-NEXT: br label [[EXIT]]678; CHECK: exit:679; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]680; CHECK-NEXT: ret i32 [[RESULT]]681;682entry:683 %tmp5 = icmp sle i32 %n, 0684 br i1 %tmp5, label %exit, label %loop.preheader685 686loop.preheader:687 br label %loop688 689loop:690 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]691 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]692 %within.bounds = icmp ult i32 %i, %length693 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]694 695 %i.i64 = zext i32 %i to i64696 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64697 %array.i = load i32, ptr %array.i.ptr, align 4698 %loop.acc.next = add i32 %loop.acc, %array.i699 700 %i.next = add nsw i32 %i, 1701 %continue = icmp ne i32 %i.next, %n702 br i1 %continue, label %loop, label %exit703 704exit:705 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]706 ret i32 %result707}708 709define i32 @signed_loop_0_to_n_unsupported_iv_step(ptr %array, i32 %length, i32 %n) {710; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(711; CHECK-NEXT: entry:712; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0713; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]714; CHECK: loop.preheader:715; CHECK-NEXT: br label [[LOOP:%.*]]716; CHECK: loop:717; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]718; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]719; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]720; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]721; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64722; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]723; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4724; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]725; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2726; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]727; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]728; CHECK: exit.loopexit:729; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]730; CHECK-NEXT: br label [[EXIT]]731; CHECK: exit:732; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]733; CHECK-NEXT: ret i32 [[RESULT]]734;735entry:736 %tmp5 = icmp sle i32 %n, 0737 br i1 %tmp5, label %exit, label %loop.preheader738 739loop.preheader:740 br label %loop741 742loop:743 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]744 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]745 %within.bounds = icmp ult i32 %i, %length746 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]747 748 %i.i64 = zext i32 %i to i64749 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64750 %array.i = load i32, ptr %array.i.ptr, align 4751 %loop.acc.next = add i32 %loop.acc, %array.i752 753 %i.next = add nsw i32 %i, 2754 %continue = icmp slt i32 %i.next, %n755 br i1 %continue, label %loop, label %exit756 757exit:758 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]759 ret i32 %result760}761 762define i32 @signed_loop_0_to_n_equal_iv_range_check(ptr %array, i32 %length, i32 %n) {763; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(764; CHECK-NEXT: entry:765; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0766; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]767; CHECK: loop.preheader:768; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]769; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]770; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]771; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]772; CHECK-NEXT: br label [[LOOP:%.*]]773; CHECK: loop:774; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]775; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]776; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]777; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]778; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]779; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])780; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64781; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]782; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4783; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]784; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1785; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1786; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]787; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]788; CHECK: exit.loopexit:789; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]790; CHECK-NEXT: br label [[EXIT]]791; CHECK: exit:792; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]793; CHECK-NEXT: ret i32 [[RESULT]]794;795entry:796 %tmp5 = icmp sle i32 %n, 0797 br i1 %tmp5, label %exit, label %loop.preheader798 799loop.preheader:800 br label %loop801 802loop:803 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]804 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]805 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]806 807 %within.bounds = icmp ult i32 %j, %length808 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]809 810 %i.i64 = zext i32 %i to i64811 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64812 %array.i = load i32, ptr %array.i.ptr, align 4813 %loop.acc.next = add i32 %loop.acc, %array.i814 815 %j.next = add nsw i32 %j, 1816 %i.next = add nsw i32 %i, 1817 %continue = icmp slt i32 %i.next, %n818 br i1 %continue, label %loop, label %exit819 820exit:821 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]822 ret i32 %result823}824 825define i32 @signed_loop_start_to_n_offset_iv_range_check(ptr %array, i32 %start.i,826; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(827; CHECK-NEXT: entry:828; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0829; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]830; CHECK: loop.preheader:831; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]832; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]833; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]834; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]835; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]836; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]837; CHECK-NEXT: br label [[LOOP:%.*]]838; CHECK: loop:839; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]840; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]841; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]842; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]843; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ]844; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])845; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64846; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]847; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4848; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]849; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1850; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1851; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]852; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]853; CHECK: exit.loopexit:854; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]855; CHECK-NEXT: br label [[EXIT]]856; CHECK: exit:857; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]858; CHECK-NEXT: ret i32 [[RESULT]]859;860 i32 %start.j, i32 %length,861 i32 %n) {862entry:863 %tmp5 = icmp sle i32 %n, 0864 br i1 %tmp5, label %exit, label %loop.preheader865 866loop.preheader:867 br label %loop868 869loop:870 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]871 %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ]872 %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ]873 874 %within.bounds = icmp ult i32 %j, %length875 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]876 877 %i.i64 = zext i32 %i to i64878 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64879 %array.i = load i32, ptr %array.i.ptr, align 4880 %loop.acc.next = add i32 %loop.acc, %array.i881 882 %j.next = add i32 %j, 1883 %i.next = add i32 %i, 1884 %continue = icmp slt i32 %i.next, %n885 br i1 %continue, label %loop, label %exit886 887exit:888 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]889 ret i32 %result890}891 892define i32 @signed_loop_0_to_n_different_iv_types(ptr %array, i16 %length, i32 %n) {893; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(894; CHECK-NEXT: entry:895; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0896; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]897; CHECK: loop.preheader:898; CHECK-NEXT: br label [[LOOP:%.*]]899; CHECK: loop:900; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]901; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]902; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]903; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]904; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]905; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64906; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]907; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4908; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]909; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1910; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1911; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]912; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]913; CHECK: exit.loopexit:914; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]915; CHECK-NEXT: br label [[EXIT]]916; CHECK: exit:917; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]918; CHECK-NEXT: ret i32 [[RESULT]]919;920entry:921 %tmp5 = icmp sle i32 %n, 0922 br i1 %tmp5, label %exit, label %loop.preheader923 924loop.preheader:925 br label %loop926 927loop:928 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]929 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]930 %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ]931 932 %within.bounds = icmp ult i16 %j, %length933 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]934 935 %i.i64 = zext i32 %i to i64936 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64937 %array.i = load i32, ptr %array.i.ptr, align 4938 %loop.acc.next = add i32 %loop.acc, %array.i939 940 %j.next = add i16 %j, 1941 %i.next = add i32 %i, 1942 %continue = icmp slt i32 %i.next, %n943 br i1 %continue, label %loop, label %exit944 945exit:946 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]947 ret i32 %result948}949 950define i32 @signed_loop_0_to_n_different_iv_strides(ptr %array, i32 %length, i32 %n) {951; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(952; CHECK-NEXT: entry:953; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0954; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]955; CHECK: loop.preheader:956; CHECK-NEXT: br label [[LOOP:%.*]]957; CHECK: loop:958; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]959; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]960; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]961; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]962; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]963; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64964; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]965; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4966; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]967; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2968; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1969; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]970; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]971; CHECK: exit.loopexit:972; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]973; CHECK-NEXT: br label [[EXIT]]974; CHECK: exit:975; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]976; CHECK-NEXT: ret i32 [[RESULT]]977;978entry:979 %tmp5 = icmp sle i32 %n, 0980 br i1 %tmp5, label %exit, label %loop.preheader981 982loop.preheader:983 br label %loop984 985loop:986 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]987 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]988 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]989 990 %within.bounds = icmp ult i32 %j, %length991 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]992 993 %i.i64 = zext i32 %i to i64994 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64995 %array.i = load i32, ptr %array.i.ptr, align 4996 %loop.acc.next = add i32 %loop.acc, %array.i997 998 %j.next = add nsw i32 %j, 2999 %i.next = add nsw i32 %i, 11000 %continue = icmp slt i32 %i.next, %n1001 br i1 %continue, label %loop, label %exit1002 1003exit:1004 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1005 ret i32 %result1006}1007 1008define i32 @two_range_checks(ptr %array.1, i32 %length.1,1009; CHECK-LABEL: @two_range_checks(1010; CHECK-NEXT: entry:1011; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01012; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1013; CHECK: loop.preheader:1014; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]1015; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]1016; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1017; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1018; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]1019; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_1]]1020; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]1021; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]]1022; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP3]], [[TMP7]]1023; CHECK-NEXT: br label [[LOOP:%.*]]1024; CHECK: loop:1025; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1026; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1027; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]1028; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]1029; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]1030; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ]1031; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1032; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641033; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]1034; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 41035; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]1036; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]1037; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 41038; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]1039; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11040; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1041; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1042; CHECK: exit.loopexit:1043; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1044; CHECK-NEXT: br label [[EXIT]]1045; CHECK: exit:1046; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1047; CHECK-NEXT: ret i32 [[RESULT]]1048;1049 ptr %array.2, i32 %length.2, i32 %n) {1050entry:1051 %tmp5 = icmp eq i32 %n, 01052 br i1 %tmp5, label %exit, label %loop.preheader1053 1054loop.preheader:1055 br label %loop1056 1057loop:1058 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1059 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1060 %within.bounds.1 = icmp ult i32 %i, %length.11061 %within.bounds.2 = icmp ult i32 %i, %length.21062 %within.bounds = and i1 %within.bounds.1, %within.bounds.21063 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1064 1065 %i.i64 = zext i32 %i to i641066 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i641067 %array.1.i = load i32, ptr %array.1.i.ptr, align 41068 %loop.acc.1 = add i32 %loop.acc, %array.1.i1069 1070 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i641071 %array.2.i = load i32, ptr %array.2.i.ptr, align 41072 %loop.acc.next = add i32 %loop.acc.1, %array.2.i1073 1074 %i.next = add nuw i32 %i, 11075 %continue = icmp ult i32 %i.next, %n1076 br i1 %continue, label %loop, label %exit1077 1078exit:1079 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1080 ret i32 %result1081}1082 1083define i32 @three_range_checks(ptr %array.1, i32 %length.1,1084; CHECK-LABEL: @three_range_checks(1085; CHECK-NEXT: entry:1086; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01087; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1088; CHECK: loop.preheader:1089; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]1090; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]1091; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1092; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1093; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]1094; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]]1095; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]1096; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]]1097; CHECK-NEXT: [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]1098; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_1]]1099; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]1100; CHECK-NEXT: [[TMP11:%.*]] = freeze i1 [[TMP10]]1101; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[TMP3]], [[TMP7]]1102; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]]1103; CHECK-NEXT: br label [[LOOP:%.*]]1104; CHECK: loop:1105; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1106; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1107; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]1108; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]1109; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]1110; CHECK-NEXT: [[WITHIN_BOUNDS_1_AND_2:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]1111; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1_AND_2]], [[WITHIN_BOUNDS_3]]1112; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP13]], i32 9) [ "deopt"() ]1113; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1114; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641115; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]1116; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 41117; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]1118; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]1119; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 41120; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]1121; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]1122; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 41123; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]1124; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11125; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1126; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1127; CHECK: exit.loopexit:1128; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1129; CHECK-NEXT: br label [[EXIT]]1130; CHECK: exit:1131; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1132; CHECK-NEXT: ret i32 [[RESULT]]1133;1134 ptr %array.2, i32 %length.2,1135 ptr %array.3, i32 %length.3, i32 %n) {1136entry:1137 %tmp5 = icmp eq i32 %n, 01138 br i1 %tmp5, label %exit, label %loop.preheader1139 1140loop.preheader:1141 br label %loop1142 1143loop:1144 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1145 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1146 %within.bounds.1 = icmp ult i32 %i, %length.11147 %within.bounds.2 = icmp ult i32 %i, %length.21148 %within.bounds.3 = icmp ult i32 %i, %length.31149 %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.21150 %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.31151 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1152 1153 %i.i64 = zext i32 %i to i641154 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i641155 %array.1.i = load i32, ptr %array.1.i.ptr, align 41156 %loop.acc.1 = add i32 %loop.acc, %array.1.i1157 1158 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i641159 %array.2.i = load i32, ptr %array.2.i.ptr, align 41160 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i1161 1162 %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i641163 %array.3.i = load i32, ptr %array.3.i.ptr, align 41164 %loop.acc.next = add i32 %loop.acc.2, %array.3.i1165 1166 %i.next = add nuw i32 %i, 11167 %continue = icmp ult i32 %i.next, %n1168 br i1 %continue, label %loop, label %exit1169 1170exit:1171 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1172 ret i32 %result1173}1174 1175define i32 @three_guards(ptr %array.1, i32 %length.1,1176; CHECK-LABEL: @three_guards(1177; CHECK-NEXT: entry:1178; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01179; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1180; CHECK: loop.preheader:1181; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]1182; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]1183; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1184; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1185; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]1186; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]]1187; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]]1188; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]]1189; CHECK-NEXT: [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]1190; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_3]]1191; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]1192; CHECK-NEXT: [[TMP11:%.*]] = freeze i1 [[TMP10]]1193; CHECK-NEXT: br label [[LOOP:%.*]]1194; CHECK: loop:1195; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1196; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1197; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]1198; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]1199; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_1]])1200; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641201; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]1202; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 41203; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]1204; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]1205; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP7]], i32 9) [ "deopt"() ]1206; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_2]])1207; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]1208; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 41209; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]1210; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]1211; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP11]], i32 9) [ "deopt"() ]1212; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_3]])1213; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]1214; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 41215; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]1216; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11217; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1218; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1219; CHECK: exit.loopexit:1220; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1221; CHECK-NEXT: br label [[EXIT]]1222; CHECK: exit:1223; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1224; CHECK-NEXT: ret i32 [[RESULT]]1225;1226 ptr %array.2, i32 %length.2,1227 ptr %array.3, i32 %length.3, i32 %n) {1228entry:1229 %tmp5 = icmp eq i32 %n, 01230 br i1 %tmp5, label %exit, label %loop.preheader1231 1232loop.preheader:1233 br label %loop1234 1235loop:1236 1237 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1238 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1239 1240 %within.bounds.1 = icmp ult i32 %i, %length.11241 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ]1242 1243 %i.i64 = zext i32 %i to i641244 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i641245 %array.1.i = load i32, ptr %array.1.i.ptr, align 41246 %loop.acc.1 = add i32 %loop.acc, %array.1.i1247 1248 %within.bounds.2 = icmp ult i32 %i, %length.21249 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ]1250 1251 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i641252 %array.2.i = load i32, ptr %array.2.i.ptr, align 41253 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i1254 1255 %within.bounds.3 = icmp ult i32 %i, %length.31256 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ]1257 1258 %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i641259 %array.3.i = load i32, ptr %array.3.i.ptr, align 41260 %loop.acc.next = add i32 %loop.acc.2, %array.3.i1261 1262 %i.next = add nuw i32 %i, 11263 %continue = icmp ult i32 %i.next, %n1264 br i1 %continue, label %loop, label %exit1265 1266exit:1267 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1268 ret i32 %result1269}1270 1271define i32 @unsigned_loop_0_to_n_unrelated_condition(ptr %array, i32 %length, i32 %n, i32 %x) {1272; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(1273; CHECK-NEXT: entry:1274; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01275; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1276; CHECK: loop.preheader:1277; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]1278; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]1279; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1280; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1281; CHECK-NEXT: br label [[LOOP:%.*]]1282; CHECK: loop:1283; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1284; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1285; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1286; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]1287; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED_COND]]1288; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[UNRELATED_COND]], [[TMP3]]1289; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]1290; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_COND]])1291; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641292; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1293; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41294; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1295; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11296; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1297; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1298; CHECK: exit.loopexit:1299; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1300; CHECK-NEXT: br label [[EXIT]]1301; CHECK: exit:1302; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1303; CHECK-NEXT: ret i32 [[RESULT]]1304;1305entry:1306 %tmp5 = icmp eq i32 %n, 01307 br i1 %tmp5, label %exit, label %loop.preheader1308 1309loop.preheader:1310 br label %loop1311 1312loop:1313 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1314 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1315 %within.bounds = icmp ult i32 %i, %length1316 %unrelated.cond = icmp ult i32 %x, %length1317 %guard.cond = and i1 %within.bounds, %unrelated.cond1318 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]1319 1320 %i.i64 = zext i32 %i to i641321 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641322 %array.i = load i32, ptr %array.i.ptr, align 41323 %loop.acc.next = add i32 %loop.acc, %array.i1324 1325 %i.next = add nuw i32 %i, 11326 %continue = icmp ult i32 %i.next, %n1327 br i1 %continue, label %loop, label %exit1328 1329exit:1330 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1331 ret i32 %result1332}1333 1334; Don't change the guard condition if there were no widened subconditions1335define i32 @test_no_widened_conditions(ptr %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {1336; CHECK-LABEL: @test_no_widened_conditions(1337; CHECK-NEXT: entry:1338; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01339; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1340; CHECK: loop.preheader:1341; CHECK-NEXT: br label [[LOOP:%.*]]1342; CHECK: loop:1343; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1344; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1345; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]1346; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]1347; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]1348; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]1349; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]1350; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]1351; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641352; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1353; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41354; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1355; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11356; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1357; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1358; CHECK: exit.loopexit:1359; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1360; CHECK-NEXT: br label [[EXIT]]1361; CHECK: exit:1362; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1363; CHECK-NEXT: ret i32 [[RESULT]]1364;1365entry:1366 %tmp5 = icmp eq i32 %n, 01367 br i1 %tmp5, label %exit, label %loop.preheader1368 1369loop.preheader:1370 br label %loop1371 1372loop:1373 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1374 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1375 %unrelated.cond.1 = icmp eq i32 %x1, %i1376 %unrelated.cond.2 = icmp eq i32 %x2, %i1377 %unrelated.cond.3 = icmp eq i32 %x3, %i1378 %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.21379 %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.31380 1381 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]1382 1383 %i.i64 = zext i32 %i to i641384 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641385 %array.i = load i32, ptr %array.i.ptr, align 41386 %loop.acc.next = add i32 %loop.acc, %array.i1387 1388 %i.next = add nuw i32 %i, 11389 %continue = icmp ult i32 %i.next, %n1390 br i1 %continue, label %loop, label %exit1391 1392exit:1393 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1394 ret i32 %result1395}1396 1397define i32 @signed_loop_start_to_n_loop_variant_bound(ptr %array, i32 %x, i32 %start, i32 %n) {1398; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(1399; CHECK-NEXT: entry:1400; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 01401; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1402; CHECK: loop.preheader:1403; CHECK-NEXT: br label [[LOOP:%.*]]1404; CHECK: loop:1405; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1406; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]1407; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]1408; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]1409; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]1410; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641411; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1412; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41413; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1414; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 11415; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]1416; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1417; CHECK: exit.loopexit:1418; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1419; CHECK-NEXT: br label [[EXIT]]1420; CHECK: exit:1421; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1422; CHECK-NEXT: ret i32 [[RESULT]]1423;1424entry:1425 %tmp5 = icmp sle i32 %n, 01426 br i1 %tmp5, label %exit, label %loop.preheader1427 1428loop.preheader:1429 br label %loop1430 1431loop:1432 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1433 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]1434 %bound = add i32 %i, %x1435 %within.bounds = icmp ult i32 %i, %bound1436 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1437 1438 %i.i64 = zext i32 %i to i641439 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641440 %array.i = load i32, ptr %array.i.ptr, align 41441 %loop.acc.next = add i32 %loop.acc, %array.i1442 1443 %i.next = add nsw i32 %i, 11444 %continue = icmp slt i32 %i.next, %n1445 br i1 %continue, label %loop, label %exit1446 1447exit:1448 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1449 ret i32 %result1450}1451 1452define i32 @signed_loop_start_to_n_non_monotonic_predicate(ptr %array, i32 %x, i32 %start, i32 %n) {1453; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(1454; CHECK-NEXT: entry:1455; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 01456; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1457; CHECK: loop.preheader:1458; CHECK-NEXT: br label [[LOOP:%.*]]1459; CHECK: loop:1460; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1461; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]1462; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]1463; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]1464; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641465; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1466; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41467; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1468; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 11469; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]1470; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1471; CHECK: exit.loopexit:1472; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1473; CHECK-NEXT: br label [[EXIT]]1474; CHECK: exit:1475; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1476; CHECK-NEXT: ret i32 [[RESULT]]1477;1478entry:1479 %tmp5 = icmp sle i32 %n, 01480 br i1 %tmp5, label %exit, label %loop.preheader1481 1482loop.preheader:1483 br label %loop1484 1485loop:1486 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1487 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]1488 %guard.cond = icmp eq i32 %i, %x1489 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]1490 1491 %i.i64 = zext i32 %i to i641492 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641493 %array.i = load i32, ptr %array.i.ptr, align 41494 %loop.acc.next = add i32 %loop.acc, %array.i1495 1496 %i.next = add nsw i32 %i, 11497 %continue = icmp slt i32 %i.next, %n1498 br i1 %continue, label %loop, label %exit1499 1500exit:1501 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1502 ret i32 %result1503}1504 1505define i32 @unsigned_loop_0_to_n_hoist_length(ptr %array, i16 %length.i16, i32 %n) {1506; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(1507; CHECK-NEXT: entry:1508; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01509; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1510; CHECK: loop.preheader:1511; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i321512; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]1513; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]1514; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]1515; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]1516; CHECK-NEXT: br label [[LOOP:%.*]]1517; CHECK: loop:1518; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1519; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1520; CHECK-NEXT: [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i321521; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1522; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]1523; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1524; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641525; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1526; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41527; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1528; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11529; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1530; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1531; CHECK: exit.loopexit:1532; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1533; CHECK-NEXT: br label [[EXIT]]1534; CHECK: exit:1535; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1536; CHECK-NEXT: ret i32 [[RESULT]]1537;1538entry:1539 %tmp5 = icmp eq i32 %n, 01540 br i1 %tmp5, label %exit, label %loop.preheader1541 1542loop.preheader:1543 br label %loop1544 1545loop:1546 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1547 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1548 %length = zext i16 %length.i16 to i321549 %within.bounds = icmp ult i32 %i, %length1550 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1551 1552 %i.i64 = zext i32 %i to i641553 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641554 %array.i = load i32, ptr %array.i.ptr, align 41555 %loop.acc.next = add i32 %loop.acc, %array.i1556 1557 %i.next = add nuw i32 %i, 11558 %continue = icmp ult i32 %i.next, %n1559 br i1 %continue, label %loop, label %exit1560 1561exit:1562 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1563 ret i32 %result1564}1565 1566define i32 @unsigned_loop_0_to_n_cant_hoist_length(ptr %array, i32 %length, i32 %divider, i32 %n) {1567; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(1568; CHECK-NEXT: entry:1569; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 01570; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1571; CHECK: loop.preheader:1572; CHECK-NEXT: br label [[LOOP:%.*]]1573; CHECK: loop:1574; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1575; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1576; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]1577; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]]1578; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]]1579; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]]1580; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1581; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1582; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]1583; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1584; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641585; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1586; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41587; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1588; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11589; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1590; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1591; CHECK: exit.loopexit:1592; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1593; CHECK-NEXT: br label [[EXIT]]1594; CHECK: exit:1595; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]1596; CHECK-NEXT: ret i32 [[RESULT]]1597;1598entry:1599 %tmp5 = icmp eq i32 %n, 01600 br i1 %tmp5, label %exit, label %loop.preheader1601 1602loop.preheader:1603 br label %loop1604 1605loop:1606 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1607 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1608 %length.udiv = udiv i32 %length, %divider1609 %within.bounds = icmp ult i32 %i, %length.udiv1610 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1611 1612 %i.i64 = zext i32 %i to i641613 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641614 %array.i = load i32, ptr %array.i.ptr, align 41615 %loop.acc.next = add i32 %loop.acc, %array.i1616 1617 %i.next = add nuw i32 %i, 11618 %continue = icmp ult i32 %i.next, %n1619 br i1 %continue, label %loop, label %exit1620 1621exit:1622 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]1623 ret i32 %result1624}1625 1626 1627; This is a case where the length information tells us that the guard1628; must trigger on some iteration.1629define i32 @provably_taken(ptr %array, ptr %length.ptr) {1630; CHECK-LABEL: @provably_taken(1631; CHECK-NEXT: loop.preheader:1632; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR:%.*]], align 4, !range [[RNG1:![0-9]+]]1633; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[LENGTH]]1634; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], false1635; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]1636; CHECK-NEXT: br label [[LOOP:%.*]]1637; CHECK: loop:1638; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]1639; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1640; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1641; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]1642; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1643; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641644; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1645; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41646; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1647; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11648; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], 2001649; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1650; CHECK: exit:1651; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]1652; CHECK-NEXT: ret i32 [[RESULT]]1653;1654loop.preheader:1655 %length = load i32, ptr %length.ptr, !range !{i32 0, i32 50}1656 br label %loop1657 1658loop:1659 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]1660 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1661 %within.bounds = icmp ult i32 %i, %length1662 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1663 1664 %i.i64 = zext i32 %i to i641665 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641666 %array.i = load i32, ptr %array.i.ptr, align 41667 %loop.acc.next = add i32 %loop.acc, %array.i1668 1669 %i.next = add nuw i32 %i, 11670 %continue = icmp slt i32 %i.next, 2001671 br i1 %continue, label %loop, label %exit1672 1673exit:1674 %result = phi i32 [ %loop.acc.next, %loop ]1675 ret i32 %result1676}1677 1678; NE Check (as produced by LFTR) where we can prove Start < End via simple1679; instruction analysis1680define i32 @ne_latch_zext(ptr %array, i32 %length, i16 %n16) {1681; CHECK-LABEL: @ne_latch_zext(1682; CHECK-NEXT: loop.preheader:1683; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i321684; CHECK-NEXT: [[NPLUS1:%.*]] = add nuw nsw i32 [[N]], 11685; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[NPLUS1]], [[LENGTH:%.*]]1686; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]1687; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]1688; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]1689; CHECK-NEXT: br label [[LOOP:%.*]]1690; CHECK: loop:1691; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]1692; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1693; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]1694; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1695; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 11696; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]1697; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1698; CHECK: exit:1699; CHECK-NEXT: ret i32 01700;1701loop.preheader:1702 %n = zext i16 %n16 to i321703 %nplus1 = add nsw nuw i32 %n, 11704 br label %loop1705 1706loop:1707 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1708 %within.bounds = icmp ult i32 %i, %length1709 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1710 1711 %i.next = add nsw nuw i32 %i, 11712 %continue = icmp ne i32 %i.next, %nplus11713 br i1 %continue, label %loop, label %exit1714 1715exit:1716 ret i32 01717}1718 1719; Same as previous, but with a pre-increment test since this is easier to match1720define i32 @ne_latch_zext_preinc(ptr %array, i32 %length, i16 %n16) {1721; CHECK-LABEL: @ne_latch_zext_preinc(1722; CHECK-NEXT: loop.preheader:1723; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i321724; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -11725; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]1726; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]1727; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]1728; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]1729; CHECK-NEXT: br label [[LOOP:%.*]]1730; CHECK: loop:1731; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]1732; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1733; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]1734; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1735; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11736; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]1737; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1738; CHECK: exit:1739; CHECK-NEXT: ret i32 01740;1741loop.preheader:1742 %n = zext i16 %n16 to i321743 br label %loop1744 1745loop:1746 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1747 %within.bounds = icmp ult i32 %i, %length1748 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1749 1750 %i.next = add nuw i32 %i, 11751 %continue = icmp ne i32 %i, %n1752 br i1 %continue, label %loop, label %exit1753 1754exit:1755 ret i32 01756}1757 1758; NE Check (as produced by LFTR) where we can prove Start < End via the1759; condition guarding the loop entry.1760define i32 @ne_latch_dom_check(ptr %array, i32 %length, i32 %n) {1761; CHECK-LABEL: @ne_latch_dom_check(1762; CHECK-NEXT: entry:1763; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 01764; CHECK-NEXT: [[NPLUS1:%.*]] = add nuw i32 [[N]], 11765; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1766; CHECK: loop.preheader:1767; CHECK-NEXT: br label [[LOOP:%.*]]1768; CHECK: loop:1769; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1770; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]1771; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]1772; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 11773; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]1774; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1775; CHECK: exit.loopexit:1776; CHECK-NEXT: br label [[EXIT]]1777; CHECK: exit:1778; CHECK-NEXT: ret i32 01779;1780entry:1781 %tmp5 = icmp sle i32 %n, 01782 %nplus1 = add nuw i32 %n, 11783 br i1 %tmp5, label %exit, label %loop.preheader1784 1785loop.preheader:1786 br label %loop1787 1788loop:1789 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1790 %within.bounds = icmp ult i32 %i, %length1791 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1792 1793 %i.next = add nsw nuw i32 %i, 11794 %continue = icmp ne i32 %i.next, %nplus11795 br i1 %continue, label %loop, label %exit1796 1797exit:1798 ret i32 01799}1800 1801; Same as previous, but easier to match1802define i32 @ne_latch_dom_check_preinc(ptr %array, i32 %length, i32 %n) {1803; CHECK-LABEL: @ne_latch_dom_check_preinc(1804; CHECK-NEXT: entry:1805; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 01806; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1807; CHECK: loop.preheader:1808; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -11809; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]1810; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]1811; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]1812; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]1813; CHECK-NEXT: br label [[LOOP:%.*]]1814; CHECK: loop:1815; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1816; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1817; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]1818; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1819; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11820; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]1821; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]1822; CHECK: exit.loopexit:1823; CHECK-NEXT: br label [[EXIT]]1824; CHECK: exit:1825; CHECK-NEXT: ret i32 01826;1827entry:1828 %tmp5 = icmp sle i32 %n, 01829 br i1 %tmp5, label %exit, label %loop.preheader1830 1831loop.preheader:1832 br label %loop1833 1834loop:1835 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1836 %within.bounds = icmp ult i32 %i, %length1837 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1838 1839 %i.next = add nuw i32 %i, 11840 %continue = icmp ne i32 %i, %n1841 br i1 %continue, label %loop, label %exit1842 1843exit:1844 ret i32 01845}1846 1847; Same as previous, except swapped br/cmp1848define i32 @eq_latch_dom_check_preinc(ptr %array, i32 %length, i32 %n) {1849; CHECK-LABEL: @eq_latch_dom_check_preinc(1850; CHECK-NEXT: entry:1851; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 01852; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]1853; CHECK: loop.preheader:1854; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -11855; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]1856; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]1857; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]1858; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]]1859; CHECK-NEXT: br label [[LOOP:%.*]]1860; CHECK: loop:1861; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]1862; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1863; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]1864; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])1865; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11866; CHECK-NEXT: [[DONE:%.*]] = icmp eq i32 [[I]], [[N]]1867; CHECK-NEXT: br i1 [[DONE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]1868; CHECK: exit.loopexit:1869; CHECK-NEXT: br label [[EXIT]]1870; CHECK: exit:1871; CHECK-NEXT: ret i32 01872;1873entry:1874 %tmp5 = icmp sle i32 %n, 01875 br i1 %tmp5, label %exit, label %loop.preheader1876 1877loop.preheader:1878 br label %loop1879 1880loop:1881 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1882 %within.bounds = icmp ult i32 %i, %length1883 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1884 1885 %i.next = add nuw i32 %i, 11886 %done = icmp eq i32 %i, %n1887 br i1 %done, label %exit, label %loop1888 1889exit:1890 ret i32 01891}1892 1893 1894; NE latch - can't prove (end-start) mod step == 0 (i.e. might wrap1895; around several times or even be infinite)1896define i32 @neg_ne_latch_mod_step(ptr %array, i32 %length, i16 %n16) {1897; CHECK-LABEL: @neg_ne_latch_mod_step(1898; CHECK-NEXT: loop.preheader:1899; CHECK-NEXT: [[N:%.*]] = zext i16 [[N16:%.*]] to i321900; CHECK-NEXT: br label [[LOOP:%.*]]1901; CHECK: loop:1902; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]1903; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]1904; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]1905; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 31906; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]1907; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1908; CHECK: exit:1909; CHECK-NEXT: ret i32 01910;1911loop.preheader:1912 %n = zext i16 %n16 to i321913 br label %loop1914 1915loop:1916 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1917 %within.bounds = icmp ult i32 %i, %length1918 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1919 1920 %i.next = add i32 %i, 31921 %continue = icmp ne i32 %i, %n1922 br i1 %continue, label %loop, label %exit1923 1924exit:1925 ret i32 01926}1927 1928; NE latch - TODO: could prove (end-start) mod step == 01929define i32 @ne_latch_mod_step(ptr %array, i32 %length) {1930; CHECK-LABEL: @ne_latch_mod_step(1931; CHECK-NEXT: loop.preheader:1932; CHECK-NEXT: br label [[LOOP:%.*]]1933; CHECK: loop:1934; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]1935; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]1936; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]1937; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 21938; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], 4001939; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1940; CHECK: exit:1941; CHECK-NEXT: ret i32 01942;1943loop.preheader:1944 br label %loop1945 1946loop:1947 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]1948 %within.bounds = icmp ult i32 %i, %length1949 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1950 1951 %i.next = add nuw i32 %i, 21952 %continue = icmp ne i32 %i, 4001953 br i1 %continue, label %loop, label %exit1954 1955exit:1956 ret i32 01957}1958 1959; NE Latch - but end > start so wraps around and not equivelent to a ult1960define i32 @neg_ne_latch_swapped_order(ptr %array, i32 %length) {1961; CHECK-LABEL: @neg_ne_latch_swapped_order(1962; CHECK-NEXT: loop.preheader:1963; CHECK-NEXT: br label [[LOOP:%.*]]1964; CHECK: loop:1965; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]1966; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]1967; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]1968; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 11969; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I]], 01970; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1971; CHECK: exit:1972; CHECK-NEXT: ret i32 01973;1974loop.preheader:1975 br label %loop1976 1977loop:1978 %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]1979 %within.bounds = icmp ult i32 %i, %length1980 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]1981 1982 %i.next = add i32 %i, 11983 %continue = icmp ne i32 %i, 01984 br i1 %continue, label %loop, label %exit1985 1986exit:1987 ret i32 01988}1989 1990; Negative test, make sure we don't crash on unconditional latches1991; TODO: there's no reason we shouldn't be able to predicate the1992; condition for an statically infinite loop.1993define i32 @unconditional_latch(ptr %a, i32 %length) {1994; CHECK-LABEL: @unconditional_latch(1995; CHECK-NEXT: loop.preheader:1996; CHECK-NEXT: br label [[LOOP:%.*]]1997; CHECK: loop:1998; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]1999; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]2000; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]2001; CHECK-NEXT: store volatile i32 0, ptr [[A:%.*]], align 42002; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 12003; CHECK-NEXT: br label [[LOOP]]2004;2005loop.preheader:2006 br label %loop2007 2008loop:2009 %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]2010 %within.bounds = icmp ult i32 %i, %length2011 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]2012 store volatile i32 0, ptr %a2013 %i.next = add i32 %i, 12014 br label %loop2015}2016