16162f6e9SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 26162f6e9SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 36162f6e9SFlorian Hahn 46162f6e9SFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 56162f6e9SFlorian Hahn 66162f6e9SFlorian Hahn 76162f6e9SFlorian Hahndeclare void @use(ptr) 86162f6e9SFlorian Hahndeclare void @use.i1(i1) 96162f6e9SFlorian Hahndeclare void @llvm.assume(i1) 106162f6e9SFlorian Hahndeclare i1 @cond() 116162f6e9SFlorian Hahn 126162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start, i16 %len) { 136162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge( 146162f6e9SFlorian Hahn; CHECK-NEXT: entry: 156162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 166162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 176162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 186162f6e9SFlorian Hahn; CHECK: loop.ph: 196162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 206162f6e9SFlorian Hahn; CHECK: loop.header: 216162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 226162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 236162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 246162f6e9SFlorian Hahn; CHECK: for.body: 25*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 266162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 276162f6e9SFlorian Hahn; CHECK: loop.latch: 286162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 296162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 306162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 316162f6e9SFlorian Hahn; CHECK: exit: 326162f6e9SFlorian Hahn; CHECK-NEXT: ret void 336162f6e9SFlorian Hahn; 346162f6e9SFlorian Hahnentry: 356162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 366162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 376162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 386162f6e9SFlorian Hahn 396162f6e9SFlorian Hahnloop.ph: 406162f6e9SFlorian Hahn br label %loop.header 416162f6e9SFlorian Hahn 426162f6e9SFlorian Hahnloop.header: 436162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 446162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 456162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 466162f6e9SFlorian Hahn 476162f6e9SFlorian Hahnfor.body: 486162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 496162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 506162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 516162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 526162f6e9SFlorian Hahn 536162f6e9SFlorian Hahnloop.latch: 546162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 556162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 566162f6e9SFlorian Hahn br label %loop.header 576162f6e9SFlorian Hahn 586162f6e9SFlorian Hahnexit: 596162f6e9SFlorian Hahn ret void 606162f6e9SFlorian Hahn} 616162f6e9SFlorian Hahn 626162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge_incoming_values_reordered(ptr %start, i16 %len) { 636162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_incoming_values_reordered( 646162f6e9SFlorian Hahn; CHECK-NEXT: entry: 656162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 666162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 676162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 686162f6e9SFlorian Hahn; CHECK: loop.ph: 696162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 706162f6e9SFlorian Hahn; CHECK: loop.header: 716162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ [[START]], [[LOOP_PH]] ] 726162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 736162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 746162f6e9SFlorian Hahn; CHECK: for.body: 75*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 766162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 776162f6e9SFlorian Hahn; CHECK: loop.latch: 786162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 796162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 806162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 816162f6e9SFlorian Hahn; CHECK: exit: 826162f6e9SFlorian Hahn; CHECK-NEXT: ret void 836162f6e9SFlorian Hahn; 846162f6e9SFlorian Hahnentry: 856162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 866162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 876162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 886162f6e9SFlorian Hahn 896162f6e9SFlorian Hahnloop.ph: 906162f6e9SFlorian Hahn br label %loop.header 916162f6e9SFlorian Hahn 926162f6e9SFlorian Hahnloop.header: 936162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %loop.ph ] 946162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 956162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 966162f6e9SFlorian Hahn 976162f6e9SFlorian Hahnfor.body: 986162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 996162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 1006162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 1016162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 1026162f6e9SFlorian Hahn 1036162f6e9SFlorian Hahnloop.latch: 1046162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 1056162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 1066162f6e9SFlorian Hahn br label %loop.header 1076162f6e9SFlorian Hahn 1086162f6e9SFlorian Hahnexit: 1096162f6e9SFlorian Hahn ret void 1106162f6e9SFlorian Hahn} 1116162f6e9SFlorian Hahn 1126162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_preheader(ptr %start, i16 %len) { 1136162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_preheader( 1146162f6e9SFlorian Hahn; CHECK-NEXT: entry: 1156162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 1166162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 1176162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_HEADER:%.*]] 1186162f6e9SFlorian Hahn; CHECK: loop.header: 1196162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1206162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 1216162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 1226162f6e9SFlorian Hahn; CHECK: for.body: 123*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 1246162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 1256162f6e9SFlorian Hahn; CHECK: loop.latch: 1266162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 1276162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 1286162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 1296162f6e9SFlorian Hahn; CHECK: exit: 1306162f6e9SFlorian Hahn; CHECK-NEXT: ret void 1316162f6e9SFlorian Hahn; 1326162f6e9SFlorian Hahnentry: 1336162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 1346162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 1356162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.header 1366162f6e9SFlorian Hahn 1376162f6e9SFlorian Hahnloop.header: 1386162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ] 1396162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 1406162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 1416162f6e9SFlorian Hahn 1426162f6e9SFlorian Hahnfor.body: 1436162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 1446162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 1456162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 1466162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 1476162f6e9SFlorian Hahn 1486162f6e9SFlorian Hahnloop.latch: 1496162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 1506162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 1516162f6e9SFlorian Hahn br label %loop.header 1526162f6e9SFlorian Hahn 1536162f6e9SFlorian Hahnexit: 1546162f6e9SFlorian Hahn ret void 1556162f6e9SFlorian Hahn} 1566162f6e9SFlorian Hahn 15772c826cfSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types(ptr %start, i16 %len) { 15872c826cfSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types( 15972c826cfSFlorian Hahn; CHECK-NEXT: entry: 16072c826cfSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 16172c826cfSFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 16272c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 16372c826cfSFlorian Hahn; CHECK: loop.ph: 16472c826cfSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 16572c826cfSFlorian Hahn; CHECK: loop.header: 16672c826cfSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 16772c826cfSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 16872c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 16972c826cfSFlorian Hahn; CHECK: for.body: 170*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 17172c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 17272c826cfSFlorian Hahn; CHECK: loop.latch: 17372c826cfSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 17472c826cfSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 17572c826cfSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 17672c826cfSFlorian Hahn; CHECK: exit: 17772c826cfSFlorian Hahn; CHECK-NEXT: ret void 17872c826cfSFlorian Hahn; 17972c826cfSFlorian Hahnentry: 18072c826cfSFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 18172c826cfSFlorian Hahn %len.neg = icmp slt i16 %len, 0 18272c826cfSFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 18372c826cfSFlorian Hahn 18472c826cfSFlorian Hahnloop.ph: 18572c826cfSFlorian Hahn br label %loop.header 18672c826cfSFlorian Hahn 18772c826cfSFlorian Hahnloop.header: 18872c826cfSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 18972c826cfSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 19072c826cfSFlorian Hahn br i1 %c, label %exit, label %for.body 19172c826cfSFlorian Hahn 19272c826cfSFlorian Hahnfor.body: 19372c826cfSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 19472c826cfSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 19572c826cfSFlorian Hahn %and = and i1 %t.1, %t.2 19672c826cfSFlorian Hahn br i1 %and, label %loop.latch, label %exit 19772c826cfSFlorian Hahn 19872c826cfSFlorian Hahnloop.latch: 19972c826cfSFlorian Hahn call void @use(ptr %ptr.iv) 20072c826cfSFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 20172c826cfSFlorian Hahn br label %loop.header 20272c826cfSFlorian Hahn 20372c826cfSFlorian Hahnexit: 20472c826cfSFlorian Hahn ret void 20572c826cfSFlorian Hahn} 20672c826cfSFlorian Hahn 20772c826cfSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_2(ptr %start, i16 %len) { 20872c826cfSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_2( 20972c826cfSFlorian Hahn; CHECK-NEXT: entry: 21072c826cfSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]] 21172c826cfSFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 21272c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 21372c826cfSFlorian Hahn; CHECK: loop.ph: 21472c826cfSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 21572c826cfSFlorian Hahn; CHECK: loop.header: 21672c826cfSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 21772c826cfSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 21872c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 21972c826cfSFlorian Hahn; CHECK: for.body: 22072c826cfSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 221*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 22272c826cfSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 22372c826cfSFlorian Hahn; CHECK: loop.latch: 22472c826cfSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 22572c826cfSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 22672c826cfSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 22772c826cfSFlorian Hahn; CHECK: exit: 22872c826cfSFlorian Hahn; CHECK-NEXT: ret void 22972c826cfSFlorian Hahn; 23072c826cfSFlorian Hahnentry: 23172c826cfSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 %len 23272c826cfSFlorian Hahn %len.neg = icmp slt i16 %len, 0 23372c826cfSFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 23472c826cfSFlorian Hahn 23572c826cfSFlorian Hahnloop.ph: 23672c826cfSFlorian Hahn br label %loop.header 23772c826cfSFlorian Hahn 23872c826cfSFlorian Hahnloop.header: 23972c826cfSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 24072c826cfSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 24172c826cfSFlorian Hahn br i1 %c, label %exit, label %for.body 24272c826cfSFlorian Hahn 24372c826cfSFlorian Hahnfor.body: 24472c826cfSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 24572c826cfSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 24672c826cfSFlorian Hahn %and = and i1 %t.1, %t.2 24772c826cfSFlorian Hahn br i1 %and, label %loop.latch, label %exit 24872c826cfSFlorian Hahn 24972c826cfSFlorian Hahnloop.latch: 25072c826cfSFlorian Hahn call void @use(ptr %ptr.iv) 25172c826cfSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 25272c826cfSFlorian Hahn br label %loop.header 25372c826cfSFlorian Hahn 25472c826cfSFlorian Hahnexit: 25572c826cfSFlorian Hahn ret void 25672c826cfSFlorian Hahn} 25772c826cfSFlorian Hahn 25882aeec65SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr(ptr %start, ptr %end) { 25982aeec65SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr( 26082aeec65SFlorian Hahn; CHECK-NEXT: entry: 26182aeec65SFlorian Hahn; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]] 26282aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 26382aeec65SFlorian Hahn; CHECK: loop.ph: 26482aeec65SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 26582aeec65SFlorian Hahn; CHECK: loop.header: 26682aeec65SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 26782aeec65SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]] 26882aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 26982aeec65SFlorian Hahn; CHECK: for.body: 270*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 27182aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 27282aeec65SFlorian Hahn; CHECK: loop.latch: 27382aeec65SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 27482aeec65SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 27582aeec65SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 27682aeec65SFlorian Hahn; CHECK: exit: 27782aeec65SFlorian Hahn; CHECK-NEXT: ret void 27882aeec65SFlorian Hahn; 27982aeec65SFlorian Hahnentry: 28082aeec65SFlorian Hahn %start.ult.end = icmp uge ptr %start, %end 28182aeec65SFlorian Hahn br i1 %start.ult.end, label %exit, label %loop.ph 28282aeec65SFlorian Hahn 28382aeec65SFlorian Hahnloop.ph: 28482aeec65SFlorian Hahn br label %loop.header 28582aeec65SFlorian Hahn 28682aeec65SFlorian Hahnloop.header: 28782aeec65SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 28882aeec65SFlorian Hahn %c = icmp eq ptr %ptr.iv, %end 28982aeec65SFlorian Hahn br i1 %c, label %exit, label %for.body 29082aeec65SFlorian Hahn 29182aeec65SFlorian Hahnfor.body: 29282aeec65SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 29382aeec65SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %end 29482aeec65SFlorian Hahn %and = and i1 %t.1, %t.2 29582aeec65SFlorian Hahn br i1 %and, label %loop.latch, label %exit 29682aeec65SFlorian Hahn 29782aeec65SFlorian Hahnloop.latch: 29882aeec65SFlorian Hahn call void @use(ptr %ptr.iv) 29982aeec65SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 30082aeec65SFlorian Hahn br label %loop.header 30182aeec65SFlorian Hahn 30282aeec65SFlorian Hahnexit: 30382aeec65SFlorian Hahn ret void 30482aeec65SFlorian Hahn} 30582aeec65SFlorian Hahn 30682aeec65SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr(ptr %start, ptr %end) { 30782aeec65SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr( 30882aeec65SFlorian Hahn; CHECK-NEXT: entry: 30982aeec65SFlorian Hahn; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]] 31082aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 31182aeec65SFlorian Hahn; CHECK: loop.ph: 31282aeec65SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 31382aeec65SFlorian Hahn; CHECK: loop.header: 31482aeec65SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 31582aeec65SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]] 31682aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 31782aeec65SFlorian Hahn; CHECK: for.body: 31882aeec65SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[END]] 319*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 32082aeec65SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 32182aeec65SFlorian Hahn; CHECK: loop.latch: 32282aeec65SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 32382aeec65SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 32482aeec65SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 32582aeec65SFlorian Hahn; CHECK: exit: 32682aeec65SFlorian Hahn; CHECK-NEXT: ret void 32782aeec65SFlorian Hahn; 32882aeec65SFlorian Hahnentry: 32982aeec65SFlorian Hahn %start.ult.end = icmp uge ptr %start, %end 33082aeec65SFlorian Hahn br i1 %start.ult.end, label %exit, label %loop.ph 33182aeec65SFlorian Hahn 33282aeec65SFlorian Hahnloop.ph: 33382aeec65SFlorian Hahn br label %loop.header 33482aeec65SFlorian Hahn 33582aeec65SFlorian Hahnloop.header: 33682aeec65SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 33782aeec65SFlorian Hahn %c = icmp eq ptr %ptr.iv, %end 33882aeec65SFlorian Hahn br i1 %c, label %exit, label %for.body 33982aeec65SFlorian Hahn 34082aeec65SFlorian Hahnfor.body: 34182aeec65SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 34282aeec65SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %end 34382aeec65SFlorian Hahn %and = and i1 %t.1, %t.2 34482aeec65SFlorian Hahn br i1 %and, label %loop.latch, label %exit 34582aeec65SFlorian Hahn 34682aeec65SFlorian Hahnloop.latch: 34782aeec65SFlorian Hahn call void @use(ptr %ptr.iv) 34882aeec65SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 34982aeec65SFlorian Hahn br label %loop.header 35082aeec65SFlorian Hahn 35182aeec65SFlorian Hahnexit: 35282aeec65SFlorian Hahn ret void 35382aeec65SFlorian Hahn} 35482aeec65SFlorian Hahn 3556162f6e9SFlorian Hahndefine void @test_ptr_iv_upper_may_be_less_than_start(ptr %start, i16 %len) { 3566162f6e9SFlorian Hahn; CHECK-LABEL: @test_ptr_iv_upper_may_be_less_than_start( 3576162f6e9SFlorian Hahn; CHECK-NEXT: entry: 3586162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 3596162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 3606162f6e9SFlorian Hahn; CHECK: loop.header: 3616162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 3626162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 3636162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 3646162f6e9SFlorian Hahn; CHECK: for.body: 3656162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 366*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_2]] 3676162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 3686162f6e9SFlorian Hahn; CHECK: loop.latch: 3696162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 3706162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 3716162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 3726162f6e9SFlorian Hahn; CHECK: exit: 3736162f6e9SFlorian Hahn; CHECK-NEXT: ret void 3746162f6e9SFlorian Hahn; 3756162f6e9SFlorian Hahnentry: 3766162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 3776162f6e9SFlorian Hahn br label %loop.header 3786162f6e9SFlorian Hahn 3796162f6e9SFlorian Hahnloop.header: 3806162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ] 3816162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 3826162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 3836162f6e9SFlorian Hahn 3846162f6e9SFlorian Hahnfor.body: 3856162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 3866162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 3876162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 3886162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 3896162f6e9SFlorian Hahn 3906162f6e9SFlorian Hahnloop.latch: 3916162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 3926162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 3936162f6e9SFlorian Hahn br label %loop.header 3946162f6e9SFlorian Hahn 3956162f6e9SFlorian Hahnexit: 3966162f6e9SFlorian Hahn ret void 3976162f6e9SFlorian Hahn} 3986162f6e9SFlorian Hahn 3996162f6e9SFlorian Hahndefine void @test_no_ptr_iv_step_inst_doesnt_use_phi(ptr %start, ptr %p, i16 %len) { 4006162f6e9SFlorian Hahn; CHECK-LABEL: @test_no_ptr_iv_step_inst_doesnt_use_phi( 4016162f6e9SFlorian Hahn; CHECK-NEXT: entry: 4026162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 4036162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 4046162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 4056162f6e9SFlorian Hahn; CHECK: loop.ph: 4066162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 4076162f6e9SFlorian Hahn; CHECK: loop.header: 4086162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 4096162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 4106162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 4116162f6e9SFlorian Hahn; CHECK: for.body: 4126162f6e9SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 4136162f6e9SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 4146162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 4156162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 4166162f6e9SFlorian Hahn; CHECK: loop.latch: 4176162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 4186162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[P:%.*]], i16 1 4196162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 4206162f6e9SFlorian Hahn; CHECK: exit: 4216162f6e9SFlorian Hahn; CHECK-NEXT: ret void 4226162f6e9SFlorian Hahn; 4236162f6e9SFlorian Hahnentry: 4246162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 4256162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 4266162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 4276162f6e9SFlorian Hahn 4286162f6e9SFlorian Hahnloop.ph: 4296162f6e9SFlorian Hahn br label %loop.header 4306162f6e9SFlorian Hahn 4316162f6e9SFlorian Hahnloop.header: 4326162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 4336162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 4346162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 4356162f6e9SFlorian Hahn 4366162f6e9SFlorian Hahnfor.body: 4376162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 4386162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 4396162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 4406162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 4416162f6e9SFlorian Hahn 4426162f6e9SFlorian Hahnloop.latch: 4436162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 4446162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %p, i16 1 4456162f6e9SFlorian Hahn br label %loop.header 4466162f6e9SFlorian Hahn 4476162f6e9SFlorian Hahnexit: 4486162f6e9SFlorian Hahn ret void 4496162f6e9SFlorian Hahn} 4506162f6e9SFlorian Hahn 451cbacab26SFlorian Hahndefine void @test_no_ptr_iv_step_inst_doesnt_use_phi_2(ptr %start, ptr %end, i16 %len) { 452cbacab26SFlorian Hahn; CHECK-LABEL: @test_no_ptr_iv_step_inst_doesnt_use_phi_2( 453cbacab26SFlorian Hahn; CHECK-NEXT: entry: 454cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]] 455cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 456cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 457cbacab26SFlorian Hahn; CHECK: loop.ph: 458cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 459cbacab26SFlorian Hahn; CHECK: loop.header: 460cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 461cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[END:%.*]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT]], [[LOOP_LATCH]] ] 462cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 463cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[LOOP_NEXT:%.*]] 464cbacab26SFlorian Hahn; CHECK: loop.next: 465cbacab26SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 466cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 467cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 468cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 469cbacab26SFlorian Hahn; CHECK: loop.latch: 470cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 471cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV_2]], i16 1 472cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 473cbacab26SFlorian Hahn; CHECK: exit: 474cbacab26SFlorian Hahn; CHECK-NEXT: ret void 475cbacab26SFlorian Hahn; 476cbacab26SFlorian Hahnentry: 477cbacab26SFlorian Hahn %upper = getelementptr inbounds float, ptr %start, i16 %len 478cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 479cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 480cbacab26SFlorian Hahn 481cbacab26SFlorian Hahnloop.ph: 482cbacab26SFlorian Hahn br label %loop.header 483cbacab26SFlorian Hahn 484cbacab26SFlorian Hahnloop.header: 485cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 486cbacab26SFlorian Hahn %ptr.iv.2 = phi ptr [ %end, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 487cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 488cbacab26SFlorian Hahn br i1 %c, label %exit, label %loop.next 489cbacab26SFlorian Hahn 490cbacab26SFlorian Hahnloop.next: 491cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 492cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 493cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 494cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 495cbacab26SFlorian Hahn 496cbacab26SFlorian Hahnloop.latch: 497cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 498cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv.2, i16 1 499cbacab26SFlorian Hahn br label %loop.header 500cbacab26SFlorian Hahn 501cbacab26SFlorian Hahnexit: 502cbacab26SFlorian Hahn ret void 503cbacab26SFlorian Hahn} 504cbacab26SFlorian Hahn 5056162f6e9SFlorian Hahndefine void @test_no_ptr_iv_different_start(ptr %start, ptr %p, i16 %len) { 5066162f6e9SFlorian Hahn; CHECK-LABEL: @test_no_ptr_iv_different_start( 5076162f6e9SFlorian Hahn; CHECK-NEXT: entry: 5086162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 5096162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 5106162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 5116162f6e9SFlorian Hahn; CHECK: loop.ph: 5126162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 5136162f6e9SFlorian Hahn; CHECK: loop.header: 5146162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[P:%.*]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 5156162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 5166162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 5176162f6e9SFlorian Hahn; CHECK: for.body: 5186162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 5196162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 5206162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 5216162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 5226162f6e9SFlorian Hahn; CHECK: loop.latch: 5236162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 5246162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 5256162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 5266162f6e9SFlorian Hahn; CHECK: exit: 5276162f6e9SFlorian Hahn; CHECK-NEXT: ret void 5286162f6e9SFlorian Hahn; 5296162f6e9SFlorian Hahnentry: 5306162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 5316162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 5326162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 5336162f6e9SFlorian Hahn 5346162f6e9SFlorian Hahnloop.ph: 5356162f6e9SFlorian Hahn br label %loop.header 5366162f6e9SFlorian Hahn 5376162f6e9SFlorian Hahnloop.header: 5386162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %p, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 5396162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 5406162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 5416162f6e9SFlorian Hahn 5426162f6e9SFlorian Hahnfor.body: 5436162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 5446162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 5456162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 5466162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 5476162f6e9SFlorian Hahn 5486162f6e9SFlorian Hahnloop.latch: 5496162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 5506162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 5516162f6e9SFlorian Hahn br label %loop.header 5526162f6e9SFlorian Hahn 5536162f6e9SFlorian Hahnexit: 5546162f6e9SFlorian Hahn ret void 5556162f6e9SFlorian Hahn} 5566162f6e9SFlorian Hahn 5576162f6e9SFlorian Hahndefine void @test_ptr_iv_not_inbounds(ptr %start, i16 %len) { 5586162f6e9SFlorian Hahn; CHECK-LABEL: @test_ptr_iv_not_inbounds( 5596162f6e9SFlorian Hahn; CHECK-NEXT: entry: 5606162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 5616162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 5626162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 5636162f6e9SFlorian Hahn; CHECK: loop.ph: 5646162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 5656162f6e9SFlorian Hahn; CHECK: loop.header: 5666162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 5676162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 5686162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 5696162f6e9SFlorian Hahn; CHECK: for.body: 570*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 5716162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 5726162f6e9SFlorian Hahn; CHECK: loop.latch: 5736162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 5746162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr i32, ptr [[PTR_IV]], i16 1 5756162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 5766162f6e9SFlorian Hahn; CHECK: exit: 5776162f6e9SFlorian Hahn; CHECK-NEXT: ret void 5786162f6e9SFlorian Hahn; 5796162f6e9SFlorian Hahnentry: 5806162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 5816162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 5826162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 5836162f6e9SFlorian Hahn 5846162f6e9SFlorian Hahnloop.ph: 5856162f6e9SFlorian Hahn br label %loop.header 5866162f6e9SFlorian Hahn 5876162f6e9SFlorian Hahnloop.header: 5886162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 5896162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 5906162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 5916162f6e9SFlorian Hahn 5926162f6e9SFlorian Hahnfor.body: 5936162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 5946162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 5956162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 5966162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 5976162f6e9SFlorian Hahn 5986162f6e9SFlorian Hahnloop.latch: 5996162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 6006162f6e9SFlorian Hahn %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i16 1 6016162f6e9SFlorian Hahn br label %loop.header 6026162f6e9SFlorian Hahn 6036162f6e9SFlorian Hahnexit: 6046162f6e9SFlorian Hahn ret void 6056162f6e9SFlorian Hahn} 6066162f6e9SFlorian Hahn 6076162f6e9SFlorian Hahndefine void @test_var_step_not_monotonic(ptr %start, i16 %len, i16 %step) { 6086162f6e9SFlorian Hahn; CHECK-LABEL: @test_var_step_not_monotonic( 6096162f6e9SFlorian Hahn; CHECK-NEXT: entry: 6106162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 6116162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 6126162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 6136162f6e9SFlorian Hahn; CHECK: loop.ph: 6146162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 6156162f6e9SFlorian Hahn; CHECK: loop.header: 6166162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 6176162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 6186162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 6196162f6e9SFlorian Hahn; CHECK: for.body: 6206162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 6216162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 6226162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 6236162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 6246162f6e9SFlorian Hahn; CHECK: loop.latch: 6256162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 6266162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP:%.*]] 6276162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 6286162f6e9SFlorian Hahn; CHECK: exit: 6296162f6e9SFlorian Hahn; CHECK-NEXT: ret void 6306162f6e9SFlorian Hahn; 6316162f6e9SFlorian Hahnentry: 6326162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 6336162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 6346162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 6356162f6e9SFlorian Hahn 6366162f6e9SFlorian Hahnloop.ph: 6376162f6e9SFlorian Hahn br label %loop.header 6386162f6e9SFlorian Hahn 6396162f6e9SFlorian Hahnloop.header: 6406162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 6416162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 6426162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 6436162f6e9SFlorian Hahn 6446162f6e9SFlorian Hahnfor.body: 6456162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 6466162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 6476162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 6486162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 6496162f6e9SFlorian Hahn 6506162f6e9SFlorian Hahnloop.latch: 6516162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 6526162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step 6536162f6e9SFlorian Hahn br label %loop.header 6546162f6e9SFlorian Hahn 6556162f6e9SFlorian Hahnexit: 6566162f6e9SFlorian Hahn ret void 6576162f6e9SFlorian Hahn} 6586162f6e9SFlorian Hahn 6596162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_step_neg_1(ptr %start, i16 %len) { 6606162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_neg_1( 6616162f6e9SFlorian Hahn; CHECK-NEXT: entry: 6626162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 6636162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 6646162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 6656162f6e9SFlorian Hahn; CHECK: loop.ph: 6666162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 6676162f6e9SFlorian Hahn; CHECK: loop.header: 6686162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 6696162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 6706162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 6716162f6e9SFlorian Hahn; CHECK: for.body: 6726162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 6736162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 6746162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 6756162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 6766162f6e9SFlorian Hahn; CHECK: loop.latch: 6776162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 6786162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 -1 6796162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 6806162f6e9SFlorian Hahn; CHECK: exit: 6816162f6e9SFlorian Hahn; CHECK-NEXT: ret void 6826162f6e9SFlorian Hahn; 6836162f6e9SFlorian Hahnentry: 6846162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 6856162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 6866162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 6876162f6e9SFlorian Hahn 6886162f6e9SFlorian Hahnloop.ph: 6896162f6e9SFlorian Hahn br label %loop.header 6906162f6e9SFlorian Hahn 6916162f6e9SFlorian Hahnloop.header: 6926162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 6936162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 6946162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 6956162f6e9SFlorian Hahn 6966162f6e9SFlorian Hahnfor.body: 6976162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 6986162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 6996162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 7006162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 7016162f6e9SFlorian Hahn 7026162f6e9SFlorian Hahnloop.latch: 7036162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 7046162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 -1 7056162f6e9SFlorian Hahn br label %loop.header 7066162f6e9SFlorian Hahn 7076162f6e9SFlorian Hahnexit: 7086162f6e9SFlorian Hahn ret void 7096162f6e9SFlorian Hahn} 7106162f6e9SFlorian Hahn 7116162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_step_sign_unknown(ptr %start, i16 %len, i16 %step) { 7126162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_unknown( 7136162f6e9SFlorian Hahn; CHECK-NEXT: entry: 7146162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 7156162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 7166162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 7176162f6e9SFlorian Hahn; CHECK: loop.ph: 7186162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 7196162f6e9SFlorian Hahn; CHECK: loop.header: 7206162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 7216162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 7226162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 7236162f6e9SFlorian Hahn; CHECK: for.body: 7246162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 7256162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 7266162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 7276162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 7286162f6e9SFlorian Hahn; CHECK: loop.latch: 7296162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 7306162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP:%.*]] 7316162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 7326162f6e9SFlorian Hahn; CHECK: exit: 7336162f6e9SFlorian Hahn; CHECK-NEXT: ret void 7346162f6e9SFlorian Hahn; 7356162f6e9SFlorian Hahnentry: 7366162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 7376162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 7386162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 7396162f6e9SFlorian Hahn 7406162f6e9SFlorian Hahnloop.ph: 7416162f6e9SFlorian Hahn br label %loop.header 7426162f6e9SFlorian Hahn 7436162f6e9SFlorian Hahnloop.header: 7446162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 7456162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 7466162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 7476162f6e9SFlorian Hahn 7486162f6e9SFlorian Hahnfor.body: 7496162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 7506162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 7516162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 7526162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 7536162f6e9SFlorian Hahn 7546162f6e9SFlorian Hahnloop.latch: 7556162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 7566162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step 7576162f6e9SFlorian Hahn br label %loop.header 7586162f6e9SFlorian Hahn 7596162f6e9SFlorian Hahnexit: 7606162f6e9SFlorian Hahn ret void 7616162f6e9SFlorian Hahn} 7626162f6e9SFlorian Hahn 7636162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_step_sign_positive_through_assume(ptr %start, i16 %len, i16 %step) { 7646162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_positive_through_assume( 7656162f6e9SFlorian Hahn; CHECK-NEXT: entry: 7666162f6e9SFlorian Hahn; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0 7676162f6e9SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[STEP_POS]]) 7686162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 7696162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 7706162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 7716162f6e9SFlorian Hahn; CHECK: loop.ph: 7726162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 7736162f6e9SFlorian Hahn; CHECK: loop.header: 7746162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 7756162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 7766162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 7776162f6e9SFlorian Hahn; CHECK: for.body: 7786162f6e9SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 7796162f6e9SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 7806162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 7816162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 7826162f6e9SFlorian Hahn; CHECK: loop.latch: 7836162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 7846162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]] 7856162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 7866162f6e9SFlorian Hahn; CHECK: exit: 7876162f6e9SFlorian Hahn; CHECK-NEXT: ret void 7886162f6e9SFlorian Hahn; 7896162f6e9SFlorian Hahnentry: 7906162f6e9SFlorian Hahn %step.pos = icmp sge i16 %step, 0 7916162f6e9SFlorian Hahn call void @llvm.assume(i1 %step.pos) 7926162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 7936162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 7946162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 7956162f6e9SFlorian Hahn 7966162f6e9SFlorian Hahnloop.ph: 7976162f6e9SFlorian Hahn br label %loop.header 7986162f6e9SFlorian Hahn 7996162f6e9SFlorian Hahnloop.header: 8006162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 8016162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 8026162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 8036162f6e9SFlorian Hahn 8046162f6e9SFlorian Hahnfor.body: 8056162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 8066162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 8076162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 8086162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 8096162f6e9SFlorian Hahn 8106162f6e9SFlorian Hahnloop.latch: 8116162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 8126162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step 8136162f6e9SFlorian Hahn br label %loop.header 8146162f6e9SFlorian Hahn 8156162f6e9SFlorian Hahnexit: 8166162f6e9SFlorian Hahn ret void 8176162f6e9SFlorian Hahn} 8186162f6e9SFlorian Hahn 8196162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_step_sign_negative_through_assume(ptr %start, i16 %len, i16 %step) { 8206162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_negative_through_assume( 8216162f6e9SFlorian Hahn; CHECK-NEXT: entry: 8226162f6e9SFlorian Hahn; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sle i16 [[STEP:%.*]], 0 8236162f6e9SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[STEP_POS]]) 8246162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 8256162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 8266162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 8276162f6e9SFlorian Hahn; CHECK: loop.ph: 8286162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 8296162f6e9SFlorian Hahn; CHECK: loop.header: 8306162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 8316162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 8326162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 8336162f6e9SFlorian Hahn; CHECK: for.body: 8346162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 8356162f6e9SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 8366162f6e9SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]] 8376162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 8386162f6e9SFlorian Hahn; CHECK: loop.latch: 8396162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 8406162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]] 8416162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 8426162f6e9SFlorian Hahn; CHECK: exit: 8436162f6e9SFlorian Hahn; CHECK-NEXT: ret void 8446162f6e9SFlorian Hahn; 8456162f6e9SFlorian Hahnentry: 8466162f6e9SFlorian Hahn %step.pos = icmp sle i16 %step, 0 8476162f6e9SFlorian Hahn call void @llvm.assume(i1 %step.pos) 8486162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 8496162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 8506162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 8516162f6e9SFlorian Hahn 8526162f6e9SFlorian Hahnloop.ph: 8536162f6e9SFlorian Hahn br label %loop.header 8546162f6e9SFlorian Hahn 8556162f6e9SFlorian Hahnloop.header: 8566162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 8576162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 8586162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 8596162f6e9SFlorian Hahn 8606162f6e9SFlorian Hahnfor.body: 8616162f6e9SFlorian Hahn %c.1 = icmp uge ptr %ptr.iv, %start 8626162f6e9SFlorian Hahn %c.2 = icmp ult ptr %ptr.iv, %upper 8636162f6e9SFlorian Hahn %and = and i1 %c.1, %c.2 8646162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 8656162f6e9SFlorian Hahn 8666162f6e9SFlorian Hahnloop.latch: 8676162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 8686162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step 8696162f6e9SFlorian Hahn br label %loop.header 8706162f6e9SFlorian Hahn 8716162f6e9SFlorian Hahnexit: 8726162f6e9SFlorian Hahn ret void 8736162f6e9SFlorian Hahn} 8746162f6e9SFlorian Hahn 8756162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2(ptr %start, i16 %len) { 8766162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2( 8776162f6e9SFlorian Hahn; CHECK-NEXT: entry: 8786162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 8796162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 8806162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 8816162f6e9SFlorian Hahn; CHECK: loop.ph: 8826162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 8836162f6e9SFlorian Hahn; CHECK: loop.header: 8846162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 8856162f6e9SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 8866162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 8876162f6e9SFlorian Hahn; CHECK: for.body: 8886162f6e9SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 889*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 8906162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 8916162f6e9SFlorian Hahn; CHECK: loop.latch: 8926162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 8936162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2 8946162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 8956162f6e9SFlorian Hahn; CHECK: exit: 8966162f6e9SFlorian Hahn; CHECK-NEXT: ret void 8976162f6e9SFlorian Hahn; 8986162f6e9SFlorian Hahnentry: 8996162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 9006162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 9016162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 9026162f6e9SFlorian Hahn 9036162f6e9SFlorian Hahnloop.ph: 9046162f6e9SFlorian Hahn br label %loop.header 9056162f6e9SFlorian Hahn 9066162f6e9SFlorian Hahnloop.header: 9076162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 9086162f6e9SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 9096162f6e9SFlorian Hahn br i1 %c, label %exit, label %for.body 9106162f6e9SFlorian Hahn 9116162f6e9SFlorian Hahnfor.body: 9126162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 9136162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 9146162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 9156162f6e9SFlorian Hahn br i1 %and, label %loop.latch, label %exit 9166162f6e9SFlorian Hahn 9176162f6e9SFlorian Hahnloop.latch: 9186162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 9196162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2 9206162f6e9SFlorian Hahn br label %loop.header 9216162f6e9SFlorian Hahn 9226162f6e9SFlorian Hahnexit: 9236162f6e9SFlorian Hahn ret void 9246162f6e9SFlorian Hahn} 9256162f6e9SFlorian Hahn 9266162f6e9SFlorian Hahndefine void @test_monotonic_ptr_iv_step_2_cond_controls_single_exit(ptr %start, i16 %len) { 9276162f6e9SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_cond_controls_single_exit( 9286162f6e9SFlorian Hahn; CHECK-NEXT: entry: 9296162f6e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 9306162f6e9SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 9316162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 9326162f6e9SFlorian Hahn; CHECK: loop.ph: 9336162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 9346162f6e9SFlorian Hahn; CHECK: loop.header: 9356162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 9366162f6e9SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 9376162f6e9SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]] 9386162f6e9SFlorian Hahn; CHECK: for.body: 9396162f6e9SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 940*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 9416162f6e9SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 9426162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 9436162f6e9SFlorian Hahn; CHECK: loop.latch: 9446162f6e9SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 9456162f6e9SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2 9466162f6e9SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 9476162f6e9SFlorian Hahn; CHECK: exit: 9486162f6e9SFlorian Hahn; CHECK-NEXT: ret void 9496162f6e9SFlorian Hahn; 9506162f6e9SFlorian Hahnentry: 9516162f6e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 9526162f6e9SFlorian Hahn %len.neg = icmp slt i16 %len, 0 9536162f6e9SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 9546162f6e9SFlorian Hahn 9556162f6e9SFlorian Hahnloop.ph: 9566162f6e9SFlorian Hahn br label %loop.header 9576162f6e9SFlorian Hahn 9586162f6e9SFlorian Hahnloop.header: 9596162f6e9SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 9606162f6e9SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 9616162f6e9SFlorian Hahn br i1 %c.1, label %exit, label %for.body 9626162f6e9SFlorian Hahn 9636162f6e9SFlorian Hahnfor.body: 9646162f6e9SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 9656162f6e9SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 9666162f6e9SFlorian Hahn %and = and i1 %t.1, %t.2 9676162f6e9SFlorian Hahn call void @use.i1(i1 %and) 9686162f6e9SFlorian Hahn br label %loop.latch 9696162f6e9SFlorian Hahn 9706162f6e9SFlorian Hahnloop.latch: 9716162f6e9SFlorian Hahn call void @use(ptr %ptr.iv) 9726162f6e9SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2 9736162f6e9SFlorian Hahn br label %loop.header 9746162f6e9SFlorian Hahn 9756162f6e9SFlorian Hahnexit: 9766162f6e9SFlorian Hahn ret void 9776162f6e9SFlorian Hahn} 9786162f6e9SFlorian Hahn 979c92c9462SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_loop_exits_on_ne(ptr %start, i16 %len) { 980c92c9462SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_loop_exits_on_ne( 981c92c9462SFlorian Hahn; CHECK-NEXT: entry: 982c92c9462SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 983c92c9462SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp sge i16 [[LEN]], 0 984c92c9462SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NEG]]) 985c92c9462SFlorian Hahn; CHECK-NEXT: br label [[LOOP_PH:%.*]] 986c92c9462SFlorian Hahn; CHECK: loop.ph: 987c92c9462SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 988c92c9462SFlorian Hahn; CHECK: loop.header: 989c92c9462SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 990c92c9462SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 991c92c9462SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 992c92c9462SFlorian Hahn; CHECK: for.body: 993c92c9462SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 994c92c9462SFlorian Hahn; CHECK: loop.latch: 995c92c9462SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 996c92c9462SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 997c92c9462SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 998c92c9462SFlorian Hahn; CHECK: exit: 999c92c9462SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 1000c92c9462SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 1001c92c9462SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 1002c92c9462SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 1003c92c9462SFlorian Hahn; CHECK-NEXT: ret void 1004c92c9462SFlorian Hahn; 1005c92c9462SFlorian Hahnentry: 1006c92c9462SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 1007c92c9462SFlorian Hahn %len.neg = icmp sge i16 %len, 0 1008c92c9462SFlorian Hahn call void @llvm.assume(i1 %len.neg) 1009c92c9462SFlorian Hahn br label %loop.ph 1010c92c9462SFlorian Hahn 1011c92c9462SFlorian Hahnloop.ph: 1012c92c9462SFlorian Hahn br label %loop.header 1013c92c9462SFlorian Hahn 1014c92c9462SFlorian Hahnloop.header: 1015c92c9462SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 1016c92c9462SFlorian Hahn %c = icmp ne ptr %ptr.iv, %upper 1017c92c9462SFlorian Hahn br i1 %c, label %exit, label %for.body 1018c92c9462SFlorian Hahn 1019c92c9462SFlorian Hahnfor.body: 1020c92c9462SFlorian Hahn br label %loop.latch 1021c92c9462SFlorian Hahn 1022c92c9462SFlorian Hahnloop.latch: 1023c92c9462SFlorian Hahn call void @use(ptr %ptr.iv) 1024c92c9462SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 1025c92c9462SFlorian Hahn br label %loop.header 1026c92c9462SFlorian Hahn 1027c92c9462SFlorian Hahnexit: 1028c92c9462SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 1029c92c9462SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 1030c92c9462SFlorian Hahn %and = and i1 %c.2, %c.3 1031c92c9462SFlorian Hahn call void @use.i1(i1 %and) 1032c92c9462SFlorian Hahn ret void 1033c92c9462SFlorian Hahn} 10349851edfcSFlorian Hahn 10359851edfcSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_inbounds(ptr %start, i16 %len) { 10369851edfcSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge_no_inbounds( 10379851edfcSFlorian Hahn; CHECK-NEXT: entry: 10389851edfcSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 10399851edfcSFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 10409851edfcSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 10419851edfcSFlorian Hahn; CHECK: loop.ph: 10429851edfcSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 10439851edfcSFlorian Hahn; CHECK: loop.header: 10449851edfcSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 10459851edfcSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 10469851edfcSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 10479851edfcSFlorian Hahn; CHECK: for.body: 10489851edfcSFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 10499851edfcSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 10509851edfcSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 10519851edfcSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 10529851edfcSFlorian Hahn; CHECK: loop.latch: 10539851edfcSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 10549851edfcSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr i32, ptr [[PTR_IV]], i16 1 10559851edfcSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 10569851edfcSFlorian Hahn; CHECK: exit: 10579851edfcSFlorian Hahn; CHECK-NEXT: ret void 10589851edfcSFlorian Hahn; 10599851edfcSFlorian Hahnentry: 10609851edfcSFlorian Hahn %upper = getelementptr i32, ptr %start, i16 %len 10619851edfcSFlorian Hahn %len.neg = icmp slt i16 %len, 0 10629851edfcSFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 10639851edfcSFlorian Hahn 10649851edfcSFlorian Hahnloop.ph: 10659851edfcSFlorian Hahn br label %loop.header 10669851edfcSFlorian Hahn 10679851edfcSFlorian Hahnloop.header: 10689851edfcSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 10699851edfcSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 10709851edfcSFlorian Hahn br i1 %c, label %exit, label %for.body 10719851edfcSFlorian Hahn 10729851edfcSFlorian Hahnfor.body: 10739851edfcSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 10749851edfcSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 10759851edfcSFlorian Hahn %and = and i1 %t.1, %t.2 10769851edfcSFlorian Hahn br i1 %and, label %loop.latch, label %exit 10779851edfcSFlorian Hahn 10789851edfcSFlorian Hahnloop.latch: 10799851edfcSFlorian Hahn call void @use(ptr %ptr.iv) 10809851edfcSFlorian Hahn %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i16 1 10819851edfcSFlorian Hahn br label %loop.header 10829851edfcSFlorian Hahn 10839851edfcSFlorian Hahnexit: 10849851edfcSFlorian Hahn ret void 10859851edfcSFlorian Hahn} 10869851edfcSFlorian Hahn 1087