1025 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"5 6 7declare void @use(ptr)8declare void @use.i1(i1)9declare void @llvm.assume(i1)10declare i1 @cond()11 12define void @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit(ptr %start, i16 %len) {13; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit(14; CHECK-NEXT: entry:15; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]16; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 017; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]18; CHECK: loop.ph:19; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]20; CHECK: loop.header:21; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]22; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]23; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]24; CHECK: for.body:25; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()26; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]27; CHECK: loop.next:28; CHECK-NEXT: [[AND:%.*]] = and i1 true, true29; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]30; CHECK: loop.latch:31; CHECK-NEXT: call void @use(ptr [[PTR_IV]])32; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 133; CHECK-NEXT: br label [[LOOP_HEADER]]34; CHECK: exit:35; CHECK-NEXT: ret void36;37entry:38 %upper = getelementptr inbounds i32, ptr %start, i16 %len39 %len.neg = icmp slt i16 %len, 040 br i1 %len.neg, label %exit, label %loop.ph41 42loop.ph:43 br label %loop.header44 45loop.header:46 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]47 %c = icmp eq ptr %ptr.iv, %upper48 br i1 %c, label %exit, label %for.body49 50for.body:51 %c.1 = call i1 @cond()52 br i1 %c.1, label %loop.next, label %exit53 54loop.next:55 %t.1 = icmp uge ptr %ptr.iv, %start56 %t.2 = icmp ult ptr %ptr.iv, %upper57 %and = and i1 %t.1, %t.258 br i1 %and, label %loop.latch, label %exit59 60loop.latch:61 call void @use(ptr %ptr.iv)62 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 163 br label %loop.header64 65exit:66 ret void67}68 69define void @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit(ptr %start, i16 %len) {70; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit(71; CHECK-NEXT: entry:72; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]]73; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 074; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]75; CHECK: loop.ph:76; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]77; CHECK: loop.header:78; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]79; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]80; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]81; CHECK: for.body:82; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()83; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]84; CHECK: loop.next:85; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]86; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]87; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]88; CHECK: loop.latch:89; CHECK-NEXT: call void @use(ptr [[PTR_IV]])90; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 191; CHECK-NEXT: br label [[LOOP_HEADER]]92; CHECK: exit:93; CHECK-NEXT: ret void94;95entry:96 %upper = getelementptr inbounds i8, ptr %start, i16 %len97 %len.neg = icmp slt i16 %len, 098 br i1 %len.neg, label %exit, label %loop.ph99 100loop.ph:101 br label %loop.header102 103loop.header:104 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]105 %c = icmp eq ptr %ptr.iv, %upper106 br i1 %c, label %exit, label %for.body107 108for.body:109 %c.1 = call i1 @cond()110 br i1 %c.1, label %loop.next, label %exit111 112loop.next:113 %t.1 = icmp uge ptr %ptr.iv, %start114 %t.2 = icmp ult ptr %ptr.iv, %upper115 %and = and i1 %t.1, %t.2116 br i1 %and, label %loop.latch, label %exit117 118loop.latch:119 call void @use(ptr %ptr.iv)120 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1121 br label %loop.header122 123exit:124 ret void125}126 127define void @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr_with_early_exit(ptr %start, ptr %end) {128; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr_with_early_exit(129; CHECK-NEXT: entry:130; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]]131; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]132; CHECK: loop.ph:133; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]134; CHECK: loop.header:135; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]136; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]]137; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]138; CHECK: for.body:139; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()140; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]141; CHECK: loop.next:142; CHECK-NEXT: [[AND:%.*]] = and i1 true, true143; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]144; CHECK: loop.latch:145; CHECK-NEXT: call void @use(ptr [[PTR_IV]])146; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1147; CHECK-NEXT: br label [[LOOP_HEADER]]148; CHECK: exit:149; CHECK-NEXT: ret void150;151entry:152 %start.ult.end = icmp uge ptr %start, %end153 br i1 %start.ult.end, label %exit, label %loop.ph154 155loop.ph:156 br label %loop.header157 158loop.header:159 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]160 %c = icmp eq ptr %ptr.iv, %end161 br i1 %c, label %exit, label %for.body162 163for.body:164 %c.1 = call i1 @cond()165 br i1 %c.1, label %loop.next, label %exit166 167loop.next:168 %t.1 = icmp uge ptr %ptr.iv, %start169 %t.2 = icmp ult ptr %ptr.iv, %end170 %and = and i1 %t.1, %t.2171 br i1 %and, label %loop.latch, label %exit172 173loop.latch:174 call void @use(ptr %ptr.iv)175 %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1176 br label %loop.header177 178exit:179 ret void180}181 182define void @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr_with_early_exit(ptr %start, ptr %end) {183; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr_with_early_exit(184; CHECK-NEXT: entry:185; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]]186; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]187; CHECK: loop.ph:188; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]189; CHECK: loop.header:190; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]191; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]]192; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]193; CHECK: for.body:194; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()195; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]196; CHECK: loop.next:197; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[END]]198; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]199; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]200; CHECK: loop.latch:201; CHECK-NEXT: call void @use(ptr [[PTR_IV]])202; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1203; CHECK-NEXT: br label [[LOOP_HEADER]]204; CHECK: exit:205; CHECK-NEXT: ret void206;207entry:208 %start.ult.end = icmp uge ptr %start, %end209 br i1 %start.ult.end, label %exit, label %loop.ph210 211loop.ph:212 br label %loop.header213 214loop.header:215 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]216 %c = icmp eq ptr %ptr.iv, %end217 br i1 %c, label %exit, label %for.body218 219for.body:220 %c.1 = call i1 @cond()221 br i1 %c.1, label %loop.next, label %exit222 223loop.next:224 %t.1 = icmp uge ptr %ptr.iv, %start225 %t.2 = icmp ult ptr %ptr.iv, %end226 %and = and i1 %t.1, %t.2227 br i1 %and, label %loop.latch, label %exit228 229loop.latch:230 call void @use(ptr %ptr.iv)231 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1232 br label %loop.header233 234exit:235 ret void236}237 238define void @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit_and_different_upper(ptr %start, ptr %end, i16 %len) {239; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit_and_different_upper(240; CHECK-NEXT: entry:241; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[END:%.*]], i16 [[LEN:%.*]]242; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0243; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]244; CHECK: loop.ph:245; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp ult ptr [[START:%.*]], [[UPPER]]246; CHECK-NEXT: call void @llvm.assume(i1 [[START_ULT_END]])247; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]248; CHECK: loop.header:249; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]250; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]251; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]252; CHECK: for.body:253; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()254; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]255; CHECK: loop.next:256; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]257; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]258; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]259; CHECK: loop.latch:260; CHECK-NEXT: call void @use(ptr [[PTR_IV]])261; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1262; CHECK-NEXT: br label [[LOOP_HEADER]]263; CHECK: exit:264; CHECK-NEXT: ret void265;266entry:267 %upper = getelementptr inbounds i32, ptr %end, i16 %len268 %len.neg = icmp slt i16 %len, 0269 br i1 %len.neg, label %exit, label %loop.ph270 271loop.ph:272 %start.ult.end = icmp ult ptr %start, %upper273 call void @llvm.assume(i1 %start.ult.end)274 br label %loop.header275 276loop.header:277 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]278 %c = icmp eq ptr %ptr.iv, %upper279 br i1 %c, label %exit, label %for.body280 281for.body:282 %c.1 = call i1 @cond()283 br i1 %c.1, label %loop.next, label %exit284 285loop.next:286 %t.1 = icmp uge ptr %ptr.iv, %start287 %t.2 = icmp ult ptr %ptr.iv, %upper288 %and = and i1 %t.1, %t.2289 br i1 %and, label %loop.latch, label %exit290 291loop.latch:292 call void @use(ptr %ptr.iv)293 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1294 br label %loop.header295 296exit:297 ret void298}299 300define void @test_monotonic_ptr_iv_step_sign_positive_through_assume_multi_exit(ptr %start, i16 %len, i16 %step) {301; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_positive_through_assume_multi_exit(302; CHECK-NEXT: entry:303; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0304; CHECK-NEXT: call void @llvm.assume(i1 [[STEP_POS]])305; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]306; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0307; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]308; CHECK: loop.ph:309; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]310; CHECK: loop.header:311; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]312; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]313; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]314; CHECK: for.body:315; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()316; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT]]317; CHECK: then:318; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]319; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]320; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]321; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]322; CHECK: loop.latch:323; CHECK-NEXT: call void @use(ptr [[PTR_IV]])324; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]]325; CHECK-NEXT: br label [[LOOP_HEADER]]326; CHECK: exit:327; CHECK-NEXT: ret void328;329entry:330 %step.pos = icmp sge i16 %step, 0331 call void @llvm.assume(i1 %step.pos)332 %upper = getelementptr inbounds i32, ptr %start, i16 %len333 %len.neg = icmp slt i16 %len, 0334 br i1 %len.neg, label %exit, label %loop.ph335 336loop.ph:337 br label %loop.header338 339loop.header:340 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]341 %c = icmp eq ptr %ptr.iv, %upper342 br i1 %c, label %exit, label %for.body343 344for.body:345 %c.1 = call i1 @cond()346 br i1 %c.1, label %then, label %exit347 348then:349 %c.2 = icmp uge ptr %ptr.iv, %start350 %c.3 = icmp ult ptr %ptr.iv, %upper351 %and = and i1 %c.2, %c.3352 br i1 %and, label %loop.latch, label %exit353 354loop.latch:355 call void @use(ptr %ptr.iv)356 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step357 br label %loop.header358 359exit:360 ret void361}362 363define void @test_monotonic_ptr_iv_cond_doesnt_control_exit(ptr %start, i16 %len) {364; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_control_exit(365; CHECK-NEXT: entry:366; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]367; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0368; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]369; CHECK: loop.ph:370; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]371; CHECK: loop.header:372; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]373; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()374; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]]375; CHECK: for.body:376; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]377; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]]378; CHECK: then:379; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]380; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]381; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]382; CHECK-NEXT: call void @use.i1(i1 [[AND]])383; CHECK-NEXT: br label [[LOOP_LATCH]]384; CHECK: loop.latch:385; CHECK-NEXT: call void @use(ptr [[PTR_IV]])386; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1387; CHECK-NEXT: br label [[LOOP_HEADER]]388; CHECK: exit:389; CHECK-NEXT: ret void390;391entry:392 %upper = getelementptr inbounds i32, ptr %start, i16 %len393 %len.neg = icmp slt i16 %len, 0394 br i1 %len.neg, label %exit, label %loop.ph395 396loop.ph:397 br label %loop.header398 399loop.header:400 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]401 %c.0 = call i1 @cond()402 br i1 %c.0, label %exit, label %for.body403 404for.body:405 %c.1 = icmp ne ptr %ptr.iv, %upper406 br i1 %c.1, label %then, label %loop.latch407 408then:409 %t.1 = icmp uge ptr %ptr.iv, %start410 %t.2 = icmp ult ptr %ptr.iv, %upper411 %and = and i1 %t.1, %t.2412 call void @use.i1(i1 %and)413 br label %loop.latch414 415loop.latch:416 call void @use(ptr %ptr.iv)417 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1418 br label %loop.header419 420exit:421 ret void422}423 424define void @test_monotonic_ptr_iv_cond_doesnt_control_exit2(ptr %start, i16 %len) {425; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_control_exit2(426; CHECK-NEXT: entry:427; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]428; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0429; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]430; CHECK: loop.ph:431; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]432; CHECK: loop.header:433; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]434; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]435; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[FOR_BODY:%.*]]436; CHECK: for.body:437; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()438; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[LOOP_LATCH]]439; CHECK: then:440; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]441; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]442; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]443; CHECK-NEXT: call void @use.i1(i1 [[AND]])444; CHECK-NEXT: br label [[LOOP_LATCH]]445; CHECK: loop.latch:446; CHECK-NEXT: call void @use(ptr [[PTR_IV]])447; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1448; CHECK-NEXT: br label [[LOOP_HEADER]]449; CHECK: exit:450; CHECK-NEXT: ret void451;452entry:453 %upper = getelementptr inbounds i32, ptr %start, i16 %len454 %len.neg = icmp slt i16 %len, 0455 br i1 %len.neg, label %exit, label %loop.ph456 457loop.ph:458 br label %loop.header459 460loop.header:461 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]462 %c.1 = icmp ne ptr %ptr.iv, %upper463 br i1 %c.1, label %then, label %for.body464 465for.body:466 %c.0 = call i1 @cond()467 br i1 %c.0, label %exit, label %loop.latch468 469then:470 %t.1 = icmp uge ptr %ptr.iv, %start471 %t.2 = icmp ult ptr %ptr.iv, %upper472 %and = and i1 %t.1, %t.2473 call void @use.i1(i1 %and)474 br label %loop.latch475 476loop.latch:477 call void @use(ptr %ptr.iv)478 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1479 br label %loop.header480 481exit:482 ret void483}484 485define void @test_monotonic_ptr_iv_cond_doesnt_dominate_checks(ptr %start, i16 %len) {486; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_dominate_checks(487; CHECK-NEXT: entry:488; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]489; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0490; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]491; CHECK: loop.ph:492; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]493; CHECK: loop.header:494; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]495; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()496; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]]497; CHECK: for.body:498; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]499; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]]500; CHECK: then:501; CHECK-NEXT: br label [[LOOP_LATCH]]502; CHECK: loop.latch:503; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]504; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]505; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]506; CHECK-NEXT: call void @use.i1(i1 [[AND]])507; CHECK-NEXT: call void @use(ptr [[PTR_IV]])508; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1509; CHECK-NEXT: br label [[LOOP_HEADER]]510; CHECK: exit:511; CHECK-NEXT: ret void512;513entry:514 %upper = getelementptr inbounds i32, ptr %start, i16 %len515 %len.neg = icmp slt i16 %len, 0516 br i1 %len.neg, label %exit, label %loop.ph517 518loop.ph:519 br label %loop.header520 521loop.header:522 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]523 %c.0 = call i1 @cond()524 br i1 %c.0, label %exit, label %for.body525 526for.body:527 %c.1 = icmp ne ptr %ptr.iv, %upper528 br i1 %c.1, label %then, label %loop.latch529 530then:531 br label %loop.latch532 533loop.latch:534 %c.2 = icmp uge ptr %ptr.iv, %start535 %c.3 = icmp ult ptr %ptr.iv, %upper536 %and = and i1 %c.2, %c.3537 call void @use.i1(i1 %and)538 call void @use(ptr %ptr.iv)539 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1540 br label %loop.header541 542exit:543 ret void544}545 546define void @test_monotonic_ptr_iv_step_2_multi_exit(ptr %start, i16 %len) {547; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_multi_exit(548; CHECK-NEXT: entry:549; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]550; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0551; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]552; CHECK: loop.ph:553; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]554; CHECK: loop.header:555; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]556; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]557; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]]558; CHECK: for.body:559; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()560; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[THEN:%.*]]561; CHECK: then:562; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]563; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_3]]564; CHECK-NEXT: call void @use.i1(i1 [[AND]])565; CHECK-NEXT: br label [[LOOP_LATCH]]566; CHECK: loop.latch:567; CHECK-NEXT: call void @use(ptr [[PTR_IV]])568; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2569; CHECK-NEXT: br label [[LOOP_HEADER]]570; CHECK: exit:571; CHECK-NEXT: ret void572;573entry:574 %upper = getelementptr inbounds i32, ptr %start, i16 %len575 %len.neg = icmp slt i16 %len, 0576 br i1 %len.neg, label %exit, label %loop.ph577 578loop.ph:579 br label %loop.header580 581loop.header:582 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]583 %c.1 = icmp eq ptr %ptr.iv, %upper584 br i1 %c.1, label %exit, label %for.body585 586for.body:587 %c.0 = call i1 @cond()588 br i1 %c.0, label %exit, label %then589 590then:591 %c.2 = icmp uge ptr %ptr.iv, %start592 %c.3 = icmp ult ptr %ptr.iv, %upper593 %and = and i1 %c.2, %c.3594 call void @use.i1(i1 %and)595 br label %loop.latch596 597loop.latch:598 call void @use(ptr %ptr.iv)599 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2600 br label %loop.header601 602exit:603 ret void604}605 606define void @test_monotonic_ptr_iv_step_2_cond_doesnt_control_exit(ptr %start, i16 %len) {607; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_cond_doesnt_control_exit(608; CHECK-NEXT: entry:609; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]610; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0611; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]612; CHECK: loop.ph:613; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]614; CHECK: loop.header:615; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]616; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()617; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]]618; CHECK: for.body:619; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]620; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]]621; CHECK: then:622; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]623; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]624; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]625; CHECK-NEXT: call void @use.i1(i1 [[AND]])626; CHECK-NEXT: br label [[LOOP_LATCH]]627; CHECK: loop.latch:628; CHECK-NEXT: call void @use(ptr [[PTR_IV]])629; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2630; CHECK-NEXT: br label [[LOOP_HEADER]]631; CHECK: exit:632; CHECK-NEXT: ret void633;634entry:635 %upper = getelementptr inbounds i32, ptr %start, i16 %len636 %len.neg = icmp slt i16 %len, 0637 br i1 %len.neg, label %exit, label %loop.ph638 639loop.ph:640 br label %loop.header641 642loop.header:643 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]644 %c.0 = call i1 @cond()645 br i1 %c.0, label %exit, label %for.body646 647for.body:648 %c.1 = icmp ne ptr %ptr.iv, %upper649 br i1 %c.1, label %then, label %loop.latch650 651then:652 %c.2 = icmp uge ptr %ptr.iv, %start653 %c.3 = icmp ult ptr %ptr.iv, %upper654 %and = and i1 %c.2, %c.3655 call void @use.i1(i1 %and)656 br label %loop.latch657 658loop.latch:659 call void @use(ptr %ptr.iv)660 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2661 br label %loop.header662 663exit:664 ret void665}666 667define void @test_monotonic_ptr_iv_step_64_cond_doesnt_control_exit(ptr %start, i16 %len) {668; CHECK-LABEL: @test_monotonic_ptr_iv_step_64_cond_doesnt_control_exit(669; CHECK-NEXT: entry:670; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i64, ptr [[START:%.*]], i16 [[LEN:%.*]]671; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0672; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]673; CHECK: loop.ph:674; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]675; CHECK: loop.header:676; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]677; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()678; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]]679; CHECK: for.body:680; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]681; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]]682; CHECK: then:683; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]684; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]685; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]686; CHECK-NEXT: call void @use.i1(i1 [[AND]])687; CHECK-NEXT: br label [[LOOP_LATCH]]688; CHECK: loop.latch:689; CHECK-NEXT: call void @use(ptr [[PTR_IV]])690; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 4691; CHECK-NEXT: br label [[LOOP_HEADER]]692; CHECK: exit:693; CHECK-NEXT: ret void694;695entry:696 %upper = getelementptr inbounds i64, ptr %start, i16 %len697 %len.neg = icmp slt i16 %len, 0698 br i1 %len.neg, label %exit, label %loop.ph699 700loop.ph:701 br label %loop.header702 703loop.header:704 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]705 %c.0 = call i1 @cond()706 br i1 %c.0, label %exit, label %for.body707 708for.body:709 %c.1 = icmp ne ptr %ptr.iv, %upper710 br i1 %c.1, label %then, label %loop.latch711 712then:713 %c.2 = icmp uge ptr %ptr.iv, %start714 %c.3 = icmp ult ptr %ptr.iv, %upper715 %and = and i1 %c.2, %c.3716 call void @use.i1(i1 %and)717 br label %loop.latch718 719loop.latch:720 call void @use(ptr %ptr.iv)721 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 4722 br label %loop.header723 724exit:725 ret void726}727 728define void @test_monotonic_ptr_iv_step_80_cond_doesnt_control_exit(ptr %start, i16 %len) {729; CHECK-LABEL: @test_monotonic_ptr_iv_step_80_cond_doesnt_control_exit(730; CHECK-NEXT: entry:731; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i64, ptr [[START:%.*]], i16 [[LEN:%.*]]732; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0733; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]734; CHECK: loop.ph:735; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]736; CHECK: loop.header:737; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]738; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()739; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]]740; CHECK: for.body:741; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]742; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]]743; CHECK: then:744; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]745; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]746; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]747; CHECK-NEXT: call void @use.i1(i1 [[AND]])748; CHECK-NEXT: br label [[LOOP_LATCH]]749; CHECK: loop.latch:750; CHECK-NEXT: call void @use(ptr [[PTR_IV]])751; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 5752; CHECK-NEXT: br label [[LOOP_HEADER]]753; CHECK: exit:754; CHECK-NEXT: ret void755;756entry:757 %upper = getelementptr inbounds i64, ptr %start, i16 %len758 %len.neg = icmp slt i16 %len, 0759 br i1 %len.neg, label %exit, label %loop.ph760 761loop.ph:762 br label %loop.header763 764loop.header:765 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]766 %c.0 = call i1 @cond()767 br i1 %c.0, label %exit, label %for.body768 769for.body:770 %c.1 = icmp ne ptr %ptr.iv, %upper771 br i1 %c.1, label %then, label %loop.latch772 773then:774 %c.2 = icmp uge ptr %ptr.iv, %start775 %c.3 = icmp ult ptr %ptr.iv, %upper776 %and = and i1 %c.2, %c.3777 call void @use.i1(i1 %and)778 br label %loop.latch779 780loop.latch:781 call void @use(ptr %ptr.iv)782 %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 5783 br label %loop.header784 785exit:786 ret void787}788 789define void @test_monotonic_ptr_iv_inc_1_check_outside_loop(ptr %start, i16 %len) {790; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_check_outside_loop(791; CHECK-NEXT: entry:792; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]793; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp sge i16 [[LEN]], 0794; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NEG]])795; CHECK-NEXT: br label [[LOOP_PH:%.*]]796; CHECK: loop.ph:797; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]798; CHECK: loop.header:799; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]800; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()801; CHECK-NEXT: br i1 [[C_0]], label [[EXIT:%.*]], label [[LOOP_LATCH]]802; CHECK: loop.latch:803; CHECK-NEXT: call void @use(ptr [[PTR_IV]])804; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1805; CHECK-NEXT: br label [[LOOP_HEADER]]806; CHECK: exit:807; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]808; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT_2:%.*]]809; CHECK: then:810; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]811; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]812; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]813; CHECK-NEXT: call void @use.i1(i1 [[AND]])814; CHECK-NEXT: br label [[EXIT_2]]815; CHECK: exit.2:816; CHECK-NEXT: ret void817;818entry:819 %upper = getelementptr inbounds i32, ptr %start, i16 %len820 %len.neg = icmp sge i16 %len, 0821 call void @llvm.assume(i1 %len.neg)822 br label %loop.ph823 824loop.ph:825 br label %loop.header826 827loop.header:828 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]829 %c.0 = call i1 @cond()830 br i1 %c.0, label %exit, label %loop.latch831 832loop.latch:833 call void @use(ptr %ptr.iv)834 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1835 br label %loop.header836 837exit:838 %c.1 = icmp ne ptr %ptr.iv, %upper839 br i1 %c.1, label %then, label %exit.2840 841then:842 %c.2 = icmp uge ptr %ptr.iv, %start843 %c.3 = icmp ult ptr %ptr.iv, %upper844 %and = and i1 %c.2, %c.3845 call void @use.i1(i1 %and)846 br label %exit.2847 848exit.2:849 ret void850}851 852define void @test_step_gep_doesnt_use_ptr_iv_phi(ptr %start, ptr %other, i16 %len) {853; CHECK-LABEL: @test_step_gep_doesnt_use_ptr_iv_phi(854; CHECK-NEXT: entry:855; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]856; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0857; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]858; CHECK: loop.ph:859; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]860; CHECK: loop.header:861; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]862; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]863; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]864; CHECK: for.body:865; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()866; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]867; CHECK: loop.next:868; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]869; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]870; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]871; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]872; CHECK: loop.latch:873; CHECK-NEXT: call void @use(ptr [[PTR_IV]])874; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[OTHER:%.*]], i16 1875; CHECK-NEXT: br label [[LOOP_HEADER]]876; CHECK: exit:877; CHECK-NEXT: ret void878;879entry:880 %upper = getelementptr inbounds float, ptr %start, i16 %len881 %len.neg = icmp slt i16 %len, 0882 br i1 %len.neg, label %exit, label %loop.ph883 884loop.ph:885 br label %loop.header886 887loop.header:888 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]889 %c = icmp eq ptr %ptr.iv, %upper890 br i1 %c, label %exit, label %for.body891 892for.body:893 %c.1 = call i1 @cond()894 br i1 %c.1, label %loop.next, label %exit895 896loop.next:897 %t.1 = icmp uge ptr %ptr.iv, %start898 %t.2 = icmp ult ptr %ptr.iv, %upper899 %and = and i1 %t.1, %t.2900 br i1 %and, label %loop.latch, label %exit901 902loop.latch:903 call void @use(ptr %ptr.iv)904 %ptr.iv.next = getelementptr inbounds float, ptr %other, i16 1905 br label %loop.header906 907exit:908 ret void909}910 911define void @test_step_gep_not_inbounds(ptr %start, ptr %end, i16 %len) {912; CHECK-LABEL: @test_step_gep_not_inbounds(913; CHECK-NEXT: entry:914; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]915; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0916; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]917; CHECK: loop.ph:918; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]919; CHECK: loop.header:920; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]921; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]922; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]923; CHECK: for.body:924; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()925; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]926; CHECK: loop.next:927; CHECK-NEXT: [[AND:%.*]] = and i1 true, true928; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]929; CHECK: loop.latch:930; CHECK-NEXT: call void @use(ptr [[PTR_IV]])931; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr float, ptr [[PTR_IV]], i16 1932; CHECK-NEXT: br label [[LOOP_HEADER]]933; CHECK: exit:934; CHECK-NEXT: ret void935;936entry:937 %upper = getelementptr inbounds float, ptr %start, i16 %len938 %len.neg = icmp slt i16 %len, 0939 br i1 %len.neg, label %exit, label %loop.ph940 941loop.ph:942 br label %loop.header943 944loop.header:945 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]946 %c = icmp eq ptr %ptr.iv, %upper947 br i1 %c, label %exit, label %for.body948 949for.body:950 %c.1 = call i1 @cond()951 br i1 %c.1, label %loop.next, label %exit952 953loop.next:954 %t.1 = icmp uge ptr %ptr.iv, %start955 %t.2 = icmp ult ptr %ptr.iv, %upper956 %and = and i1 %t.1, %t.2957 br i1 %and, label %loop.latch, label %exit958 959loop.latch:960 call void @use(ptr %ptr.iv)961 %ptr.iv.next = getelementptr float, ptr %ptr.iv, i16 1962 br label %loop.header963 964exit:965 ret void966}967 968define void @test_upper_gep_not_inbounds(ptr %start, ptr %end, i16 %len) {969; CHECK-LABEL: @test_upper_gep_not_inbounds(970; CHECK-NEXT: entry:971; CHECK-NEXT: [[UPPER:%.*]] = getelementptr float, ptr [[START:%.*]], i16 [[LEN:%.*]]972; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0973; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]974; CHECK: loop.ph:975; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]976; CHECK: loop.header:977; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]978; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]979; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]980; CHECK: for.body:981; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()982; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]983; CHECK: loop.next:984; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]985; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]]986; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]987; CHECK: loop.latch:988; CHECK-NEXT: call void @use(ptr [[PTR_IV]])989; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1990; CHECK-NEXT: br label [[LOOP_HEADER]]991; CHECK: exit:992; CHECK-NEXT: ret void993;994entry:995 %upper = getelementptr float, ptr %start, i16 %len996 %len.neg = icmp slt i16 %len, 0997 br i1 %len.neg, label %exit, label %loop.ph998 999loop.ph:1000 br label %loop.header1001 1002loop.header:1003 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]1004 %c = icmp eq ptr %ptr.iv, %upper1005 br i1 %c, label %exit, label %for.body1006 1007for.body:1008 %c.1 = call i1 @cond()1009 br i1 %c.1, label %loop.next, label %exit1010 1011loop.next:1012 %t.1 = icmp uge ptr %ptr.iv, %start1013 %t.2 = icmp ult ptr %ptr.iv, %upper1014 %and = and i1 %t.1, %t.21015 br i1 %and, label %loop.latch, label %exit1016 1017loop.latch:1018 call void @use(ptr %ptr.iv)1019 %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 11020 br label %loop.header1021 1022exit:1023 ret void1024}1025