brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.1 KiB · f05f324 Raw
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