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