brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.9 KiB · b343269 Raw
1087 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_eq_to_uge(ptr %start, i16 %len) {13; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(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:    [[AND:%.*]] = and i1 true, true26; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]27; CHECK:       loop.latch:28; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])29; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 130; CHECK-NEXT:    br label [[LOOP_HEADER]]31; CHECK:       exit:32; CHECK-NEXT:    ret void33;34entry:35  %upper = getelementptr inbounds i32, ptr %start, i16 %len36  %len.neg = icmp slt i16 %len, 037  br i1 %len.neg, label %exit, label %loop.ph38 39loop.ph:40  br label %loop.header41 42loop.header:43  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]44  %c = icmp eq ptr %ptr.iv, %upper45  br i1 %c, label %exit, label %for.body46 47for.body:48  %t.1 = icmp uge ptr %ptr.iv, %start49  %t.2 = icmp ult ptr %ptr.iv, %upper50  %and = and i1 %t.1, %t.251  br i1 %and, label %loop.latch, label %exit52 53loop.latch:54  call void @use(ptr %ptr.iv)55  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 156  br label %loop.header57 58exit:59  ret void60}61 62define void @test_monotonic_ptr_iv_inc_1_eq_to_uge_incoming_values_reordered(ptr %start, i16 %len) {63; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_incoming_values_reordered(64; CHECK-NEXT:  entry:65; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]66; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 067; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]68; CHECK:       loop.ph:69; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]70; CHECK:       loop.header:71; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ [[START]], [[LOOP_PH]] ]72; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]73; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]74; CHECK:       for.body:75; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true76; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]77; CHECK:       loop.latch:78; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])79; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 180; CHECK-NEXT:    br label [[LOOP_HEADER]]81; CHECK:       exit:82; CHECK-NEXT:    ret void83;84entry:85  %upper = getelementptr inbounds i32, ptr %start, i16 %len86  %len.neg = icmp slt i16 %len, 087  br i1 %len.neg, label %exit, label %loop.ph88 89loop.ph:90  br label %loop.header91 92loop.header:93  %ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %loop.ph ]94  %c = icmp eq ptr %ptr.iv, %upper95  br i1 %c, label %exit, label %for.body96 97for.body:98  %t.1 = icmp uge ptr %ptr.iv, %start99  %t.2 = icmp ult ptr %ptr.iv, %upper100  %and = and i1 %t.1, %t.2101  br i1 %and, label %loop.latch, label %exit102 103loop.latch:104  call void @use(ptr %ptr.iv)105  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1106  br label %loop.header107 108exit:109  ret void110}111 112define void @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_preheader(ptr %start, i16 %len) {113; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_preheader(114; CHECK-NEXT:  entry:115; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]116; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0117; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_HEADER:%.*]]118; CHECK:       loop.header:119; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]120; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]121; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]122; CHECK:       for.body:123; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true124; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]125; CHECK:       loop.latch:126; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])127; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1128; CHECK-NEXT:    br label [[LOOP_HEADER]]129; CHECK:       exit:130; CHECK-NEXT:    ret void131;132entry:133  %upper = getelementptr inbounds i32, ptr %start, i16 %len134  %len.neg = icmp slt i16 %len, 0135  br i1 %len.neg, label %exit, label %loop.header136 137loop.header:138  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]139  %c = icmp eq ptr %ptr.iv, %upper140  br i1 %c, label %exit, label %for.body141 142for.body:143  %t.1 = icmp uge ptr %ptr.iv, %start144  %t.2 = icmp ult ptr %ptr.iv, %upper145  %and = and i1 %t.1, %t.2146  br i1 %and, label %loop.latch, label %exit147 148loop.latch:149  call void @use(ptr %ptr.iv)150  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1151  br label %loop.header152 153exit:154  ret void155}156 157define void @test_monotonic_ptr_iv_inc_1_different_element_types(ptr %start, i16 %len) {158; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types(159; CHECK-NEXT:  entry:160; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]161; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0162; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]163; CHECK:       loop.ph:164; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]165; CHECK:       loop.header:166; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]167; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]168; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]169; CHECK:       for.body:170; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true171; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]172; CHECK:       loop.latch:173; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])174; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1175; CHECK-NEXT:    br label [[LOOP_HEADER]]176; CHECK:       exit:177; CHECK-NEXT:    ret void178;179entry:180  %upper = getelementptr inbounds i32, ptr %start, i16 %len181  %len.neg = icmp slt i16 %len, 0182  br i1 %len.neg, label %exit, label %loop.ph183 184loop.ph:185  br label %loop.header186 187loop.header:188  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]189  %c = icmp eq ptr %ptr.iv, %upper190  br i1 %c, label %exit, label %for.body191 192for.body:193  %t.1 = icmp uge ptr %ptr.iv, %start194  %t.2 = icmp ult ptr %ptr.iv, %upper195  %and = and i1 %t.1, %t.2196  br i1 %and, label %loop.latch, label %exit197 198loop.latch:199  call void @use(ptr %ptr.iv)200  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1201  br label %loop.header202 203exit:204  ret void205}206 207define void @test_monotonic_ptr_iv_inc_1_different_element_types_2(ptr %start, i16 %len) {208; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_2(209; CHECK-NEXT:  entry:210; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]]211; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0212; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]213; CHECK:       loop.ph:214; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]215; CHECK:       loop.header:216; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]217; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]218; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]219; CHECK:       for.body:220; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]221; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]222; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]223; CHECK:       loop.latch:224; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])225; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1226; CHECK-NEXT:    br label [[LOOP_HEADER]]227; CHECK:       exit:228; CHECK-NEXT:    ret void229;230entry:231  %upper = getelementptr inbounds i8, ptr %start, i16 %len232  %len.neg = icmp slt i16 %len, 0233  br i1 %len.neg, label %exit, label %loop.ph234 235loop.ph:236  br label %loop.header237 238loop.header:239  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]240  %c = icmp eq ptr %ptr.iv, %upper241  br i1 %c, label %exit, label %for.body242 243for.body:244  %t.1 = icmp uge ptr %ptr.iv, %start245  %t.2 = icmp ult ptr %ptr.iv, %upper246  %and = and i1 %t.1, %t.2247  br i1 %and, label %loop.latch, label %exit248 249loop.latch:250  call void @use(ptr %ptr.iv)251  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1252  br label %loop.header253 254exit:255  ret void256}257 258define void @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr(ptr %start, ptr %end) {259; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr(260; CHECK-NEXT:  entry:261; CHECK-NEXT:    [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]]262; CHECK-NEXT:    br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]263; CHECK:       loop.ph:264; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]265; CHECK:       loop.header:266; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]267; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]]268; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]269; CHECK:       for.body:270; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true271; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]272; CHECK:       loop.latch:273; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])274; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1275; CHECK-NEXT:    br label [[LOOP_HEADER]]276; CHECK:       exit:277; CHECK-NEXT:    ret void278;279entry:280  %start.ult.end = icmp uge ptr %start, %end281  br i1 %start.ult.end, label %exit, label %loop.ph282 283loop.ph:284  br label %loop.header285 286loop.header:287  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]288  %c = icmp eq ptr %ptr.iv, %end289  br i1 %c, label %exit, label %for.body290 291for.body:292  %t.1 = icmp uge ptr %ptr.iv, %start293  %t.2 = icmp ult ptr %ptr.iv, %end294  %and = and i1 %t.1, %t.2295  br i1 %and, label %loop.latch, label %exit296 297loop.latch:298  call void @use(ptr %ptr.iv)299  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1300  br label %loop.header301 302exit:303  ret void304}305 306define void @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr(ptr %start, ptr %end) {307; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr(308; CHECK-NEXT:  entry:309; CHECK-NEXT:    [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]]310; CHECK-NEXT:    br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]311; CHECK:       loop.ph:312; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]313; CHECK:       loop.header:314; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]315; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]]316; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]317; CHECK:       for.body:318; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[END]]319; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]320; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]321; CHECK:       loop.latch:322; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])323; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1324; CHECK-NEXT:    br label [[LOOP_HEADER]]325; CHECK:       exit:326; CHECK-NEXT:    ret void327;328entry:329  %start.ult.end = icmp uge ptr %start, %end330  br i1 %start.ult.end, label %exit, label %loop.ph331 332loop.ph:333  br label %loop.header334 335loop.header:336  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]337  %c = icmp eq ptr %ptr.iv, %end338  br i1 %c, label %exit, label %for.body339 340for.body:341  %t.1 = icmp uge ptr %ptr.iv, %start342  %t.2 = icmp ult ptr %ptr.iv, %end343  %and = and i1 %t.1, %t.2344  br i1 %and, label %loop.latch, label %exit345 346loop.latch:347  call void @use(ptr %ptr.iv)348  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1349  br label %loop.header350 351exit:352  ret void353}354 355define void @test_ptr_iv_upper_may_be_less_than_start(ptr %start, i16 %len) {356; CHECK-LABEL: @test_ptr_iv_upper_may_be_less_than_start(357; CHECK-NEXT:  entry:358; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]359; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]360; CHECK:       loop.header:361; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]362; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]363; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]364; CHECK:       for.body:365; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]366; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[C_2]]367; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]368; CHECK:       loop.latch:369; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])370; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1371; CHECK-NEXT:    br label [[LOOP_HEADER]]372; CHECK:       exit:373; CHECK-NEXT:    ret void374;375entry:376  %upper = getelementptr inbounds i32, ptr %start, i16 %len377  br label %loop.header378 379loop.header:380  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]381  %c = icmp eq ptr %ptr.iv, %upper382  br i1 %c, label %exit, label %for.body383 384for.body:385  %c.1 = icmp uge ptr %ptr.iv, %start386  %c.2 = icmp ult ptr %ptr.iv, %upper387  %and = and i1 %c.1, %c.2388  br i1 %and, label %loop.latch, label %exit389 390loop.latch:391  call void @use(ptr %ptr.iv)392  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1393  br label %loop.header394 395exit:396  ret void397}398 399define void @test_no_ptr_iv_step_inst_doesnt_use_phi(ptr %start, ptr %p, i16 %len) {400; CHECK-LABEL: @test_no_ptr_iv_step_inst_doesnt_use_phi(401; CHECK-NEXT:  entry:402; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]403; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0404; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]405; CHECK:       loop.ph:406; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]407; CHECK:       loop.header:408; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]409; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]410; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]411; CHECK:       for.body:412; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]413; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]414; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]415; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]416; CHECK:       loop.latch:417; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])418; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[P:%.*]], i16 1419; CHECK-NEXT:    br label [[LOOP_HEADER]]420; CHECK:       exit:421; CHECK-NEXT:    ret void422;423entry:424  %upper = getelementptr inbounds i32, ptr %start, i16 %len425  %len.neg = icmp slt i16 %len, 0426  br i1 %len.neg, label %exit, label %loop.ph427 428loop.ph:429  br label %loop.header430 431loop.header:432  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]433  %c = icmp eq ptr %ptr.iv, %upper434  br i1 %c, label %exit, label %for.body435 436for.body:437  %t.1 = icmp uge ptr %ptr.iv, %start438  %t.2 = icmp ult ptr %ptr.iv, %upper439  %and = and i1 %t.1, %t.2440  br i1 %and, label %loop.latch, label %exit441 442loop.latch:443  call void @use(ptr %ptr.iv)444  %ptr.iv.next = getelementptr inbounds i32, ptr %p, i16 1445  br label %loop.header446 447exit:448  ret void449}450 451define void @test_no_ptr_iv_step_inst_doesnt_use_phi_2(ptr %start, ptr %end, i16 %len) {452; CHECK-LABEL: @test_no_ptr_iv_step_inst_doesnt_use_phi_2(453; CHECK-NEXT:  entry:454; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]455; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0456; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]457; CHECK:       loop.ph:458; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]459; CHECK:       loop.header:460; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]461; CHECK-NEXT:    [[PTR_IV_2:%.*]] = phi ptr [ [[END:%.*]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT]], [[LOOP_LATCH]] ]462; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]463; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[LOOP_NEXT:%.*]]464; CHECK:       loop.next:465; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]466; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]467; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]468; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]469; CHECK:       loop.latch:470; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])471; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV_2]], i16 1472; CHECK-NEXT:    br label [[LOOP_HEADER]]473; CHECK:       exit:474; CHECK-NEXT:    ret void475;476entry:477  %upper = getelementptr inbounds float, ptr %start, i16 %len478  %len.neg = icmp slt i16 %len, 0479  br i1 %len.neg, label %exit, label %loop.ph480 481loop.ph:482  br label %loop.header483 484loop.header:485  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]486  %ptr.iv.2 = phi ptr [ %end, %loop.ph ], [ %ptr.iv.next, %loop.latch ]487  %c = icmp eq ptr %ptr.iv, %upper488  br i1 %c, label %exit, label %loop.next489 490loop.next:491  %t.1 = icmp uge ptr %ptr.iv, %start492  %t.2 = icmp ult ptr %ptr.iv, %upper493  %and = and i1 %t.1, %t.2494  br i1 %and, label %loop.latch, label %exit495 496loop.latch:497  call void @use(ptr %ptr.iv)498  %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv.2, i16 1499  br label %loop.header500 501exit:502  ret void503}504 505define void @test_no_ptr_iv_different_start(ptr %start, ptr %p, i16 %len) {506; CHECK-LABEL: @test_no_ptr_iv_different_start(507; CHECK-NEXT:  entry:508; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]509; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0510; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]511; CHECK:       loop.ph:512; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]513; CHECK:       loop.header:514; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[P:%.*]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]515; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]516; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]517; CHECK:       for.body:518; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]519; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]520; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]521; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]522; CHECK:       loop.latch:523; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])524; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1525; CHECK-NEXT:    br label [[LOOP_HEADER]]526; CHECK:       exit:527; CHECK-NEXT:    ret void528;529entry:530  %upper = getelementptr inbounds i32, ptr %start, i16 %len531  %len.neg = icmp slt i16 %len, 0532  br i1 %len.neg, label %exit, label %loop.ph533 534loop.ph:535  br label %loop.header536 537loop.header:538  %ptr.iv = phi ptr [ %p, %loop.ph ], [ %ptr.iv.next, %loop.latch ]539  %c = icmp eq ptr %ptr.iv, %upper540  br i1 %c, label %exit, label %for.body541 542for.body:543  %c.1 = icmp uge ptr %ptr.iv, %start544  %c.2 = icmp ult ptr %ptr.iv, %upper545  %and = and i1 %c.1, %c.2546  br i1 %and, label %loop.latch, label %exit547 548loop.latch:549  call void @use(ptr %ptr.iv)550  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1551  br label %loop.header552 553exit:554  ret void555}556 557define void @test_ptr_iv_not_inbounds(ptr %start, i16 %len) {558; CHECK-LABEL: @test_ptr_iv_not_inbounds(559; CHECK-NEXT:  entry:560; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]561; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0562; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]563; CHECK:       loop.ph:564; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]565; CHECK:       loop.header:566; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]567; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]568; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]569; CHECK:       for.body:570; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true571; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]572; CHECK:       loop.latch:573; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])574; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr i32, ptr [[PTR_IV]], i16 1575; CHECK-NEXT:    br label [[LOOP_HEADER]]576; CHECK:       exit:577; CHECK-NEXT:    ret void578;579entry:580  %upper = getelementptr inbounds i32, ptr %start, i16 %len581  %len.neg = icmp slt i16 %len, 0582  br i1 %len.neg, label %exit, label %loop.ph583 584loop.ph:585  br label %loop.header586 587loop.header:588  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]589  %c = icmp eq ptr %ptr.iv, %upper590  br i1 %c, label %exit, label %for.body591 592for.body:593  %c.1 = icmp uge ptr %ptr.iv, %start594  %c.2 = icmp ult ptr %ptr.iv, %upper595  %and = and i1 %c.1, %c.2596  br i1 %and, label %loop.latch, label %exit597 598loop.latch:599  call void @use(ptr %ptr.iv)600  %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i16 1601  br label %loop.header602 603exit:604  ret void605}606 607define void @test_var_step_not_monotonic(ptr %start, i16 %len, i16 %step) {608; CHECK-LABEL: @test_var_step_not_monotonic(609; CHECK-NEXT:  entry:610; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]611; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0612; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]613; CHECK:       loop.ph:614; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]615; CHECK:       loop.header:616; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]617; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]618; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]619; CHECK:       for.body:620; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]621; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]622; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]623; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]624; CHECK:       loop.latch:625; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])626; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP:%.*]]627; CHECK-NEXT:    br label [[LOOP_HEADER]]628; CHECK:       exit:629; CHECK-NEXT:    ret void630;631entry:632  %upper = getelementptr inbounds i32, ptr %start, i16 %len633  %len.neg = icmp slt i16 %len, 0634  br i1 %len.neg, label %exit, label %loop.ph635 636loop.ph:637  br label %loop.header638 639loop.header:640  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]641  %c = icmp eq ptr %ptr.iv, %upper642  br i1 %c, label %exit, label %for.body643 644for.body:645  %c.1 = icmp uge ptr %ptr.iv, %start646  %c.2 = icmp ult ptr %ptr.iv, %upper647  %and = and i1 %c.1, %c.2648  br i1 %and, label %loop.latch, label %exit649 650loop.latch:651  call void @use(ptr %ptr.iv)652  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step653  br label %loop.header654 655exit:656  ret void657}658 659define void @test_monotonic_ptr_iv_step_neg_1(ptr %start, i16 %len) {660; CHECK-LABEL: @test_monotonic_ptr_iv_step_neg_1(661; CHECK-NEXT:  entry:662; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]663; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0664; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]665; CHECK:       loop.ph:666; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]667; CHECK:       loop.header:668; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]669; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]670; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]671; CHECK:       for.body:672; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]673; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]674; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]675; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]676; CHECK:       loop.latch:677; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])678; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 -1679; CHECK-NEXT:    br label [[LOOP_HEADER]]680; CHECK:       exit:681; CHECK-NEXT:    ret void682;683entry:684  %upper = getelementptr inbounds i32, ptr %start, i16 %len685  %len.neg = icmp slt i16 %len, 0686  br i1 %len.neg, label %exit, label %loop.ph687 688loop.ph:689  br label %loop.header690 691loop.header:692  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]693  %c = icmp eq ptr %ptr.iv, %upper694  br i1 %c, label %exit, label %for.body695 696for.body:697  %c.1 = icmp uge ptr %ptr.iv, %start698  %c.2 = icmp ult ptr %ptr.iv, %upper699  %and = and i1 %c.1, %c.2700  br i1 %and, label %loop.latch, label %exit701 702loop.latch:703  call void @use(ptr %ptr.iv)704  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 -1705  br label %loop.header706 707exit:708  ret void709}710 711define void @test_monotonic_ptr_iv_step_sign_unknown(ptr %start, i16 %len, i16 %step) {712; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_unknown(713; CHECK-NEXT:  entry:714; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]715; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0716; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]717; CHECK:       loop.ph:718; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]719; CHECK:       loop.header:720; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]721; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]722; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]723; CHECK:       for.body:724; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]725; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]726; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]727; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]728; CHECK:       loop.latch:729; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])730; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP:%.*]]731; CHECK-NEXT:    br label [[LOOP_HEADER]]732; CHECK:       exit:733; CHECK-NEXT:    ret void734;735entry:736  %upper = getelementptr inbounds i32, ptr %start, i16 %len737  %len.neg = icmp slt i16 %len, 0738  br i1 %len.neg, label %exit, label %loop.ph739 740loop.ph:741  br label %loop.header742 743loop.header:744  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]745  %c = icmp eq ptr %ptr.iv, %upper746  br i1 %c, label %exit, label %for.body747 748for.body:749  %c.1 = icmp uge ptr %ptr.iv, %start750  %c.2 = icmp ult ptr %ptr.iv, %upper751  %and = and i1 %c.1, %c.2752  br i1 %and, label %loop.latch, label %exit753 754loop.latch:755  call void @use(ptr %ptr.iv)756  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step757  br label %loop.header758 759exit:760  ret void761}762 763define void @test_monotonic_ptr_iv_step_sign_positive_through_assume(ptr %start, i16 %len, i16 %step) {764; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_positive_through_assume(765; CHECK-NEXT:  entry:766; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0767; CHECK-NEXT:    call void @llvm.assume(i1 [[STEP_POS]])768; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]769; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0770; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]771; CHECK:       loop.ph:772; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]773; CHECK:       loop.header:774; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]775; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]776; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]777; CHECK:       for.body:778; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]779; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]780; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]781; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]782; CHECK:       loop.latch:783; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])784; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]]785; CHECK-NEXT:    br label [[LOOP_HEADER]]786; CHECK:       exit:787; CHECK-NEXT:    ret void788;789entry:790  %step.pos = icmp sge i16 %step, 0791  call void @llvm.assume(i1 %step.pos)792  %upper = getelementptr inbounds i32, ptr %start, i16 %len793  %len.neg = icmp slt i16 %len, 0794  br i1 %len.neg, label %exit, label %loop.ph795 796loop.ph:797  br label %loop.header798 799loop.header:800  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]801  %c = icmp eq ptr %ptr.iv, %upper802  br i1 %c, label %exit, label %for.body803 804for.body:805  %t.1 = icmp uge ptr %ptr.iv, %start806  %t.2 = icmp ult ptr %ptr.iv, %upper807  %and = and i1 %t.1, %t.2808  br i1 %and, label %loop.latch, label %exit809 810loop.latch:811  call void @use(ptr %ptr.iv)812  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step813  br label %loop.header814 815exit:816  ret void817}818 819define void @test_monotonic_ptr_iv_step_sign_negative_through_assume(ptr %start, i16 %len, i16 %step) {820; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_negative_through_assume(821; CHECK-NEXT:  entry:822; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sle i16 [[STEP:%.*]], 0823; CHECK-NEXT:    call void @llvm.assume(i1 [[STEP_POS]])824; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]825; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0826; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]827; CHECK:       loop.ph:828; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]829; CHECK:       loop.header:830; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]831; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]832; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]833; CHECK:       for.body:834; CHECK-NEXT:    [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]835; CHECK-NEXT:    [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]836; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_1]], [[C_2]]837; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]838; CHECK:       loop.latch:839; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])840; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]]841; CHECK-NEXT:    br label [[LOOP_HEADER]]842; CHECK:       exit:843; CHECK-NEXT:    ret void844;845entry:846  %step.pos = icmp sle i16 %step, 0847  call void @llvm.assume(i1 %step.pos)848  %upper = getelementptr inbounds i32, ptr %start, i16 %len849  %len.neg = icmp slt i16 %len, 0850  br i1 %len.neg, label %exit, label %loop.ph851 852loop.ph:853  br label %loop.header854 855loop.header:856  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]857  %c = icmp eq ptr %ptr.iv, %upper858  br i1 %c, label %exit, label %for.body859 860for.body:861  %c.1 = icmp uge ptr %ptr.iv, %start862  %c.2 = icmp ult ptr %ptr.iv, %upper863  %and = and i1 %c.1, %c.2864  br i1 %and, label %loop.latch, label %exit865 866loop.latch:867  call void @use(ptr %ptr.iv)868  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step869  br label %loop.header870 871exit:872  ret void873}874 875define void @test_monotonic_ptr_iv_inc_2(ptr %start, i16 %len) {876; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2(877; CHECK-NEXT:  entry:878; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]879; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0880; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]881; CHECK:       loop.ph:882; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]883; CHECK:       loop.header:884; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]885; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]886; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]887; CHECK:       for.body:888; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]889; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]890; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]891; CHECK:       loop.latch:892; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])893; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2894; CHECK-NEXT:    br label [[LOOP_HEADER]]895; CHECK:       exit:896; CHECK-NEXT:    ret void897;898entry:899  %upper = getelementptr inbounds i32, ptr %start, i16 %len900  %len.neg = icmp slt i16 %len, 0901  br i1 %len.neg, label %exit, label %loop.ph902 903loop.ph:904  br label %loop.header905 906loop.header:907  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]908  %c = icmp eq ptr %ptr.iv, %upper909  br i1 %c, label %exit, label %for.body910 911for.body:912  %t.1 = icmp uge ptr %ptr.iv, %start913  %t.2 = icmp ult ptr %ptr.iv, %upper914  %and = and i1 %t.1, %t.2915  br i1 %and, label %loop.latch, label %exit916 917loop.latch:918  call void @use(ptr %ptr.iv)919  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2920  br label %loop.header921 922exit:923  ret void924}925 926define void @test_monotonic_ptr_iv_step_2_cond_controls_single_exit(ptr %start, i16 %len) {927; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_cond_controls_single_exit(928; CHECK-NEXT:  entry:929; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]930; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0931; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]932; CHECK:       loop.ph:933; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]934; CHECK:       loop.header:935; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]936; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]937; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]]938; CHECK:       for.body:939; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]940; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]941; CHECK-NEXT:    call void @use.i1(i1 [[AND]])942; CHECK-NEXT:    br label [[LOOP_LATCH]]943; CHECK:       loop.latch:944; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])945; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2946; CHECK-NEXT:    br label [[LOOP_HEADER]]947; CHECK:       exit:948; CHECK-NEXT:    ret void949;950entry:951  %upper = getelementptr inbounds i32, ptr %start, i16 %len952  %len.neg = icmp slt i16 %len, 0953  br i1 %len.neg, label %exit, label %loop.ph954 955loop.ph:956  br label %loop.header957 958loop.header:959  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]960  %c.1 = icmp eq ptr %ptr.iv, %upper961  br i1 %c.1, label %exit, label %for.body962 963for.body:964  %t.1 = icmp uge ptr %ptr.iv, %start965  %t.2 = icmp ult ptr %ptr.iv, %upper966  %and = and i1 %t.1, %t.2967  call void @use.i1(i1 %and)968  br label %loop.latch969 970loop.latch:971  call void @use(ptr %ptr.iv)972  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2973  br label %loop.header974 975exit:976  ret void977}978 979define void @test_monotonic_ptr_iv_inc_1_loop_exits_on_ne(ptr %start, i16 %len) {980; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_loop_exits_on_ne(981; CHECK-NEXT:  entry:982; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]983; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp sge i16 [[LEN]], 0984; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_NEG]])985; CHECK-NEXT:    br label [[LOOP_PH:%.*]]986; CHECK:       loop.ph:987; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]988; CHECK:       loop.header:989; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]990; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]991; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]992; CHECK:       for.body:993; CHECK-NEXT:    br label [[LOOP_LATCH]]994; CHECK:       loop.latch:995; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])996; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1997; CHECK-NEXT:    br label [[LOOP_HEADER]]998; CHECK:       exit:999; CHECK-NEXT:    [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]1000; CHECK-NEXT:    [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]1001; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_3]]1002; CHECK-NEXT:    call void @use.i1(i1 [[AND]])1003; CHECK-NEXT:    ret void1004;1005entry:1006  %upper = getelementptr inbounds i32, ptr %start, i16 %len1007  %len.neg = icmp sge i16 %len, 01008  call void @llvm.assume(i1 %len.neg)1009  br label %loop.ph1010 1011loop.ph:1012  br label %loop.header1013 1014loop.header:1015  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]1016  %c = icmp ne ptr %ptr.iv, %upper1017  br i1 %c, label %exit, label %for.body1018 1019for.body:1020  br label %loop.latch1021 1022loop.latch:1023  call void @use(ptr %ptr.iv)1024  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 11025  br label %loop.header1026 1027exit:1028  %c.2 = icmp uge ptr %ptr.iv, %start1029  %c.3 = icmp ult ptr %ptr.iv, %upper1030  %and = and i1 %c.2, %c.31031  call void @use.i1(i1 %and)1032  ret void1033}1034 1035define void @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_inbounds(ptr %start, i16 %len) {1036; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_inbounds(1037; CHECK-NEXT:  entry:1038; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr i32, ptr [[START:%.*]], i16 [[LEN:%.*]]1039; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 01040; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]1041; CHECK:       loop.ph:1042; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]1043; CHECK:       loop.header:1044; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1045; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]1046; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]1047; CHECK:       for.body:1048; CHECK-NEXT:    [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]1049; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]1050; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[T_2]]1051; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]1052; CHECK:       loop.latch:1053; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])1054; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr i32, ptr [[PTR_IV]], i16 11055; CHECK-NEXT:    br label [[LOOP_HEADER]]1056; CHECK:       exit:1057; CHECK-NEXT:    ret void1058;1059entry:1060  %upper = getelementptr i32, ptr %start, i16 %len1061  %len.neg = icmp slt i16 %len, 01062  br i1 %len.neg, label %exit, label %loop.ph1063 1064loop.ph:1065  br label %loop.header1066 1067loop.header:1068  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]1069  %c = icmp eq ptr %ptr.iv, %upper1070  br i1 %c, label %exit, label %for.body1071 1072for.body:1073  %t.1 = icmp uge ptr %ptr.iv, %start1074  %t.2 = icmp ult ptr %ptr.iv, %upper1075  %and = and i1 %t.1, %t.21076  br i1 %and, label %loop.latch, label %exit1077 1078loop.latch:1079  call void @use(ptr %ptr.iv)1080  %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i16 11081  br label %loop.header1082 1083exit:1084  ret void1085}1086 1087