xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/monotonic-pointer-phis.ll (revision e6a1657fa30c747f4412fc47f567660ebe861a9e)
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