Index: llvm/test/Transforms/IRCE/stride_more_than_1.ll =================================================================== --- llvm/test/Transforms/IRCE/stride_more_than_1.ll +++ llvm/test/Transforms/IRCE/stride_more_than_1.ll @@ -701,9 +701,116 @@ ret i32 -1 } +; Same as test_09 but range check comparison is inversed. +; TODO: IRCE is allowed. +define i32 @test_10(ptr %p, ptr %capacity_p, ptr %num_elements_p) { +; CHECK-LABEL: define i32 @test_10 +; CHECK-SAME: (ptr [[P:%.*]], ptr [[CAPACITY_P:%.*]], ptr [[NUM_ELEMENTS_P:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P]], align 4, !range [[RNG16]] +; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P]], align 4, !range [[RNG16]] +; CHECK-NEXT: [[LIMIT:%.*]] = sub i32 [[CAPACITY]], 3 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp sge i32 [[IV]], [[LIMIT]] +; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]], !prof [[PROF19:![0-9]+]] +; CHECK: backedge: +; CHECK-NEXT: [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64 +; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE]] +; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 +; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] +; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ] +; CHECK-NEXT: ret i32 [[IV_LCSSA1]] +; CHECK: out_of_bounds: +; CHECK-NEXT: ret i32 -1 +; +entry: + %capacity = load i32, ptr %capacity_p, !range !4 + %num_elements = load i32, ptr %num_elements_p, !range !4 + %limit = sub i32 %capacity, 3 + br label %loop + +loop: + %iv = phi i32 [0, %entry], [%iv.next, %backedge] + %capacity_check = icmp sge i32 %iv, %limit + br i1 %capacity_check, label %out_of_bounds, label %backedge, !prof !6 + +backedge: + %iv.wide = zext i32 %iv to i64 + %el.ptr = getelementptr i32, ptr %p, i64 %iv.wide + store i32 1, ptr %el.ptr + %iv.next = add nuw nsw i32 %iv, 4 + %loop_cond = icmp slt i32 %iv.next, %num_elements + br i1 %loop_cond, label %loop, label %exit + +exit: + ret i32 %iv + +out_of_bounds: + ret i32 -1 +} + +; Same as test_09 but range check comparison is non-strict: +; TODO: IRCE is allowed. +define i32 @test_11(ptr %p, ptr %capacity_p, ptr %num_elements_p) { +; CHECK-LABEL: define i32 @test_11 +; CHECK-SAME: (ptr [[P:%.*]], ptr [[CAPACITY_P:%.*]], ptr [[NUM_ELEMENTS_P:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P]], align 4, !range [[RNG16]] +; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P]], align 4, !range [[RNG16]] +; CHECK-NEXT: [[LIMIT:%.*]] = sub i32 [[CAPACITY]], 4 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[IV]], [[LIMIT]] +; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[BACKEDGE]], label [[OUT_OF_BOUNDS:%.*]], !prof [[PROF17]] +; CHECK: backedge: +; CHECK-NEXT: [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64 +; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE]] +; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 +; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] +; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: [[IV_LCSSA1:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ] +; CHECK-NEXT: ret i32 [[IV_LCSSA1]] +; CHECK: out_of_bounds: +; CHECK-NEXT: ret i32 -1 +; +entry: + %capacity = load i32, ptr %capacity_p, !range !4 + %num_elements = load i32, ptr %num_elements_p, !range !4 + %limit = sub i32 %capacity, 4 + br label %loop + +loop: + %iv = phi i32 [0, %entry], [%iv.next, %backedge] + %capacity_check = icmp sle i32 %iv, %limit + br i1 %capacity_check, label %backedge, label %out_of_bounds, !prof !5 + +backedge: + %iv.wide = zext i32 %iv to i64 + %el.ptr = getelementptr i32, ptr %p, i64 %iv.wide + store i32 1, ptr %el.ptr + %iv.next = add nuw nsw i32 %iv, 4 + %loop_cond = icmp slt i32 %iv.next, %num_elements + br i1 %loop_cond, label %loop, label %exit + +exit: + ret i32 %iv + +out_of_bounds: + ret i32 -1 +} + !0 = !{i32 0, i32 50} !1 = !{i32 0, i32 2147483640} !2 = !{i32 0, i32 2147483641} !3 = !{i32 10, i32 50} !4 = !{i32 1, i32 2147483648} !5 = !{!"branch_weights", i32 1000, i32 1} +!6 = !{!"branch_weights", i32 1, i32 1000}