diff options
author | Eric Christopher <echristo@gmail.com> | 2019-04-17 02:12:23 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2019-04-17 02:12:23 +0000 |
commit | a86343512845c9c1fdbac865fea88aa5fce7142a (patch) | |
tree | 666fc6353de19ad8b00e56b67edd33f24104e4a7 /llvm/test/Transforms/IRCE | |
parent | 7f8ca6e3679b3af951cb7a4b1377edfaa3244b93 (diff) | |
download | bcm5719-llvm-a86343512845c9c1fdbac865fea88aa5fce7142a.tar.gz bcm5719-llvm-a86343512845c9c1fdbac865fea88aa5fce7142a.zip |
Temporarily Revert "Add basic loop fusion pass."
As it's causing some bot failures (and per request from kbarton).
This reverts commit r358543/ab70da07286e618016e78247e4a24fcb84077fda.
llvm-svn: 358546
Diffstat (limited to 'llvm/test/Transforms/IRCE')
32 files changed, 0 insertions, 5977 deletions
diff --git a/llvm/test/Transforms/IRCE/add-metadata-pre-post-loops.ll b/llvm/test/Transforms/IRCE/add-metadata-pre-post-loops.ll deleted file mode 100644 index d47cee00377..00000000000 --- a/llvm/test/Transforms/IRCE/add-metadata-pre-post-loops.ll +++ /dev/null @@ -1,82 +0,0 @@ -; RUN: opt -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; test that the pre and post loops have loop metadata which disables any further -; loop optimizations. - -; generates a post loop, which should have metadata !llvm.loop !2 -; Function Attrs: alwaysinline -define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 { -; CHECK-LABEL: inner_loop( -; CHECK-LABEL: in.bounds.postloop -; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit.loopexit, !llvm.loop !2, !irce.loop.clone !7 - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - -loop: ; preds = %in.bounds, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - -in.bounds: ; preds = %loop - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - -out.of.bounds: ; preds = %loop - ret void - -exit: ; preds = %in.bounds, %entry - ret void -} - -; add loop metadata for pre and post loops -define void @single_access_with_preloop(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32 %offset) { -; CHECK-LABEL: @single_access_with_preloop( -; CHECK-LABEL: in.bounds.preloop -; CHECK: br i1 [[COND:%[^ ]+]], label %loop.preloop, label %preloop.exit.selector, !llvm.loop !8, !irce.loop.clone !7 -; CHECK-LABEL: in.bounds.postloop -; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit.loopexit, !llvm.loop !9, !irce.loop.clone !7 - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %array.idx = add i32 %idx, %offset - %abc.high = icmp slt i32 %array.idx, %len - %abc.low = icmp sge i32 %array.idx, 0 - %abc = and i1 %abc.low, %abc.high - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %array.idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} -attributes #0 = { alwaysinline } - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} -!2 = distinct !{!2, !3, !4, !5, !6} -!3 = !{!"llvm.loop.unroll.disable"} -!4 = !{!"llvm.loop.vectorize.enable", i1 false} -!5 = !{!"llvm.loop.licm_versioning.disable"} -!6 = !{!"llvm.loop.distribute.enable", i1 false} -!7 = !{} -!8 = distinct !{!8, !3, !4, !5} -!9 = distinct !{!9, !3, !4, !5} diff --git a/llvm/test/Transforms/IRCE/bad-loop-structure.ll b/llvm/test/Transforms/IRCE/bad-loop-structure.ll deleted file mode 100644 index e094543d129..00000000000 --- a/llvm/test/Transforms/IRCE/bad-loop-structure.ll +++ /dev/null @@ -1,46 +0,0 @@ -; RUN: opt -S -irce -irce-print-changed-loops=true < %s | FileCheck %s -; RUN: opt -S -passes='require<branch-prob>,loop(irce)' -irce-print-changed-loops=true < %s | FileCheck %s - -; CHECK-NOT: irce - -define void @bad_loop_structure_increasing(i64 %iv.start) { -entry: - br label %for.body - -for.body: - %indvars.iv = phi i64 [ %iv.start, %entry ], [ %indvars.iv.next, %for.inc ] - %cmp = icmp ult i64 %indvars.iv, 100 - br i1 %cmp, label %switch.lookup, label %for.inc - -switch.lookup: - br label %for.inc - -for.inc: - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %cmp55 = icmp slt i64 %indvars.iv.next, 11 - br i1 %cmp55, label %for.body, label %for.end - -for.end: - ret void -} - -define void @bad_loop_structure_decreasing(i64 %iv.start) { -entry: - br label %for.body - -for.body: - %indvars.iv = phi i64 [ %iv.start, %entry ], [ %indvars.iv.next, %for.inc ] - %cmp = icmp ult i64 %indvars.iv, 100 - br i1 %cmp, label %switch.lookup, label %for.inc - -switch.lookup: - br label %for.inc - -for.inc: - %indvars.iv.next = add nuw nsw i64 %indvars.iv, -1 - %cmp55 = icmp sgt i64 %indvars.iv.next, 11 - br i1 %cmp55, label %for.body, label %for.end - -for.end: - ret void -} diff --git a/llvm/test/Transforms/IRCE/bad_expander.ll b/llvm/test/Transforms/IRCE/bad_expander.ll deleted file mode 100644 index bc98456a31b..00000000000 --- a/llvm/test/Transforms/IRCE/bad_expander.ll +++ /dev/null @@ -1,136 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" -target triple = "x86_64-unknown-linux-gnu" - -; IRCE should fail here because the preheader's exiting value is a phi from the -; loop, and this value cannot be expanded at loop's preheader. - -; CHECK-NOT: irce: in function test_01: constrained Loop -; CHECK-NOT: irce: in function test_02: constrained Loop -; CHECK-LABEL: irce: in function test_03: constrained Loop - -define void @test_01() { - -; CHECK-NOT: irce: in function test_01: constrained Loop - -; CHECK-LABEL: test_01 -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK-NOT: br i1 false -; CHECK-NOT: br i1 true - -entry: - br label %loop - -exit: ; preds = %guarded, %loop - ret void - -loop: ; preds = %guarded, %entry - %iv = phi i64 [ 380, %entry ], [ %limit, %guarded ] - %bad_phi = phi i32 [ 3, %entry ], [ %bad_phi.next, %guarded ] - %bad_phi.next = add nuw nsw i32 %bad_phi, 1 - %iv.next = add nuw nsw i64 %iv, 1 - %rc = icmp slt i64 %iv.next, 5 - br i1 %rc, label %guarded, label %exit - -guarded: - %limit = add nsw i64 %iv, -1 - %tmp5 = add nuw nsw i32 %bad_phi, 8 - %tmp6 = zext i32 %tmp5 to i64 - %tmp7 = icmp eq i64 %limit, %tmp6 - br i1 %tmp7, label %exit, label %loop -} - -; This test should fail because we are unable to prove that the division is -; safe to expand it to preheader: if we exit by maybe_exit condition, it is -; unsafe to execute it there. - -define void @test_02(i64* %p1, i64* %p2, i1 %maybe_exit) { - -; CHECK-LABEL: test_02 -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK-NOT: br i1 false -; CHECK-NOT: br i1 true - - -entry: - %num = load i64, i64* %p1, align 4, !range !0 - %denom = load i64, i64* %p2, align 4, !range !0 - br label %loop - -exit: ; preds = %guarded, %loop - ret void - -loop: ; preds = %guarded, %entry - %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ] - %iv.next = add nuw nsw i64 %iv, 1 - br i1 %maybe_exit, label %range_check, label %exit - -range_check: - %div_result = udiv i64 %num, %denom - %rc = icmp slt i64 %iv.next, %div_result - br i1 %rc, label %guarded, label %exit - -guarded: - %gep = getelementptr i64, i64* %p1, i64 %iv.next - %loaded = load i64, i64* %gep, align 4 - %tmp7 = icmp slt i64 %iv.next, 1000 - br i1 %tmp7, label %loop, label %exit -} - -define void @test_03(i64* %p1, i64* %p2, i1 %maybe_exit) { - -; Show that IRCE would hit test_02 if the division was safe (denom not zero). - -; CHECK-LABEL: test_03 -; CHECK: entry: -; CHECK-NEXT: %num = load i64, i64* %p1, align 4 -; CHECK-NEXT: [[DIV:%[^ ]+]] = udiv i64 %num, 13 -; CHECK-NEXT: [[DIV_MINUS_1:%[^ ]+]] = add i64 [[DIV]], -1 -; CHECK-NEXT: [[COMP1:%[^ ]+]] = icmp sgt i64 [[DIV_MINUS_1]], 0 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[COMP1]], i64 [[DIV_MINUS_1]], i64 0 -; CHECK-NEXT: [[COMP2:%[^ ]+]] = icmp slt i64 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COMP2]], label %loop.preheader, label %main.pseudo.exit -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK-NEXT: %iv = phi i64 [ %iv.next, %guarded ], [ 0, %loop.preheader ] -; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1 -; CHECK-NEXT: %rc = icmp slt i64 %iv.next, %div_result -; CHECK-NEXT: %or.cond = and i1 %maybe_exit, true -; CHECK-NEXT: br i1 %or.cond, label %guarded, label %exit.loopexit1 -; CHECK: guarded: -; CHECK-NEXT: %gep = getelementptr i64, i64* %p1, i64 %iv.next -; CHECK-NEXT: %loaded = load i64, i64* %gep, align 4 -; CHECK-NEXT: %tmp7 = icmp slt i64 %iv.next, 1000 -; CHECK-NEXT: [[EXIT_MAIN_LOOP:%[^ ]+]] = icmp slt i64 %iv.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[EXIT_MAIN_LOOP]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %num = load i64, i64* %p1, align 4, !range !0 - br label %loop - -exit: ; preds = %guarded, %loop - ret void - -loop: ; preds = %guarded, %entry - %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ] - %iv.next = add nuw nsw i64 %iv, 1 - br i1 %maybe_exit, label %range_check, label %exit - -range_check: - %div_result = udiv i64 %num, 13 - %rc = icmp slt i64 %iv.next, %div_result - br i1 %rc, label %guarded, label %exit - -guarded: - %gep = getelementptr i64, i64* %p1, i64 %iv.next - %loaded = load i64, i64* %gep, align 4 - %tmp7 = icmp slt i64 %iv.next, 1000 - br i1 %tmp7, label %loop, label %exit -} - -!0 = !{i64 0, i64 100} diff --git a/llvm/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll b/llvm/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll deleted file mode 100644 index 087b89c08e0..00000000000 --- a/llvm/test/Transforms/IRCE/bug-loop-varying-upper-limit.ll +++ /dev/null @@ -1,32 +0,0 @@ -; RUN: opt -irce-print-changed-loops -S -verify-loop-info -irce -verify < %s 2>&1 | FileCheck %s -; RUN: opt -irce-print-changed-loops -S -verify-loop-info -passes='require<branch-prob>,loop(irce)' -verify < %s 2>&1 | FileCheck %s - -; CHECK-NOT: constrained loop - -define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %len = load i32, i32* %a_len_ptr, !range !0 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/bug-mismatched-types.ll b/llvm/test/Transforms/IRCE/bug-mismatched-types.ll deleted file mode 100644 index 8172e368444..00000000000 --- a/llvm/test/Transforms/IRCE/bug-mismatched-types.ll +++ /dev/null @@ -1,67 +0,0 @@ -; RUN: opt -verify-loop-info -irce -S < %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s - -; These test cases don't check the correctness of the transform, but -; that -irce does not crash in the presence of certain things in -; the IR: - -define void @mismatched_types_1() { -; In this test case, the safe range for the only range check in the -; loop is of type [i32, i32) while the backedge taken count is of type -; i64. - -; CHECK-LABEL: @mismatched_types_1( -entry: - br label %for.body - -for.body: - %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] - %0 = trunc i64 %indvars.iv to i32 - %1 = icmp ult i32 %0, 7 - br i1 %1, label %switch.lookup, label %for.inc - -switch.lookup: - br label %for.inc - -for.inc: - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %cmp55 = icmp slt i64 %indvars.iv.next, 11 - br i1 %cmp55, label %for.body, label %for.end - -for.end: - unreachable -} - -define void @mismatched_types_2() { -; In this test case, there are two range check in the loop, one with a -; safe range of type [i32, i32) and one with a safe range of type -; [i64, i64). - -; CHECK-LABEL: @mismatched_types_2( -entry: - br label %for.body.a - -for.body.a: - %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] - %cond.a = icmp ult i64 %indvars.iv, 7 - br i1 %cond.a, label %switch.lookup.a, label %for.body.b - -switch.lookup.a: - br label %for.body.b - -for.body.b: - %truncated = trunc i64 %indvars.iv to i32 - %cond.b = icmp ult i32 %truncated, 7 - br i1 %cond.b, label %switch.lookup.b, label %for.inc - -switch.lookup.b: - br label %for.inc - -for.inc: - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %cmp55 = icmp slt i64 %indvars.iv.next, 11 - br i1 %cmp55, label %for.body.a, label %for.end - -for.end: - unreachable -} diff --git a/llvm/test/Transforms/IRCE/clamp.ll b/llvm/test/Transforms/IRCE/clamp.ll deleted file mode 100644 index 8cd05556770..00000000000 --- a/llvm/test/Transforms/IRCE/clamp.ll +++ /dev/null @@ -1,95 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; The test demonstrates that incorrect behavior of Clamp may lead to incorrect -; calculation of post-loop exit condition. - -; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in_bounds<exiting>,%not_zero<latch><exiting> -; CHECK-NOT: irce: in function test_02: constrained Loop - -define void @test_01() { - -; CHECK-LABEL: test_01 - -entry: - %indvars.iv.next467 = add nuw nsw i64 2, 1 - %length.i167 = load i32, i32 addrspace(1)* undef, align 8 - %tmp21 = zext i32 %length.i167 to i64 - %tmp34 = load atomic i32, i32 addrspace(1)* undef unordered, align 4 - %tmp35 = add i32 %tmp34, -9581 - %tmp36 = icmp ugt i32 %length.i167, 1 - br i1 %tmp36, label %preheader, label %exit - -exit: ; preds = %in_bounds, %loop, %not_zero, %entry - ret void - -preheader: ; preds = %entry -; CHECK: preheader: -; CHECK-NEXT: %length_gep.i146 = getelementptr inbounds i8, i8 addrspace(1)* undef, i64 8 -; CHECK-NEXT: %length_gep_typed.i147 = bitcast i8 addrspace(1)* undef to i32 addrspace(1)* -; CHECK-NEXT: %tmp43 = icmp ult i64 %indvars.iv.next467, %tmp21 -; CHECK-NEXT: [[C0:%[^ ]+]] = icmp ugt i64 %tmp21, 1 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[C0]], i64 %tmp21, i64 1 -; CHECK-NEXT: [[C1:%[^ ]+]] = icmp ult i64 1, %exit.mainloop.at -; CHECK-NEXT: br i1 [[C1]], label %loop.preheader, label %main.pseudo.exit - - %length_gep.i146 = getelementptr inbounds i8, i8 addrspace(1)* undef, i64 8 - %length_gep_typed.i147 = bitcast i8 addrspace(1)* undef to i32 addrspace(1)* - %tmp43 = icmp ult i64 %indvars.iv.next467, %tmp21 - br label %loop - -not_zero: ; preds = %in_bounds -; CHECK: not_zero: -; CHECK: %tmp56 = icmp ult i64 %indvars.iv.next, %tmp21 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i64 %indvars.iv.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop, label %main.exit.selector - - %tmp51 = trunc i64 %indvars.iv.next to i32 - %tmp53 = mul i32 %tmp51, %tmp51 - %tmp54 = add i32 %tmp53, -9582 - %tmp55 = add i32 %tmp54, %tmp62 - %tmp56 = icmp ult i64 %indvars.iv.next, %tmp21 - br i1 %tmp56, label %loop, label %exit - -loop: ; preds = %not_zero, %preheader - %tmp62 = phi i32 [ 1, %preheader ], [ %tmp55, %not_zero ] - %indvars.iv750 = phi i64 [ 1, %preheader ], [ %indvars.iv.next, %not_zero ] - %length.i148 = load i32, i32 addrspace(1)* %length_gep_typed.i147, align 8 - %tmp68 = zext i32 %length.i148 to i64 - %tmp97 = icmp ult i64 2, %tmp68 - %or.cond = and i1 %tmp43, %tmp97 - %tmp99 = icmp ult i64 %indvars.iv750, %tmp21 - %or.cond1 = and i1 %or.cond, %tmp99 - br i1 %or.cond1, label %in_bounds, label %exit - -in_bounds: ; preds = %loop - %indvars.iv.next = add nuw nsw i64 %indvars.iv750, 3 - %tmp107 = icmp ult i64 %indvars.iv.next, 2 - br i1 %tmp107, label %not_zero, label %exit -} - -define void @test_02() { - -; Now IRCE is smart enough to understand that the safe range here is empty. -; Previously it executed the entire loop in safe preloop and never actually -; entered the main loop. - -entry: - br label %loop - -loop: ; preds = %in_bounds, %entry - %iv1 = phi i64 [ 3, %entry ], [ %iv1.next, %in_bounds ] - %iv2 = phi i64 [ 4294967295, %entry ], [ %iv2.next, %in_bounds ] - %iv2.offset = add i64 %iv2, 1 - %rc = icmp ult i64 %iv2.offset, 400 - br i1 %rc, label %in_bounds, label %bci_321 - -bci_321: ; preds = %in_bounds, %loop - ret void - -in_bounds: ; preds = %loop - %iv1.next = add nuw nsw i64 %iv1, 2 - %iv2.next = add nuw nsw i64 %iv2, 2 - %cond = icmp ugt i64 %iv1, 204 - br i1 %cond, label %bci_321, label %loop -} diff --git a/llvm/test/Transforms/IRCE/conjunctive-checks.ll b/llvm/test/Transforms/IRCE/conjunctive-checks.ll deleted file mode 100644 index 60a0af83174..00000000000 --- a/llvm/test/Transforms/IRCE/conjunctive-checks.ll +++ /dev/null @@ -1,110 +0,0 @@ -; RUN: opt -S -verify-loop-info -irce < %s | FileCheck %s -; RUN: opt -S -verify-loop-info -passes='require<branch-prob>,loop(irce)' < %s | FileCheck %s - -define void @f_0(i32 *%arr, i32 *%a_len_ptr, i32 %n, i1* %cond_buf) { -; CHECK-LABEL: @f_0( - -; CHECK: loop.preheader: -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len -; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_n]], [[not_safe_range_end]] -; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_n]], i32 [[not_safe_range_end]] -; CHECK: [[exit_main_loop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_main_loop_at_hiclamp]] -; CHECK: [[exit_main_loop_at_loclamp_cmp:[^ ]+]] = icmp sgt i32 [[exit_main_loop_at_hiclamp]], 0 -; CHECK: [[exit_main_loop_at_loclamp:[^ ]+]] = select i1 [[exit_main_loop_at_loclamp_cmp]], i32 [[exit_main_loop_at_hiclamp]], i32 0 -; CHECK: [[enter_main_loop:[^ ]+]] = icmp slt i32 0, [[exit_main_loop_at_loclamp]] -; CHECK: br i1 [[enter_main_loop]], label %loop.preheader2, label %main.pseudo.exit - -; CHECK: loop.preheader2: -; CHECK: br label %loop - - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.for.abc = add i32 %idx, 4 - %abc.actual = icmp slt i32 %idx.for.abc, %len - %cond = load volatile i1, i1* %cond_buf - %abc = and i1 %cond, %abc.actual - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - -; CHECK: loop: -; CHECK: %cond = load volatile i1, i1* %cond_buf -; CHECK: %abc = and i1 %cond, true -; CHECK: br i1 %abc, label %in.bounds, label %out.of.bounds.loopexit3, !prof !1 - -; CHECK: out.of.bounds.loopexit: -; CHECK: br label %out.of.bounds - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx.for.abc - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -define void @f_1( - i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) { -; CHECK-LABEL: @f_1( - -; CHECK: loop.preheader: -; CHECK: [[not_len_b:[^ ]+]] = sub i32 -1, %len.b -; CHECK: [[not_len_a:[^ ]+]] = sub i32 -1, %len.a -; CHECK: [[smax_not_len_cond:[^ ]+]] = icmp sgt i32 [[not_len_b]], [[not_len_a]] -; CHECK: [[smax_not_len:[^ ]+]] = select i1 [[smax_not_len_cond]], i32 [[not_len_b]], i32 [[not_len_a]] -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_upper_limit_cond_loclamp:[^ ]+]] = icmp sgt i32 [[smax_not_len]], [[not_n]] -; CHECK: [[not_upper_limit_loclamp:[^ ]+]] = select i1 [[not_upper_limit_cond_loclamp]], i32 [[smax_not_len]], i32 [[not_n]] -; CHECK: [[upper_limit_loclamp:[^ ]+]] = sub i32 -1, [[not_upper_limit_loclamp]] -; CHECK: [[upper_limit_cmp:[^ ]+]] = icmp sgt i32 [[upper_limit_loclamp]], 0 -; CHECK: [[upper_limit:[^ ]+]] = select i1 [[upper_limit_cmp]], i32 [[upper_limit_loclamp]], i32 0 - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc.a = icmp slt i32 %idx, %len.a - %abc.b = icmp slt i32 %idx, %len.b - %abc = and i1 %abc.a, %abc.b - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - -; CHECK: loop: -; CHECK: %abc = and i1 true, true -; CHECK: br i1 %abc, label %in.bounds, label %out.of.bounds.loopexit4, !prof !1 - -; CHECK: out.of.bounds.loopexit: -; CHECK-NEXT: br label %out.of.bounds - - - in.bounds: - %addr.a = getelementptr i32, i32* %arr_a, i32 %idx - store i32 0, i32* %addr.a - %addr.b = getelementptr i32, i32* %arr_b, i32 %idx - store i32 -1, i32* %addr.b - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/correct-loop-info.ll b/llvm/test/Transforms/IRCE/correct-loop-info.ll deleted file mode 100644 index 0141b37acdd..00000000000 --- a/llvm/test/Transforms/IRCE/correct-loop-info.ll +++ /dev/null @@ -1,183 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -irce < %s -S | FileCheck %s -; RUN: opt -passes='require<branch-prob>,loop(irce)' < %s -S | FileCheck %s - -; REQUIRES: asserts - -; IRCE creates the pre and post loop, and invokes the -; canonicalizing these loops to LCSSA and loop-simplfy structure. Make sure that the update to the loopinfo does not -; incorrectly change the header while canonicalizing these pre/post loops. We -; were incorrectly updating LI when the split loop is a subloop as in the case below. -source_filename = "correct-loop-info.ll" - -define void @baz() personality i32* ()* @ham { -; CHECK-LABEL: @baz( -; CHECK-NEXT: bb: -; CHECK-NEXT: br label [[OUTERHEADER:%.*]] -; CHECK: outerheader: -; CHECK-NEXT: [[TMP:%.*]] = icmp slt i32 undef, 84 -; CHECK-NEXT: br i1 [[TMP]], label [[BB2:%.*]], label [[BB16:%.*]] -; CHECK: bb2: -; CHECK-NEXT: br i1 false, label [[INNERHEADER_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] -; CHECK: innerheader.preloop.preheader: -; CHECK-NEXT: br label [[INNERHEADER_PRELOOP:%.*]] -; CHECK: mainloop: -; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[INDVAR_END:%.*]], 0 -; CHECK-NEXT: br i1 [[TMP0]], label [[INNERHEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] -; CHECK: innerheader.preheader: -; CHECK-NEXT: br label [[INNERHEADER:%.*]] -; CHECK: innerheader: -; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP6:%.*]], [[BB8:%.*]] ], [ [[TMP4_PRELOOP_COPY:%.*]], [[INNERHEADER_PREHEADER]] ] -; CHECK-NEXT: invoke void @pluto() -; CHECK-NEXT: to label [[BB5:%.*]] unwind label %outer_exiting.loopexit.split-lp.loopexit.split-lp -; CHECK: bb5: -; CHECK-NEXT: [[TMP6]] = add i32 [[TMP4]], 1 -; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 1 -; CHECK-NEXT: br i1 true, label [[BB8]], label [[EXIT3_LOOPEXIT5:%.*]] -; CHECK: bb8: -; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i32 [[TMP6]], 84 -; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP6]], 0 -; CHECK-NEXT: br i1 [[TMP1]], label [[INNERHEADER]], label [[MAIN_EXIT_SELECTOR:%.*]] -; CHECK: main.exit.selector: -; CHECK-NEXT: [[TMP6_LCSSA:%.*]] = phi i32 [ [[TMP6]], [[BB8]] ] -; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP6_LCSSA]], 84 -; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[BB13:%.*]] -; CHECK: main.pseudo.exit: -; CHECK-NEXT: [[TMP4_COPY:%.*]] = phi i32 [ [[TMP4_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END1:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[TMP6_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[POSTLOOP:%.*]] -; CHECK: outer_exiting.loopexit: -; CHECK-NEXT: [[LPAD_LOOPEXIT:%.*]] = landingpad { i8*, i32 } -; CHECK-NEXT: cleanup -; CHECK-NEXT: br label [[OUTER_EXITING:%.*]] -; CHECK: outer_exiting.loopexit.split-lp.loopexit: -; CHECK-NEXT: [[LPAD_LOOPEXIT2:%.*]] = landingpad { i8*, i32 } -; CHECK-NEXT: cleanup -; CHECK-NEXT: br label %outer_exiting.loopexit.split-lp -; CHECK: outer_exiting.loopexit.split-lp.loopexit.split-lp: -; CHECK-NEXT: %lpad.loopexit.split-lp3 = landingpad { i8*, i32 } -; CHECK-NEXT: cleanup -; CHECK-NEXT: br label %outer_exiting.loopexit.split-lp -; CHECK: outer_exiting.loopexit.split-lp: -; CHECK-NEXT: br label [[OUTER_EXITING]] -; CHECK: outer_exiting: -; CHECK-NEXT: switch i32 undef, label [[EXIT2:%.*]] [ -; CHECK-NEXT: i32 142, label [[BB14:%.*]] -; CHECK-NEXT: i32 448, label [[EXIT:%.*]] -; CHECK-NEXT: ] -; CHECK: exit3.loopexit: -; CHECK-NEXT: br label [[EXIT3:%.*]] -; CHECK: exit3.loopexit4: -; CHECK-NEXT: br label [[EXIT3]] -; CHECK: exit3.loopexit5: -; CHECK-NEXT: br label [[EXIT3]] -; CHECK: exit3: -; CHECK-NEXT: ret void -; CHECK: bb13.loopexit: -; CHECK-NEXT: br label [[BB13]] -; CHECK: bb13: -; CHECK-NEXT: unreachable -; CHECK: bb14: -; CHECK-NEXT: br label [[OUTERHEADER]] -; CHECK: exit: -; CHECK-NEXT: ret void -; CHECK: bb16: -; CHECK-NEXT: ret void -; CHECK: exit2: -; CHECK-NEXT: ret void -; CHECK: innerheader.preloop: -; CHECK-NEXT: [[TMP4_PRELOOP:%.*]] = phi i32 [ [[TMP6_PRELOOP:%.*]], [[BB8_PRELOOP:%.*]] ], [ undef, [[INNERHEADER_PRELOOP_PREHEADER]] ] -; CHECK-NEXT: invoke void @pluto() -; CHECK-NEXT: to label [[BB5_PRELOOP:%.*]] unwind label [[OUTER_EXITING_LOOPEXIT:%.*]] -; CHECK: bb5.preloop: -; CHECK-NEXT: [[TMP6_PRELOOP]] = add i32 [[TMP4_PRELOOP]], 1 -; CHECK-NEXT: [[TMP7_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 1 -; CHECK-NEXT: br i1 [[TMP7_PRELOOP]], label [[BB8_PRELOOP]], label [[EXIT3_LOOPEXIT:%.*]] -; CHECK: bb8.preloop: -; CHECK-NEXT: [[TMP9_PRELOOP:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], 84 -; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP6_PRELOOP]], -1 -; CHECK-NEXT: br i1 [[TMP3]], label [[INNERHEADER_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop !0, !irce.loop.clone !5 -; CHECK: preloop.exit.selector: -; CHECK-NEXT: [[TMP6_PRELOOP_LCSSA:%.*]] = phi i32 [ [[TMP6_PRELOOP]], [[BB8_PRELOOP]] ] -; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i32 [[TMP6_PRELOOP_LCSSA]], 84 -; CHECK-NEXT: br i1 [[TMP4]], label [[PRELOOP_PSEUDO_EXIT]], label [[BB13]] -; CHECK: preloop.pseudo.exit: -; CHECK-NEXT: [[TMP4_PRELOOP_COPY]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ undef, [[BB2]] ], [ [[TMP6_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[MAINLOOP]] -; CHECK: postloop: -; CHECK-NEXT: br label [[INNERHEADER_POSTLOOP:%.*]] -; CHECK: innerheader.postloop: -; CHECK-NEXT: [[TMP4_POSTLOOP:%.*]] = phi i32 [ [[TMP6_POSTLOOP:%.*]], [[BB8_POSTLOOP:%.*]] ], [ [[TMP4_COPY]], [[POSTLOOP]] ] -; CHECK-NEXT: invoke void @pluto() -; CHECK-NEXT: to label [[BB5_POSTLOOP:%.*]] unwind label %outer_exiting.loopexit.split-lp.loopexit -; CHECK: bb5.postloop: -; CHECK-NEXT: [[TMP6_POSTLOOP]] = add i32 [[TMP4_POSTLOOP]], 1 -; CHECK-NEXT: [[TMP7_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 1 -; CHECK-NEXT: br i1 [[TMP7_POSTLOOP]], label [[BB8_POSTLOOP]], label [[EXIT3_LOOPEXIT4:%.*]] -; CHECK: bb8.postloop: -; CHECK-NEXT: [[TMP9_POSTLOOP:%.*]] = icmp slt i32 [[TMP6_POSTLOOP]], 84 -; CHECK-NEXT: br i1 [[TMP9_POSTLOOP]], label [[INNERHEADER_POSTLOOP]], label [[BB13_LOOPEXIT:%.*]], !llvm.loop !6, !irce.loop.clone !5 -; -bb: - br label %outerheader - -outerheader: ; preds = %bb14, %bb - %tmp = icmp slt i32 undef, 84 - br i1 %tmp, label %bb2, label %bb16 - -bb2: ; preds = %outerheader - br label %innerheader - -innerheader: ; preds = %bb8, %bb2 - %tmp4 = phi i32 [ %tmp6, %bb8 ], [ undef, %bb2 ] - invoke void @pluto() - to label %bb5 unwind label %outer_exiting - -bb5: ; preds = %innerheader - %tmp6 = add i32 %tmp4, 1 - %tmp7 = icmp slt i32 %tmp6, 1 - br i1 %tmp7, label %bb8, label %exit3 - -bb8: ; preds = %bb5 - %tmp9 = icmp slt i32 %tmp6, 84 - br i1 %tmp9, label %innerheader, label %bb13 - -outer_exiting: ; preds = %innerheader - %tmp11 = landingpad { i8*, i32 } - cleanup - switch i32 undef, label %exit2 [ - i32 142, label %bb14 - i32 448, label %exit - ] - -exit3: ; preds = %bb5 - ret void - -bb13: ; preds = %bb8 - unreachable - -bb14: ; preds = %outer_exiting - br label %outerheader - -exit: ; preds = %outer_exiting - ret void - -bb16: ; preds = %outerheader - ret void - -exit2: ; preds = %outer_exiting - ret void -} - -declare i32* @ham() - -declare void @pluto() - -!0 = distinct !{!0, !1, !2, !3, !4} -!1 = !{!"llvm.loop.unroll.disable"} -!2 = !{!"llvm.loop.vectorize.enable", i1 false} -!3 = !{!"llvm.loop.licm_versioning.disable"} -!4 = !{!"llvm.loop.distribute.enable", i1 false} -!5 = !{} -!6 = distinct !{!6, !1, !2, !3, !4} diff --git a/llvm/test/Transforms/IRCE/decrementing-loop.ll b/llvm/test/Transforms/IRCE/decrementing-loop.ll deleted file mode 100644 index 4c82cd3e341..00000000000 --- a/llvm/test/Transforms/IRCE/decrementing-loop.ll +++ /dev/null @@ -1,266 +0,0 @@ -; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s | FileCheck %s - -define void @decrementing_loop(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - %start = sub i32 %n, 1 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %start, %entry ] , [ %idx.dec, %in.bounds ] - %idx.dec = sub i32 %idx, 1 - %abc.high = icmp slt i32 %idx, %len - %abc.low = icmp sge i32 %idx, 0 - %abc = and i1 %abc.low, %abc.high - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp sgt i32 %idx.dec, -1 - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void - -; CHECK: loop.preheader: -; CHECK: [[not_len:[^ ]+]] = sub i32 -1, %len -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_len_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_len]], [[not_n]] -; CHECK: [[not_len_hiclamp:[^ ]+]] = select i1 [[not_len_hiclamp_cmp]], i32 [[not_len]], i32 [[not_n]] -; CHECK: [[len_hiclamp:[^ ]+]] = sub i32 -1, [[not_len_hiclamp]] -; CHECK: [[not_exit_preloop_at_cmp:[^ ]+]] = icmp sgt i32 [[len_hiclamp]], 0 -; CHECK: [[not_exit_preloop_at:[^ ]+]] = select i1 [[not_exit_preloop_at_cmp]], i32 [[len_hiclamp]], i32 0 -; CHECK: %exit.preloop.at = add i32 [[not_exit_preloop_at]], -1 -} - -; Make sure that we can eliminate the range check when the loop looks like: -; for (i = len.a - 1; i >= 0; --i) -; b[i] = a[i]; -define void @test_01(i32* %a, i32* %b, i32* %a_len_ptr, i32* %b_len_ptr) { - -; CHECK-LABEL: test_01 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: %rc = and i1 true, true -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp ne i32 %len.a, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %len.a, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rca = icmp ult i32 %idx.next, %len.a - %rcb = icmp ult i32 %idx.next, %len.b - %rc = and i1 %rca, %rcb - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %el.b = getelementptr i32, i32* %b, i32 %idx.next - %v = load i32, i32* %el.a - store i32 %v, i32* %el.b - %loop.cond = icmp slt i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_01, but the latch condition is unsigned -define void @test_02(i32* %a, i32* %b, i32* %a_len_ptr, i32* %b_len_ptr) { - -; CHECK-LABEL: test_02 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: %rc = and i1 true, true -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp ne i32 %len.a, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %len.a, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rca = icmp ult i32 %idx.next, %len.a - %rcb = icmp ult i32 %idx.next, %len.b - %rc = and i1 %rca, %rcb - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %el.b = getelementptr i32, i32* %b, i32 %idx.next - %v = load i32, i32* %el.a - store i32 %v, i32* %el.b - %loop.cond = icmp ult i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - - out.of.bounds: - ret void - - exit: - ret void -} - -; Check that we can figure out that IV is non-negative via implication through -; Phi node. -define void @test_03(i32* %a, i32* %a_len_ptr, i1 %cond) { - -; CHECK-LABEL: test_03 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.minus.one = sub nsw i32 %len.a, 1 - %len.minus.two = sub nsw i32 %len.a, 2 - br i1 %cond, label %if.true, label %if.false - -if.true: - br label %merge - -if.false: - br label %merge - -merge: - %starting.value = phi i32 [ %len.minus.two, %if.true ], [ %len.minus.one, %if.false ] - %first.itr.check = icmp sgt i32 %len.a, 3 - br i1 %first.itr.check, label %loop, label %exit - -loop: - %idx = phi i32 [ %starting.value, %merge ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rc = icmp ult i32 %idx.next, %len.a - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - -in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %v = load i32, i32* %el.a - %loop.cond = icmp slt i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check that we can figure out that IV is non-negative via implication through -; two Phi nodes. -define void @test_04(i32* %a, i32* %a_len_ptr, i1 %cond) { - -; CHECK-LABEL: test_04 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.minus.one = sub nsw i32 %len.a, 1 - %len.plus.one = add nsw i32 %len.a, 1 - %len.minus.two = sub nsw i32 %len.a, 2 - br i1 %cond, label %if.true, label %if.false - -if.true: - br label %merge - -if.false: - br label %merge - -merge: - %starting.value = phi i32 [ %len.minus.two, %if.true ], [ %len.minus.one, %if.false ] - %len.phi = phi i32 [ %len.a, %if.true ], [ %len.plus.one, %if.false ] - %first.itr.check = icmp sgt i32 %len.a, 3 - br i1 %first.itr.check, label %loop, label %exit - -loop: - %idx = phi i32 [ %starting.value, %merge ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rc = icmp ult i32 %idx.next, %len.phi - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - -in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %v = load i32, i32* %el.a - %loop.cond = icmp slt i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check that we can figure out that IV is non-negative via implication through -; two Phi nodes, one being AddRec. -define void @test_05(i32* %a, i32* %a_len_ptr, i1 %cond) { - -; CHECK-LABEL: test_05 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds -; CHECK: loop.preloop: - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.minus.one = sub nsw i32 %len.a, 1 - %len.plus.one = add nsw i32 %len.a, 1 - %len.minus.two = sub nsw i32 %len.a, 2 - br label %merge - -merge: - %starting.value = phi i32 [ %len.minus.two, %entry ], [ %len.minus.one, %merge ] - %len.phi = phi i32 [ %len.a, %entry ], [ %len.phi.next, %merge ] - %len.phi.next = add nsw i32 %len.phi, 1 - br i1 true, label %first.iter.check, label %merge - -first.iter.check: - %first.itr.check = icmp sgt i32 %len.a, 3 - br i1 %first.itr.check, label %loop, label %exit - -loop: - %idx = phi i32 [ %starting.value, %first.iter.check ] , [ %idx.next, %in.bounds ] - %idx.next = sub i32 %idx, 1 - %rc = icmp ult i32 %idx.next, %len.phi - br i1 %rc, label %in.bounds, label %out.of.bounds, !prof !1 - -in.bounds: - %el.a = getelementptr i32, i32* %a, i32 %idx.next - %v = load i32, i32* %el.a - %loop.cond = icmp slt i32 %idx, 2 - br i1 %loop.cond, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/empty_ranges.ll b/llvm/test/Transforms/IRCE/empty_ranges.ll deleted file mode 100644 index 362ab8f85d1..00000000000 --- a/llvm/test/Transforms/IRCE/empty_ranges.ll +++ /dev/null @@ -1,69 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S - -; Make sure that IRCE doesn't apply in case of empty ranges. -; (i + 30 < 40) if i in [-30, 10). -; Intersected with iteration space, it is [0, 10). -; (i - 60 < 40) if i in [60 , 100). -; The intersection with safe iteration space is the empty range [60, 10). -; It is better to eliminate one range check than attempt to eliminate both given -; that we will never go to the main loop in the latter case and basically -; only duplicate code with no benefits. - -define void @test_01(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_01( -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: br i1 true, label %loop.preheader, label %main.pseudo.exit -; CHECK: in.bounds.1: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %off1 = add i32 %idx, 30 -; CHECK-NEXT: %c2 = icmp slt i32 %off1, 40 -; CHECK-NEXT: br i1 true, label %in.bounds.2, label %exit.loopexit2 -; CHECK: in.bounds.2: -; CHECK-NEXT: %off2 = add i32 %idx, -60 -; CHECK-NEXT: %c3 = icmp slt i32 %off2, 40 -; CHECK-NEXT: br i1 %c3, label %in.bounds.3, label %exit.loopexit2 -; CHECK: in.bounds.3: -; CHECK-NEXT: %next = icmp ult i32 %idx.next, 100 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ult i32 %idx.next, 10 -; CHECK-NEXT: br i1 [[COND1]], label %loop, label %main.exit.selector -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds.3 ] -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ult i32 %idx.next.lcssa, 100 -; CHECK-NEXT: br i1 [[COND2]], label %main.pseudo.exit, label %exit -; CHECK: postloop: - -entry: - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds.3 ] - %idx.next = add nsw nuw i32 %idx, 1 - %c1 = icmp slt i32 %idx, 20 - br i1 %c1, label %in.bounds.1, label %out.of.bounds - -in.bounds.1: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %off1 = add i32 %idx, 30 - %c2 = icmp slt i32 %off1, 40 - br i1 %c2, label %in.bounds.2, label %exit - -in.bounds.2: - %off2 = add i32 %idx, -60 - %c3 = icmp slt i32 %off2, 40 - br i1 %c3, label %in.bounds.3, label %exit - -in.bounds.3: - %next = icmp ult i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} diff --git a/llvm/test/Transforms/IRCE/eq_ne.ll b/llvm/test/Transforms/IRCE/eq_ne.ll deleted file mode 100644 index 290c1cb823e..00000000000 --- a/llvm/test/Transforms/IRCE/eq_ne.ll +++ /dev/null @@ -1,288 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_01u: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -; Show that IRCE can turn 'ne' condition to 'slt' in increasing IV when the IV -; can be negative at some point. -define void @test_01(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_01 -; CHECK: main.exit.selector: -; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 100 -; CHECK-NEXT: br i1 [[COND]] - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ -3, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ne i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE can turn 'ne' condition to 'ult' in increasing IV when IV is -; non-negative. -define void @test_01u(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_01u -; CHECK: main.exit.selector: -; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 100 -; CHECK-NEXT: br i1 [[COND]] - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ne i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that if n is not known to be greater than the starting value, IRCE -; doesn't apply. -define void @test_02(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_02( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ne i32 %idx.next, -100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE can turn 'eq' condition to 'sge' in increasing IV. -define void @test_03(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_03( -; CHECK: main.exit.selector: -; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 100 -; CHECK-NEXT: br i1 [[COND]] - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp eq i32 %idx.next, 100 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -define void @test_04(i32* %arr, i32* %a_len_ptr) #0 { - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp eq i32 %idx.next, -100 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE can turn 'ne' condition to 'sgt' in decreasing IV. -define void @test_05(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_05( -; CHECK: preloop.exit.selector: -; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ] -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0 -; CHECK-NEXT: br i1 [[COND]] - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ne i32 %idx.next, 0 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE cannot turn 'ne' condition to 'sgt' in decreasing IV if the end -; value is not proved to be less than the start value. -define void @test_06(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_06( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ne i32 %idx.next, 120 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE can turn 'eq' condition to 'slt' in decreasing IV. -define void @test_07(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_07( -; CHECK: preloop.exit.selector: -; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ] -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0 -; CHECK-NEXT: br i1 [[COND]] - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp eq i32 %idx.next, 0 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Show that IRCE cannot turn 'eq' condition to 'slt' in decreasing IV if the end -; value is not proved to be less than the start value. -define void @test_08(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_08( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp eq i32 %idx.next, 120 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 50} diff --git a/llvm/test/Transforms/IRCE/low-becount.ll b/llvm/test/Transforms/IRCE/low-becount.ll deleted file mode 100644 index 39f21230e26..00000000000 --- a/llvm/test/Transforms/IRCE/low-becount.ll +++ /dev/null @@ -1,35 +0,0 @@ -; RUN: opt -irce-print-changed-loops -verify-loop-info -irce -S < %s 2>&1 | FileCheck %s -; -; TODO: new-pm version should be enabled after we decide on branch-probability handling for loop passes -; TODO: opt -irce-print-changed-loops -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK-NOT: constrained Loop - -define void @low_profiled_be_count(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit, !prof !2 - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} -!2 = !{!"branch_weights", i32 4, i32 64} diff --git a/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll b/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll deleted file mode 100644 index 000d1ab36f2..00000000000 --- a/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll +++ /dev/null @@ -1,67 +0,0 @@ -; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s | FileCheck %s - -define void @multiple_access_no_preloop( - i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) { - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds.b ] - %idx.next = add i32 %idx, 1 - %abc.a = icmp slt i32 %idx, %len.a - br i1 %abc.a, label %in.bounds.a, label %out.of.bounds, !prof !1 - - in.bounds.a: - %addr.a = getelementptr i32, i32* %arr_a, i32 %idx - store i32 0, i32* %addr.a - %abc.b = icmp slt i32 %idx, %len.b - br i1 %abc.b, label %in.bounds.b, label %out.of.bounds, !prof !1 - - in.bounds.b: - %addr.b = getelementptr i32, i32* %arr_b, i32 %idx - store i32 -1, i32* %addr.b - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @multiple_access_no_preloop( - -; CHECK: loop.preheader: -; CHECK: [[not_len_b:[^ ]+]] = sub i32 -1, %len.b -; CHECK: [[not_len_a:[^ ]+]] = sub i32 -1, %len.a -; CHECK: [[smax_not_len_cond:[^ ]+]] = icmp sgt i32 [[not_len_b]], [[not_len_a]] -; CHECK: [[smax_not_len:[^ ]+]] = select i1 [[smax_not_len_cond]], i32 [[not_len_b]], i32 [[not_len_a]] -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_upper_limit_cond_loclamp:[^ ]+]] = icmp sgt i32 [[smax_not_len]], [[not_n]] -; CHECK: [[not_upper_limit_loclamp:[^ ]+]] = select i1 [[not_upper_limit_cond_loclamp]], i32 [[smax_not_len]], i32 [[not_n]] -; CHECK: [[upper_limit_loclamp:[^ ]+]] = sub i32 -1, [[not_upper_limit_loclamp]] -; CHECK: [[upper_limit_cmp:[^ ]+]] = icmp sgt i32 [[upper_limit_loclamp]], 0 -; CHECK: [[upper_limit:[^ ]+]] = select i1 [[upper_limit_cmp]], i32 [[upper_limit_loclamp]], i32 0 - -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds.a, label %out.of.bounds - -; CHECK: in.bounds.a: -; CHECK: br i1 true, label %in.bounds.b, label %out.of.bounds - -; CHECK: in.bounds.b: -; CHECK: [[main_loop_cond:[^ ]+]] = icmp slt i32 %idx.next, [[upper_limit]] -; CHECK: br i1 [[main_loop_cond]], label %loop, label %main.exit.selector - -; CHECK: in.bounds.b.postloop: -; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n -; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/non_known_positive_end.ll b/llvm/test/Transforms/IRCE/non_known_positive_end.ll deleted file mode 100644 index 135e4461f1a..00000000000 --- a/llvm/test/Transforms/IRCE/non_known_positive_end.ll +++ /dev/null @@ -1,139 +0,0 @@ -; RUN: opt -verify-loop-info -irce -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s - -; Make sure that we can pick up both range checks. -define void @test_01(i32 *%arr, i32* %a_len_ptr, i32* %size_ptr) { - -; CHECK-LABEL: @test_01( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %size = load i32, i32* %size_ptr - %first_iter_check = icmp sle i32 %size, 0 - br i1 %first_iter_check, label %exit, label %loop - -loop: - %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp slt i32 %iv, %len - %rc2 = icmp slt i32 %iv, %size - ; CHECK: %rc = and i1 true, true - %rc = and i1 %rc1, %rc2 - br i1 %rc, label %backedge, label %out_of_bounds - - -backedge: - %iv.next = add i32 %iv, 1 - %arr_el_ptr = getelementptr i32, i32* %arr, i32 %iv - %el = load i32, i32* %arr_el_ptr - %loopcond = icmp ne i32 %iv, %size - br i1 %loopcond, label %loop, label %exit - -exit: - ret void - -out_of_bounds: - ret void -} - -; Same as test_01, unsigned predicates. -define void @test_02(i32 *%arr, i32* %a_len_ptr, i32* %size_ptr) { - -; CHECK-LABEL: @test_02( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %size = load i32, i32* %size_ptr - %first_iter_check = icmp sle i32 %size, 0 - br i1 %first_iter_check, label %exit, label %loop - -loop: - %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp ult i32 %iv, %len - %rc2 = icmp ult i32 %iv, %size - ; CHECK: %rc = and i1 true, true - %rc = and i1 %rc1, %rc2 - br i1 %rc, label %backedge, label %out_of_bounds - - -backedge: - %iv.next = add i32 %iv, 1 - %arr_el_ptr = getelementptr i32, i32* %arr, i32 %iv - %el = load i32, i32* %arr_el_ptr - %loopcond = icmp ne i32 %iv, %size - br i1 %loopcond, label %loop, label %exit - -exit: - ret void - -out_of_bounds: - ret void -} - -define void @test_03(i32 *%arr, i32* %a_len_ptr, i32* %size_ptr) { - -; CHECK-LABEL: @test_03( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %size = load i32, i32* %size_ptr - %first_iter_check = icmp eq i32 %size, 0 - br i1 %first_iter_check, label %exit, label %loop - -loop: - %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp slt i32 %iv, %len - %rc2 = icmp slt i32 %iv, %size - ; CHECK: %rc = and i1 true, true - %rc = and i1 %rc1, %rc2 - br i1 %rc, label %backedge, label %out_of_bounds - - -backedge: - %iv.next = add i32 %iv, 1 - %arr_el_ptr = getelementptr i32, i32* %arr, i32 %iv - %el = load i32, i32* %arr_el_ptr - %loopcond = icmp ne i32 %iv, %len - br i1 %loopcond, label %loop, label %exit - -exit: - ret void - -out_of_bounds: - ret void -} - -define void @test_04(i32 *%arr, i32* %a_len_ptr, i32* %size_ptr) { - -; CHECK-LABEL: @test_04( - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %size = load i32, i32* %size_ptr - %first_iter_check = icmp eq i32 %size, 0 - br i1 %first_iter_check, label %exit, label %loop - -loop: - %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp ult i32 %iv, %len - %rc2 = icmp ult i32 %iv, %size - ; CHECK: %rc = and i1 true, true - %rc = and i1 %rc1, %rc2 - br i1 %rc, label %backedge, label %out_of_bounds - - -backedge: - %iv.next = add i32 %iv, 1 - %arr_el_ptr = getelementptr i32, i32* %arr, i32 %iv - %el = load i32, i32* %arr_el_ptr - %loopcond = icmp ne i32 %iv, %len - br i1 %loopcond, label %loop, label %exit - -exit: - ret void - -out_of_bounds: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/not-likely-taken.ll b/llvm/test/Transforms/IRCE/not-likely-taken.ll deleted file mode 100644 index 3b28ae14f9f..00000000000 --- a/llvm/test/Transforms/IRCE/not-likely-taken.ll +++ /dev/null @@ -1,43 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s -; -; TODO: new-pm version should be enabled after we decide on branch-probability handling for loop passes -; TODO: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' < %s 2>&1 | FileCheck %s - -; CHECK-NOT: constrained Loop - -define void @multiple_access_no_preloop( - i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) { - - entry: - %len.a = load i32, i32* %a_len_ptr, !range !0 - %len.b = load i32, i32* %b_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds.b ] - %idx.next = add i32 %idx, 1 - %abc.a = icmp slt i32 %idx, %len.a - br i1 %abc.a, label %in.bounds.a, label %out.of.bounds, !prof !1 - - in.bounds.a: - %addr.a = getelementptr i32, i32* %arr_a, i32 %idx - store i32 0, i32* %addr.a - %abc.b = icmp slt i32 %idx, %len.b - br i1 %abc.b, label %in.bounds.b, label %out.of.bounds, !prof !1 - - in.bounds.b: - %addr.b = getelementptr i32, i32* %arr_b, i32 %idx - store i32 -1, i32* %addr.b - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 1, i32 1} diff --git a/llvm/test/Transforms/IRCE/only-lower-check.ll b/llvm/test/Transforms/IRCE/only-lower-check.ll deleted file mode 100644 index ad379fb20ac..00000000000 --- a/llvm/test/Transforms/IRCE/only-lower-check.ll +++ /dev/null @@ -1,37 +0,0 @@ -; RUN: opt -irce-print-range-checks -irce-print-changed-loops -verify-loop-info -irce < %s 2>&1 | FileCheck %s -; RUN: opt -irce-print-range-checks -irce-print-changed-loops -verify-loop-info -passes='require<branch-prob>,loop(irce)' < %s 2>&1 | FileCheck %s - -; CHECK: irce: loop has 1 inductive range checks: -; CHECK-NEXT: InductiveRangeCheck: -; CHECK-NEXT: Begin: (-1 + %n) Step: -1 End: 2147483647 -; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 Operand: 0 -; CHECK-NEXT: irce: in function only_lower_check: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -define void @only_lower_check(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - %start = sub i32 %n, 1 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ %start, %entry ] , [ %idx.dec, %in.bounds ] - %idx.dec = sub i32 %idx, 1 - %abc = icmp sge i32 %idx, 0 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp sgt i32 %idx.dec, -1 - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/only-upper-check.ll b/llvm/test/Transforms/IRCE/only-upper-check.ll deleted file mode 100644 index 45a911b5bfd..00000000000 --- a/llvm/test/Transforms/IRCE/only-upper-check.ll +++ /dev/null @@ -1,37 +0,0 @@ -; RUN: opt -verify-loop-info -irce -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s - -; CHECK: irce: loop has 1 inductive range checks: -; CHECK-NEXT:InductiveRangeCheck: -; CHECK-NEXT: Begin: %offset Step: 1 End: %len -; CHECK-NEXT: CheckUse: br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 Operand: 0 -; CHECK-NEXT: irce: in function incrementing: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -define void @incrementing(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32 %offset) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %array.idx = add i32 %idx, %offset - %abc = icmp slt i32 %array.idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %array.idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/optimistic_scev.ll b/llvm/test/Transforms/IRCE/optimistic_scev.ll deleted file mode 100644 index 5bb6019f4ec..00000000000 --- a/llvm/test/Transforms/IRCE/optimistic_scev.ll +++ /dev/null @@ -1,42 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s - -; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 2 containing: - -define void @test_01(i64 %len) { - -; CHECK-LABEL: @test_01( - -entry: - br label %loop - -check: - %entry_check = icmp eq i32 %idx.next, 0 - br i1 %entry_check, label %exit, label %loop - -loop: - %idx = phi i32 [ 1, %entry ], [ %idx.next, %check ] - %idx_ext = sext i32 %idx to i64 - br label %inner_loop - -inner_loop: - %iv = phi i64 [ 0, %loop ], [ %iv.next, %inner_backedge ] - %iv.next = add nuw nsw i64 %iv, 1 - %inner_check = icmp slt i64 %iv.next, %idx_ext - br i1 %inner_check, label %inner, label %outer_check - -inner: - %iv_next_check = icmp slt i64 %iv.next, 100 - br i1 %iv_next_check, label %inner_backedge, label %exit - -inner_backedge: - %cond = icmp eq i64 %iv.next, 100 - br i1 %cond, label %exit, label %inner_loop - -outer_check: - %idx.next = add i32 %idx, 1 - %loopdone = icmp slt i32 %idx.next, 2 - br i1 %loopdone, label %check, label %exit - -exit: - ret void -} diff --git a/llvm/test/Transforms/IRCE/pre_post_loops.ll b/llvm/test/Transforms/IRCE/pre_post_loops.ll deleted file mode 100644 index 8e41d428742..00000000000 --- a/llvm/test/Transforms/IRCE/pre_post_loops.ll +++ /dev/null @@ -1,118 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -; Iterate from 0 to SINT_MAX, check that the post-loop is generated. -define void @test_01(i32* %arr, i32* %a_len_ptr) { - -; CHECK: test_01( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add i32 %idx, 1 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp slt i32 %idx.next, 2147483647 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp slt i32 %idx.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, 2147483647 -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 2147483647 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Iterate from SINT_MAX to 0, check that the pre-loop is generated. -define void @test_02(i32* %arr, i32* %a_len_ptr) { - -; CHECK: test_02( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECH-NEXT: br i1 true, label %loop.preloop.preheader -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -1 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp sgt i32 %idx.next, -1 -; CHECK-NEXT: br i1 %next, label %loop, label %exit.loopexit -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 2147483647, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp slt i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp sgt i32 %idx.next.preloop, -1 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 %idx.next.preloop, -1 -; CHECK-NEXT: br i1 [[COND]], label %loop.preloop, label %preloop.exit.selector - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 2147483647, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp sgt i32 %idx.next, -1 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 50} diff --git a/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll b/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll deleted file mode 100644 index 489f34f70ac..00000000000 --- a/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll +++ /dev/null @@ -1,287 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing: -; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing: -; CHECK-LABEL: irce: in function test_03: constrained Loop at depth 1 containing: -; CHECK-LABEL: irce: in function test_04: constrained Loop at depth 1 containing: -; CHECK-LABEL: irce: in function test_05: constrained Loop at depth 1 containing: - -; This test used to demonstrate a miscompile: the outer loop's IV iterates in -; range of [2, 400) and the range check is done against value 331. Due to a bug -; in range intersection IRCE manages to eliminate the range check without -; inserting a postloop, which is incorrect. We treat the range of this test as -; an unsigned range and are able to intersect ranges correctly and insert a -; postloop. - -define void @test_01() { - -; CHECK-LABEL: test_01 -; CHECK-NOT: preloop -; CHECK: range_check_block: ; preds = %inner_loop -; CHECK-NEXT: %range_check = icmp slt i32 %iv, 331 -; CHECK-NEXT: br i1 true, label %loop_latch -; CHECK: loop_latch: -; CHECK-NEXT: %iv_next = add i32 %iv, 1 -; CHECK-NEXT: %loop_cond = icmp ult i32 %iv_next, 400 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 %iv_next, 331 -; CHECK-NEXT: br i1 [[COND]], label %loop_header, label %main.exit.selector -; CHECK: main.exit.selector: ; preds = %loop_latch -; CHECK-NEXT: %iv_next.lcssa = phi i32 [ %iv_next, %loop_latch ] -; CHECK-NEXT: %iv.lcssa = phi i32 [ %iv, %loop_latch ] -; CHECK-NEXT: [[MES_COND:%[^ ]+]] = icmp ult i32 %iv_next.lcssa, 400 -; CHECK-NEXT: br i1 [[MES_COND]], label %main.pseudo.exit, label %exit -; CHECK: loop_latch.postloop: ; preds = %range_check_block.postloop -; CHECK-NEXT: %iv_next.postloop = add i32 %iv.postloop, 1 -; CHECK-NEXT: %loop_cond.postloop = icmp ult i32 %iv_next.postloop, 400 -; CHECK-NEXT: br i1 %loop_cond.postloop, label %loop_header.postloop, label %exit.loopexit - -entry: - br label %loop_header - -loop_header: ; preds = %loop_latch, %entry - %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ] - %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ] - %tmp2 = icmp sgt i32 %iv.prev, -1 - br i1 %tmp2, label %loop_header.split.us, label %exit - -loop_header.split.us: ; preds = %loop_header - br label %inner_loop - -inner_loop: ; preds = %inner_loop, %loop_header.split.us - %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] - %inner_iv_next = add nuw nsw i32 %inner_iv, 1 - %inner_cond = icmp ult i32 %inner_iv_next, 31 - br i1 %inner_cond, label %inner_loop, label %range_check_block - -exit: ; preds = %loop_latch, %loop_header - ret void - -range_check_block: ; preds = %inner_loop - %range_check = icmp slt i32 %iv, 331 - br i1 %range_check, label %loop_latch, label %deopt - -loop_latch: ; preds = %range_check_block - %iv_next = add i32 %iv, 1 - %loop_cond = icmp ult i32 %iv_next, 400 - br i1 %loop_cond, label %loop_header, label %exit - -deopt: ; preds = %range_check_block - ret void -} - -; Similar to test_01, but here the range check is done against 450. No postloop -; is required. - -define void @test_02() { - -; CHECK-LABEL: test_02 -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK: range_check_block: ; preds = %inner_loop -; CHECK-NEXT: %range_check = icmp slt i32 %iv, 450 -; CHECK-NEXT: br i1 true, label %loop_latch -; CHECK: loop_latch: ; preds = %range_check_block -; CHECK-NEXT: %iv_next = add i32 %iv, 1 -; CHECK-NEXT: %loop_cond = icmp ult i32 %iv_next, 400 -; CHECK-NEXT: br i1 %loop_cond, label %loop_header, label %exit - -entry: - br label %loop_header - -loop_header: ; preds = %loop_latch, %entry - %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ] - %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ] - %tmp2 = icmp sgt i32 %iv.prev, -1 - br i1 %tmp2, label %loop_header.split.us, label %exit - -loop_header.split.us: ; preds = %loop_header - br label %inner_loop - -inner_loop: ; preds = %inner_loop, %loop_header.split.us - %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] - %inner_iv_next = add nuw nsw i32 %inner_iv, 1 - %inner_cond = icmp ult i32 %inner_iv_next, 31 - br i1 %inner_cond, label %inner_loop, label %range_check_block - -exit: ; preds = %loop_latch, %loop_header - ret void - -range_check_block: ; preds = %inner_loop - %range_check = icmp slt i32 %iv, 450 - br i1 %range_check, label %loop_latch, label %deopt - -loop_latch: ; preds = %range_check_block - %iv_next = add i32 %iv, 1 - %loop_cond = icmp ult i32 %iv_next, 400 - br i1 %loop_cond, label %loop_header, label %exit - -deopt: ; preds = %range_check_block - ret void -} - -; Range check is made against 0, so the safe iteration range is empty. IRCE -; should not apply to the inner loop. The condition %tmp2 can be eliminated. - -define void @test_03() { - -; CHECK-LABEL: test_03 -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK: %tmp2 = icmp sgt i32 %iv.prev, -1 -; CHECK-NEXT: br i1 true, label %loop_header.split.us, label %exit -; CHECK: range_check_block: -; CHECK-NEXT: %range_check = icmp slt i32 %iv, 0 -; CHECK-NEXT: br i1 %range_check, label %loop_latch, label %deopt - -entry: - br label %loop_header - -loop_header: ; preds = %loop_latch, %entry - %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ] - %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ] - %tmp2 = icmp sgt i32 %iv.prev, -1 - br i1 %tmp2, label %loop_header.split.us, label %exit - -loop_header.split.us: ; preds = %loop_header - br label %inner_loop - -inner_loop: ; preds = %inner_loop, %loop_header.split.us - %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] - %inner_iv_next = add nuw nsw i32 %inner_iv, 1 - %inner_cond = icmp ult i32 %inner_iv_next, 31 - br i1 %inner_cond, label %inner_loop, label %range_check_block - -exit: ; preds = %loop_latch, %loop_header - ret void - -range_check_block: ; preds = %inner_loop - %range_check = icmp slt i32 %iv, 0 - br i1 %range_check, label %loop_latch, label %deopt - -loop_latch: ; preds = %range_check_block - %iv_next = add i32 %iv, 1 - %loop_cond = icmp ult i32 %iv_next, 400 - br i1 %loop_cond, label %loop_header, label %exit - -deopt: ; preds = %range_check_block - ret void -} - -; We can also properly eliminate range check against %n which is not always -; known positive. - -define void @test_04(i32* %p) { - -; CHECK-LABEL: test_04 -; CHECK: entry -; CHECK-NOT: preloop -; CHECK: %tmp2 = icmp sgt i32 %iv.prev, -1 -; CHECK-NEXT: br i1 true, label %loop_header.split.us, label %exit -; CHECK: range_check_block: -; CHECK-NEXT: %range_check = icmp slt i32 %iv, %n -; CHECK-NEXT: br i1 true, label %loop_latch, label %deopt -; CHECK: postloop: - -entry: - %n = load i32, i32* %p - br label %loop_header - -loop_header: ; preds = %loop_latch, %entry - %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ] - %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ] - %tmp2 = icmp sgt i32 %iv.prev, -1 - br i1 %tmp2, label %loop_header.split.us, label %exit - -loop_header.split.us: ; preds = %loop_header - br label %inner_loop - -inner_loop: ; preds = %inner_loop, %loop_header.split.us - %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] - %inner_iv_next = add nuw nsw i32 %inner_iv, 1 - %inner_cond = icmp ult i32 %inner_iv_next, 31 - br i1 %inner_cond, label %inner_loop, label %range_check_block - -exit: ; preds = %loop_latch, %loop_header - ret void - -range_check_block: ; preds = %inner_loop - %range_check = icmp slt i32 %iv, %n - br i1 %range_check, label %loop_latch, label %deopt - -loop_latch: ; preds = %range_check_block - %iv_next = add i32 %iv, 1 - %loop_cond = icmp ult i32 %iv_next, 400 - br i1 %loop_cond, label %loop_header, label %exit - -deopt: ; preds = %range_check_block - ret void -} - -; Same as test_04, but range guarantees that %n is positive. So we can safely -; intersect ranges (with insertion of postloop). - -define void @test_05(i32* %p) { - -; CHECK-LABEL: test_05 -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: %n = load i32, i32* %p, !range ! -; CHECK-NEXT: [[CMP_1:%[^ ]+]] = icmp ugt i32 %n, 2 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP_1]], i32 %n, i32 2 -; CHECK-NEXT: [[CMP_2:%[^ ]+]] = icmp ult i32 2, %exit.mainloop.at -; CHECK-NEXT: br i1 [[CMP_2]], label %loop_header.preheader, label %main.pseudo.exit -; CHECK: range_check_block: ; preds = %inner_loop -; CHECK-NEXT: %range_check = icmp slt i32 %iv, %n -; CHECK-NEXT: br i1 true, label %loop_latch, label %deopt.loopexit2 -; CHECK: loop_latch: ; preds = %range_check_block -; CHECK-NEXT: %iv_next = add i32 %iv, 1 -; CHECK-NEXT: %loop_cond = icmp ult i32 %iv_next, 400 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 %iv_next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop_header, label %main.exit.selector -; CHECK: main.exit.selector: ; preds = %loop_latch -; CHECK-NEXT: %iv_next.lcssa = phi i32 [ %iv_next, %loop_latch ] -; CHECK-NEXT: %iv.lcssa = phi i32 [ %iv, %loop_latch ] -; CHECK-NEXT: [[MES_COND:%[^ ]+]] = icmp ult i32 %iv_next.lcssa, 400 -; CHECK-NEXT: br i1 [[MES_COND]], label %main.pseudo.exit, label %exit -; CHECK: loop_latch.postloop: ; preds = %range_check_block.postloop -; CHECK-NEXT: %iv_next.postloop = add i32 %iv.postloop, 1 -; CHECK-NEXT: %loop_cond.postloop = icmp ult i32 %iv_next.postloop, 400 -; CHECK-NEXT: br i1 %loop_cond.postloop, label %loop_header.postloop, label %exit.loopexit - -entry: - %n = load i32, i32* %p, !range !0 - br label %loop_header - -loop_header: ; preds = %loop_latch, %entry - %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ] - %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ] - %tmp2 = icmp sgt i32 %iv.prev, -1 - br i1 %tmp2, label %loop_header.split.us, label %exit - -loop_header.split.us: ; preds = %loop_header - br label %inner_loop - -inner_loop: ; preds = %inner_loop, %loop_header.split.us - %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] - %inner_iv_next = add nuw nsw i32 %inner_iv, 1 - %inner_cond = icmp ult i32 %inner_iv_next, 31 - br i1 %inner_cond, label %inner_loop, label %range_check_block - -exit: ; preds = %loop_latch, %loop_header - ret void - -range_check_block: ; preds = %inner_loop - %range_check = icmp slt i32 %iv, %n - br i1 %range_check, label %loop_latch, label %deopt - -loop_latch: ; preds = %range_check_block - %iv_next = add i32 %iv, 1 - %loop_cond = icmp ult i32 %iv_next, 400 - br i1 %loop_cond, label %loop_header, label %exit - -deopt: ; preds = %range_check_block - ret void -} - -!0 = !{i32 0, i32 50} diff --git a/llvm/test/Transforms/IRCE/ranges_of_different_types.ll b/llvm/test/Transforms/IRCE/ranges_of_different_types.ll deleted file mode 100644 index 5c8161369f2..00000000000 --- a/llvm/test/Transforms/IRCE/ranges_of_different_types.ll +++ /dev/null @@ -1,428 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; Make sure we can eliminate range check with signed latch, unsigned IRC and -; positive offset. The safe iteration space is: -; No preloop, -; %exit.mainloop.at = smax (0, -1 - smax(12 - %len, -102)). -; Formula verification: -; %len = 10 -; %exit.mainloop.at = 0 -; %len = 50 -; %exit.mainloop.at = 50 - 13 = 37. -; %len = 100 -; %exit.mainloop.at = 100 - 13 = 87. -; %len = 150 -; %exit.mainloop.at = 101. -; %len = SINT_MAX -; %exit.mainloop.at = 101 - -define void @test_01(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_01( -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 12, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[SUB1]], -102 -; CHECK-NEXT: [[SMAX:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, [[SMAX]] -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp sgt i32 [[SUB2]], 0 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP2]], i32 [[SUB2]], i32 0 -; CHECK-NEXT: [[GOTO_LOOP:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[GOTO_LOOP]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop -; CHECK: br i1 true, label %in.bounds -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = add i32 %idx, 13 - %abc = icmp ult i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Make sure we can eliminate range check with signed latch, unsigned IRC and -; negative offset. The safe iteration space is: -; %exit.preloop.at = 13 -; %exit.mainloop.at = smax(-1 - smax(smax(%len - SINT_MAX, -13) - 1 - %len, -102), 0) -; Formula verification: -; %len = 10 -; %exit.mainloop.at = 0 -; %len = 50 -; %exit.mainloop.at = 63 -; %len = 100 -; %exit.mainloop.at = 101 -; %len = 150 -; %exit.mainloop.at = 101 -; %len = SINT_MAX -; %exit.mainloop.at = 101 - -define void @test_02(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_02( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[LEN_MINUS_SMAX:%[^ ]+]] = add i32 %len, -2147483647 -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[LEN_MINUS_SMAX]], -13 -; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[LEN_MINUS_SMAX]], i32 -13 -; CHECK-NEXT: [[ADD1:%[^ ]+]] = add i32 [[SMAX1]], -1 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 [[ADD1]], %len -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp sgt i32 [[SUB1]], -102 -; CHECK-NEXT: [[SMAX2:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, [[SMAX2]] -; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp sgt i32 [[SUB2]], 0 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP3]], i32 [[SUB2]], i32 0 -; CHECK-NEXT: br i1 true, label %loop.preloop.preheader -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 0, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, 1 -; CHECK-NEXT: %idx.offset.preloop = sub i32 %idx.preloop, 13 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.offset.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp slt i32 %idx.next.preloop, 101 -; CHECK-NEXT: [[PRELOOP_COND:%[^ ]+]] = icmp slt i32 %idx.next.preloop, 13 -; CHECK-NEXT: br i1 [[PRELOOP_COND]], label %loop.preloop, label %preloop.exit.selector -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = sub i32 %idx, 13 - %abc = icmp ult i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Make sure we can eliminate range check with unsigned latch, signed IRC and -; positive offset. The safe iteration space is: -; No preloop, -; %exit.mainloop.at = -1 - umax(-2 - %len - smax(-1 - %len, -14), -102) -; Formula verification: -; %len = 10 -; %exit.mainloop.at = 0 -; %len = 50 -; %exit.mainloop.at = 37 -; %len = 100 -; %exit.mainloop.at = 87 -; %len = 150 -; %exit.mainloop.at = 101 -; %len = SINT_MAX -; %exit.mainloop.at = 101 - -define void @test_03(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_03( -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 -2, %len -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[SUB2]], -14 -; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB2]], i32 -14 -; CHECK-NEXT: [[SUB3:%[^ ]+]] = sub i32 [[SUB1]], [[SMAX1]] -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp ugt i32 [[SUB3]], -102 -; CHECK-NEXT: [[UMAX1:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB3]], i32 -102 -; CHECK-NEXT: %exit.mainloop.at = sub i32 -1, [[UMAX1]] -; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[CMP3]], label %loop.preheader, label %main.pseudo.exit -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = add i32 %idx, 13 - %abc = icmp slt i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Make sure we can eliminate range check with unsigned latch, signed IRC and -; positive offset. The safe iteration space is: -; %exit.preloop.at = 13 -; %exit.mainloop.at = -1 - umax(-14 - %len, -102) -; Formula verification: -; %len = 10 -; %exit.mainloop.at = 23 -; %len = 50 -; %exit.mainloop.at = 63 -; %len = 100 -; %exit.mainloop.at = 101 -; %len = 150 -; %exit.mainloop.at = 101 -; %len = SINT_MAX -; %exit.mainloop.at = 101 - -define void @test_04(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_04( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 -14, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp ugt i32 [[SUB1]], -102 -; CHECK-NEXT: [[UMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: %exit.mainloop.at = sub i32 -1, [[UMAX1]] -; CHECK-NEXT: br i1 true, label %loop.preloop.preheader -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp ult i32 %idx.next.preloop, 101 -; CHECK-NEXT: [[PRELOOP_COND:%[^ ]+]] = icmp ult i32 %idx.next.preloop, 13 -; CHECK-NEXT: br i1 [[PRELOOP_COND]], label %loop.preloop, label %preloop.exit.selector -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = sub i32 %idx, 13 - %abc = icmp slt i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Signed latch, signed RC, positive offset. Same as test_01. -define void @test_05(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_05( -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 12, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[SUB1]], -102 -; CHECK-NEXT: [[SMAX:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, [[SMAX]] -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp sgt i32 [[SUB2]], 0 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP2]], i32 [[SUB2]], i32 0 -; CHECK-NEXT: [[GOTO_LOOP:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[GOTO_LOOP]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop -; CHECK: br i1 true, label %in.bounds -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = add i32 %idx, 13 - %abc = icmp slt i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Signed latch, signed RC, negative offset. Same as test_02. -define void @test_06(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_06( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[LEN_MINUS_SMAX:%[^ ]+]] = add i32 %len, -2147483647 -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[LEN_MINUS_SMAX]], -13 -; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[LEN_MINUS_SMAX]], i32 -13 -; CHECK-NEXT: [[ADD1:%[^ ]+]] = add i32 [[SMAX1]], -1 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 [[ADD1]], %len -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp sgt i32 [[SUB1]], -102 -; CHECK-NEXT: [[SMAX2:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, [[SMAX2]] -; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp sgt i32 [[SUB2]], 0 -; CHECK-NEXT: %exit.mainloop.at = select i1 [[CMP3]], i32 [[SUB2]], i32 0 -; CHECK-NEXT: br i1 true, label %loop.preloop.preheader -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp slt i32 %idx.next.preloop, 101 -; CHECK-NEXT: [[PRELOOP_COND:%[^ ]+]] = icmp slt i32 %idx.next.preloop, 13 -; CHECK-NEXT: br i1 [[PRELOOP_COND]], label %loop.preloop, label %preloop.exit.selector -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = sub i32 %idx, 13 - %abc = icmp slt i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Unsigned latch, Unsigned RC, negative offset. Same as test_03. -define void @test_07(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_07( -; CHECK-NOT: preloop -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 -2, %len -; CHECK-NEXT: [[SUB2:%[^ ]+]] = sub i32 -1, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp sgt i32 [[SUB2]], -14 -; CHECK-NEXT: [[SMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB2]], i32 -14 -; CHECK-NEXT: [[SUB3:%[^ ]+]] = sub i32 [[SUB1]], [[SMAX1]] -; CHECK-NEXT: [[CMP2:%[^ ]+]] = icmp ugt i32 [[SUB3]], -102 -; CHECK-NEXT: [[UMAX1:%[^ ]+]] = select i1 [[CMP2]], i32 [[SUB3]], i32 -102 -; CHECK-NEXT: %exit.mainloop.at = sub i32 -1, [[UMAX1]] -; CHECK-NEXT: [[CMP3:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[CMP3]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop -; CHECK: br i1 true, label %in.bounds -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = add i32 %idx, 13 - %abc = icmp ult i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Unsigned latch, Unsigned RC, negative offset. Same as test_04. -define void @test_08(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK-LABEL: test_08( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[SUB1:%[^ ]+]] = sub i32 -14, %len -; CHECK-NEXT: [[CMP1:%[^ ]+]] = icmp ugt i32 [[SUB1]], -102 -; CHECK-NEXT: [[UMAX1:%[^ ]+]] = select i1 [[CMP1]], i32 [[SUB1]], i32 -102 -; CHECK-NEXT: %exit.mainloop.at = sub i32 -1, [[UMAX1]] -; CHECK-NEXT: br i1 true, label %loop.preloop.preheader -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp ult i32 %idx.next.preloop, 101 -; CHECK-NEXT: [[PRELOOP_COND:%[^ ]+]] = icmp ult i32 %idx.next.preloop, 13 -; CHECK-NEXT: br i1 [[PRELOOP_COND]], label %loop.preloop, label %preloop.exit.selector -; CHECK: postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.offset = sub i32 %idx, 13 - %abc = icmp ult i32 %idx.offset, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 101 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} diff --git a/llvm/test/Transforms/IRCE/rc-negative-bound.ll b/llvm/test/Transforms/IRCE/rc-negative-bound.ll deleted file mode 100644 index bfc0cd14778..00000000000 --- a/llvm/test/Transforms/IRCE/rc-negative-bound.ll +++ /dev/null @@ -1,600 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK-NOT: irce: in function test_01: constrained Loop -; CHECK-NOT: irce: in function test_02: constrained Loop -; CHECK: irce: in function test_03: constrained Loop - -; RC against known negative value. We should not do IRCE here. -define void @test_01(i32 *%arr, i32 %n) { -; CHECK-LABEL: @test_01( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp slt i32 [[IDX]], -9 -; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; - - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, -9 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_01, but the latch condition is unsigned. -define void @test_02(i32 *%arr, i32 %n) { -; CHECK-LABEL: @test_02( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp slt i32 [[IDX]], -9 -; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; - - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, -9 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; RC against a value which is not known to be non-negative. Here we should -; expand runtime checks against bound being positive or negative. -define void @test_03(i32 *%arr, i32 %n, i32 %bound) { -; CHECK-LABEL: @test_03( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[BOUND:%.*]], -2147483647 -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[TMP0]], i32 0 -; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[BOUND]], [[SMAX]] -; CHECK-NEXT: [[TMP3:%.*]] = sub i32 -1, [[BOUND]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP3]], -1 -; CHECK-NEXT: [[SMAX1:%.*]] = select i1 [[TMP4]], i32 [[TMP3]], i32 -1 -; CHECK-NEXT: [[TMP5:%.*]] = sub i32 -1, [[SMAX1]] -; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP5]], -1 -; CHECK-NEXT: [[SMAX2:%.*]] = select i1 [[TMP6]], i32 [[TMP5]], i32 -1 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[SMAX2]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = mul i32 [[TMP2]], [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = sub i32 -1, [[TMP8]] -; CHECK-NEXT: [[TMP10:%.*]] = sub i32 -1, [[N]] -; CHECK-NEXT: [[TMP11:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] -; CHECK-NEXT: [[SMAX3:%.*]] = select i1 [[TMP11]], i32 [[TMP9]], i32 [[TMP10]] -; CHECK-NEXT: [[TMP12:%.*]] = sub i32 -1, [[SMAX3]] -; CHECK-NEXT: [[TMP13:%.*]] = icmp sgt i32 [[TMP12]], 0 -; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = select i1 [[TMP13]], i32 [[TMP12]], i32 0 -; CHECK-NEXT: [[TMP14:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP14]], label [[LOOP_PREHEADER5:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] -; CHECK: loop.preheader5: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER5]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp slt i32 [[IDX]], [[BOUND]] -; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT6:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP15]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]] -; CHECK: main.exit.selector: -; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ] -; CHECK-NEXT: [[TMP16:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], [[N]] -; CHECK-NEXT: br i1 [[TMP16]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: main.pseudo.exit: -; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[POSTLOOP:%.*]] -; CHECK: out.of.bounds.loopexit: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]] -; CHECK: out.of.bounds.loopexit6: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit.loopexit: -; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; CHECK: postloop: -; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]] -; CHECK: loop.postloop: -; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ], [ [[IDX_COPY]], [[POSTLOOP]] ] -; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1 -; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[BOUND]] -; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof !0 -; CHECK: in.bounds.postloop: -; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, i32* [[ARR]], i32 [[IDX_POSTLOOP]] -; CHECK-NEXT: store i32 0, i32* [[ADDR_POSTLOOP]] -; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], [[N]] -; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop !1, !irce.loop.clone !6 -; - - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %bound - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; RC against a value which is not known to be non-negative. Here we should -; expand runtime checks against bound being positive or negative. -define void @test_04(i32 *%arr, i32 %n, i32 %bound) { -; CHECK-LABEL: @test_04( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = sub i32 -1, [[BOUND:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], -1 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[TMP0]], i32 -1 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[BOUND]], [[SMAX]] -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP2]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = sub i32 -1, [[SMAX]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP4]], -1 -; CHECK-NEXT: [[SMAX1:%.*]] = select i1 [[TMP5]], i32 [[TMP4]], i32 -1 -; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SMAX1]], 1 -; CHECK-NEXT: [[TMP7:%.*]] = mul i32 [[TMP3]], [[TMP6]] -; CHECK-NEXT: [[TMP8:%.*]] = sub i32 -1, [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = sub i32 -1, [[N]] -; CHECK-NEXT: [[TMP10:%.*]] = icmp ugt i32 [[TMP8]], [[TMP9]] -; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP10]], i32 [[TMP8]], i32 [[TMP9]] -; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = sub i32 -1, [[UMAX]] -; CHECK-NEXT: [[TMP11:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP11]], label [[LOOP_PREHEADER2:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] -; CHECK: loop.preheader2: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER2]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp slt i32 [[IDX]], [[BOUND]] -; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT3:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP12]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]] -; CHECK: main.exit.selector: -; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ] -; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], [[N]] -; CHECK-NEXT: br i1 [[TMP13]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: main.pseudo.exit: -; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[POSTLOOP:%.*]] -; CHECK: out.of.bounds.loopexit: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]] -; CHECK: out.of.bounds.loopexit3: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit.loopexit: -; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; CHECK: postloop: -; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]] -; CHECK: loop.postloop: -; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ], [ [[IDX_COPY]], [[POSTLOOP]] ] -; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1 -; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[BOUND]] -; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof !0 -; CHECK: in.bounds.postloop: -; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, i32* [[ARR]], i32 [[IDX_POSTLOOP]] -; CHECK-NEXT: store i32 0, i32* [[ADDR_POSTLOOP]] -; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], [[N]] -; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop !7, !irce.loop.clone !6 -; - - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %bound - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_01, unsigned range check. -; FIXME: We could remove the range check here, but it does not happen due to the -; limintation we posed to fix the miscompile (see comments in the method -; computeSafeIterationSpace). -define void @test_05(i32 *%arr, i32 %n) { -; CHECK-LABEL: @test_05( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], -9 -; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, -9 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_02, unsigned range check. -; FIXME: We could remove the range check here, but it does not happen due to the -; limintation we posed to fix the miscompile (see comments in the method -; computeSafeIterationSpace). -define void @test_06(i32 *%arr, i32 %n) { -; CHECK-LABEL: @test_06( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], -9 -; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, -9 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_03, unsigned range check. -; FIXME: Currently we remove the check, but we will not execute the main loop if -; %bound is negative (i.e. in [SINT_MAX + 1, UINT_MAX)). We should be able to -; safely remove this check (see comments in the method -; computeSafeIterationSpace). -define void @test_07(i32 *%arr, i32 %n, i32 %bound) { -; CHECK-LABEL: @test_07( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[BOUND:%.*]], -2147483647 -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[TMP0]], i32 0 -; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[BOUND]], [[SMAX]] -; CHECK-NEXT: [[TMP3:%.*]] = sub i32 -1, [[BOUND]] -; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP3]], -1 -; CHECK-NEXT: [[SMAX1:%.*]] = select i1 [[TMP4]], i32 [[TMP3]], i32 -1 -; CHECK-NEXT: [[TMP5:%.*]] = sub i32 -1, [[SMAX1]] -; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP5]], -1 -; CHECK-NEXT: [[SMAX2:%.*]] = select i1 [[TMP6]], i32 [[TMP5]], i32 -1 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[SMAX2]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = mul i32 [[TMP2]], [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = sub i32 -1, [[TMP8]] -; CHECK-NEXT: [[TMP10:%.*]] = sub i32 -1, [[N]] -; CHECK-NEXT: [[TMP11:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] -; CHECK-NEXT: [[SMAX3:%.*]] = select i1 [[TMP11]], i32 [[TMP9]], i32 [[TMP10]] -; CHECK-NEXT: [[TMP12:%.*]] = sub i32 -1, [[SMAX3]] -; CHECK-NEXT: [[TMP13:%.*]] = icmp sgt i32 [[TMP12]], 0 -; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = select i1 [[TMP13]], i32 [[TMP12]], i32 0 -; CHECK-NEXT: [[TMP14:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP14]], label [[LOOP_PREHEADER5:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] -; CHECK: loop.preheader5: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER5]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[BOUND]] -; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT6:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP15]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]] -; CHECK: main.exit.selector: -; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ] -; CHECK-NEXT: [[TMP16:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], [[N]] -; CHECK-NEXT: br i1 [[TMP16]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: main.pseudo.exit: -; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[POSTLOOP:%.*]] -; CHECK: out.of.bounds.loopexit: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]] -; CHECK: out.of.bounds.loopexit6: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit.loopexit: -; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; CHECK: postloop: -; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]] -; CHECK: loop.postloop: -; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ], [ [[IDX_COPY]], [[POSTLOOP]] ] -; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1 -; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[BOUND]] -; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof !0 -; CHECK: in.bounds.postloop: -; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, i32* [[ARR]], i32 [[IDX_POSTLOOP]] -; CHECK-NEXT: store i32 0, i32* [[ADDR_POSTLOOP]] -; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], [[N]] -; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop !8, !irce.loop.clone !6 -; - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, %bound - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Same as test_04, unsigned range check. -; FIXME: Currently we remove the check, but we will not execute the main loop if -; %bound is negative (i.e. in [SINT_MAX + 1, UINT_MAX)). We should be able to -; safely remove this check (see comments in the method -; computeSafeIterationSpace). -define void @test_08(i32 *%arr, i32 %n, i32 %bound) { -; CHECK-LABEL: @test_08( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[FIRST_ITR_CHECK:%.*]] = icmp sgt i32 [[N:%.*]], 0 -; CHECK-NEXT: br i1 [[FIRST_ITR_CHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] -; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = sub i32 -1, [[BOUND:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], -1 -; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP1]], i32 [[TMP0]], i32 -1 -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[BOUND]], [[SMAX]] -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP2]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = sub i32 -1, [[SMAX]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP4]], -1 -; CHECK-NEXT: [[SMAX1:%.*]] = select i1 [[TMP5]], i32 [[TMP4]], i32 -1 -; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SMAX1]], 1 -; CHECK-NEXT: [[TMP7:%.*]] = mul i32 [[TMP3]], [[TMP6]] -; CHECK-NEXT: [[TMP8:%.*]] = sub i32 -1, [[TMP7]] -; CHECK-NEXT: [[TMP9:%.*]] = sub i32 -1, [[N]] -; CHECK-NEXT: [[TMP10:%.*]] = icmp ugt i32 [[TMP8]], [[TMP9]] -; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP10]], i32 [[TMP8]], i32 [[TMP9]] -; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = sub i32 -1, [[UMAX]] -; CHECK-NEXT: [[TMP11:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP11]], label [[LOOP_PREHEADER2:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] -; CHECK: loop.preheader2: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER2]] ] -; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1 -; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[BOUND]] -; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT3:%.*]], !prof !0 -; CHECK: in.bounds: -; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, i32* [[ARR:%.*]], i32 [[IDX]] -; CHECK-NEXT: store i32 0, i32* [[ADDR]] -; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], [[N]] -; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]] -; CHECK-NEXT: br i1 [[TMP12]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]] -; CHECK: main.exit.selector: -; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ] -; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], [[N]] -; CHECK-NEXT: br i1 [[TMP13]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT_LOOPEXIT:%.*]] -; CHECK: main.pseudo.exit: -; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[LOOP_PREHEADER]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] -; CHECK-NEXT: br label [[POSTLOOP:%.*]] -; CHECK: out.of.bounds.loopexit: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]] -; CHECK: out.of.bounds.loopexit3: -; CHECK-NEXT: br label [[OUT_OF_BOUNDS]] -; CHECK: out.of.bounds: -; CHECK-NEXT: ret void -; CHECK: exit.loopexit.loopexit: -; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] -; CHECK: exit.loopexit: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret void -; CHECK: postloop: -; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]] -; CHECK: loop.postloop: -; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ], [ [[IDX_COPY]], [[POSTLOOP]] ] -; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1 -; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[BOUND]] -; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof !0 -; CHECK: in.bounds.postloop: -; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, i32* [[ARR]], i32 [[IDX_POSTLOOP]] -; CHECK-NEXT: store i32 0, i32* [[ADDR_POSTLOOP]] -; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], [[N]] -; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop !9, !irce.loop.clone !6 -; - entry: - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, %bound - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !0 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} -!0 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/single-access-no-preloop.ll b/llvm/test/Transforms/IRCE/single-access-no-preloop.ll deleted file mode 100644 index fb643139c6d..00000000000 --- a/llvm/test/Transforms/IRCE/single-access-no-preloop.ll +++ /dev/null @@ -1,250 +0,0 @@ -; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s | FileCheck %s - -define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_no_preloop_no_offset( - -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds - -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[continue:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, %n -; CHECK-NEXT: br i1 [[continue]], label %main.pseudo.exit, label %exit.loopexit - -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop - -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop - -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.postloop ], [ %idx.copy, %postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %len -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds - -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, %n -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - - -define void @single_access_no_preloop_with_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.for.abc = add i32 %idx, 4 - %abc = icmp slt i32 %idx.for.abc, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx.for.abc - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_no_preloop_with_offset( - -; CHECK: loop.preheader: -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_safe_range_end:[^ ]+]] = sub i32 3, %len -; CHECK: [[not_exit_main_loop_at_hiclamp_cmp:[^ ]+]] = icmp sgt i32 [[not_n]], [[not_safe_range_end]] -; CHECK: [[not_exit_main_loop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_main_loop_at_hiclamp_cmp]], i32 [[not_n]], i32 [[not_safe_range_end]] -; CHECK: [[exit_main_loop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_main_loop_at_hiclamp]] -; CHECK: [[exit_main_loop_at_loclamp_cmp:[^ ]+]] = icmp sgt i32 [[exit_main_loop_at_hiclamp]], 0 -; CHECK: [[exit_main_loop_at_loclamp:[^ ]+]] = select i1 [[exit_main_loop_at_loclamp_cmp]], i32 [[exit_main_loop_at_hiclamp]], i32 0 -; CHECK: [[enter_main_loop:[^ ]+]] = icmp slt i32 0, [[exit_main_loop_at_loclamp]] -; CHECK: br i1 [[enter_main_loop]], label %loop.preheader2, label %main.pseudo.exit - -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds - -; CHECK: in.bounds: -; CHECK: [[continue_main_loop:[^ ]+]] = icmp slt i32 %idx.next, [[exit_main_loop_at_loclamp]] -; CHECK: br i1 [[continue_main_loop]], label %loop, label %main.exit.selector - -; CHECK: main.pseudo.exit: -; CHECK: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK: br label %postloop - -; CHECK: loop.postloop: -; CHECK: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.postloop ], [ %idx.copy, %postloop ] - -; CHECK: in.bounds.postloop: -; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n -; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -; Make sure that we do not do IRCE if we know that the safe iteration range of -; the main loop is empty. - -define void @single_access_empty_range(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, 0 - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_empty_range( -; CHECK-NOT: br i1 false -; CHECK-NOT: preloop -; CHECK-NOT: postloop - -define void @single_access_empty_range_2(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds2 ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, 60 - br i1 %abc, label %in.bounds1, label %out.of.bounds, !prof !1 - - in.bounds1: - %def = icmp slt i32 %idx, 0 - br i1 %def, label %in.bounds2, label %out.of.bounds, !prof !1 - -in.bounds2: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_empty_range_2( -; CHECK-NOT: br i1 false -; CHECK-NOT: preloop - -define void @single_access_no_preloop_no_offset_phi_len(i32 *%arr, i32 *%a_len_ptr, i32 *%b_len_ptr, i32 %n, i1 %unknown_cond) { - entry: - br i1 %unknown_cond, label %if.true, label %if.false - -if.true: - %len_a = load i32, i32* %a_len_ptr, !range !0 - br label %merge - -if.false: - %len_b = load i32, i32* %b_len_ptr, !range !0 - br label %merge - -merge: - %len = phi i32 [ %len_a, %if.true ], [ %len_b, %if.false ] - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %merge ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_no_preloop_no_offset_phi_len( - -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds - -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[continue:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, %n -; CHECK-NEXT: br i1 [[continue]], label %main.pseudo.exit, label %exit.loopexit - -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop - -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop - -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.postloop ], [ %idx.copy, %postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %len -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds - -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, %n -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/single-access-with-preloop.ll b/llvm/test/Transforms/IRCE/single-access-with-preloop.ll deleted file mode 100644 index 6f3b0324e39..00000000000 --- a/llvm/test/Transforms/IRCE/single-access-with-preloop.ll +++ /dev/null @@ -1,93 +0,0 @@ -; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s -; RUN: opt -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s | FileCheck %s - -define void @single_access_with_preloop(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32 %offset) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %array.idx = add i32 %idx, %offset - %abc.high = icmp slt i32 %array.idx, %len - %abc.low = icmp sge i32 %array.idx, 0 - %abc = and i1 %abc.low, %abc.high - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %array.idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; CHECK-LABEL: @single_access_with_preloop( -; CHECK: loop.preheader: -; CHECK: [[check_min_sint_offset:[^ ]+]] = icmp sgt i32 %offset, -2147483647 -; CHECK: [[safe_offset_preloop:[^ ]+]] = select i1 [[check_min_sint_offset]], i32 %offset, i32 -2147483647 -; If Offset was a SINT_MIN, we could have an overflow here. That is why we calculated its safe version. -; CHECK: [[not_safe_start:[^ ]+]] = add i32 [[safe_offset_preloop]], -1 -; CHECK: [[not_n:[^ ]+]] = sub i32 -1, %n -; CHECK: [[not_exit_preloop_at_cond_loclamp:[^ ]+]] = icmp sgt i32 [[not_safe_start]], [[not_n]] -; CHECK: [[not_exit_preloop_at_loclamp:[^ ]+]] = select i1 [[not_exit_preloop_at_cond_loclamp]], i32 [[not_safe_start]], i32 [[not_n]] -; CHECK: [[exit_preloop_at_loclamp:[^ ]+]] = sub i32 -1, [[not_exit_preloop_at_loclamp]] -; CHECK: [[exit_preloop_at_cond:[^ ]+]] = icmp sgt i32 [[exit_preloop_at_loclamp]], 0 -; CHECK: [[exit_preloop_at:[^ ]+]] = select i1 [[exit_preloop_at_cond]], i32 [[exit_preloop_at_loclamp]], i32 0 - - -; CHECK: [[len_minus_sint_max:[^ ]+]] = add i32 %len, -2147483647 -; CHECK: [[check_len_min_sint_offset:[^ ]+]] = icmp sgt i32 %offset, [[len_minus_sint_max]] -; CHECK: [[safe_offset_mainloop:[^ ]+]] = select i1 [[check_len_min_sint_offset]], i32 %offset, i32 [[len_minus_sint_max]] -; CHECK: [[not_safe_start_2:[^ ]+]] = add i32 [[safe_offset_mainloop]], -1 -; If Offset was a SINT_MIN, we could have an overflow here. That is why we calculated its safe version. -; CHECK: [[not_safe_upper_end:[^ ]+]] = sub i32 [[not_safe_start_2]], %len -; CHECK: [[not_exit_mainloop_at_cond_loclamp:[^ ]+]] = icmp sgt i32 [[not_safe_upper_end]], [[not_n]] -; CHECK: [[not_exit_mainloop_at_loclamp:[^ ]+]] = select i1 [[not_exit_mainloop_at_cond_loclamp]], i32 [[not_safe_upper_end]], i32 [[not_n]] -; CHECK: [[check_offset_mainloop_2:[^ ]+]] = icmp sgt i32 %offset, 0 -; CHECK: [[safe_offset_mainloop_2:[^ ]+]] = select i1 [[check_offset_mainloop_2]], i32 %offset, i32 0 -; CHECK: [[not_safe_lower_end:[^ ]+]] = add i32 [[safe_offset_mainloop_2]], -2147483648 -; CHECK: [[not_exit_mainloop_at_cond_hiclamp:[^ ]+]] = icmp sgt i32 [[not_exit_mainloop_at_loclamp]], [[not_safe_lower_end]] -; CHECK: [[not_exit_mainloop_at_hiclamp:[^ ]+]] = select i1 [[not_exit_mainloop_at_cond_hiclamp]], i32 [[not_exit_mainloop_at_loclamp]], i32 [[not_safe_lower_end]] -; CHECK: [[exit_mainloop_at_hiclamp:[^ ]+]] = sub i32 -1, [[not_exit_mainloop_at_hiclamp]] -; CHECK: [[exit_mainloop_at_cmp:[^ ]+]] = icmp sgt i32 [[exit_mainloop_at_hiclamp]], 0 -; CHECK: [[exit_mainloop_at:[^ ]+]] = select i1 [[exit_mainloop_at_cmp]], i32 [[exit_mainloop_at_hiclamp]], i32 0 - -; CHECK: mainloop: -; CHECK: br label %loop - -; CHECK: loop: -; CHECK: %abc.high = icmp slt i32 %array.idx, %len -; CHECK: %abc.low = icmp sge i32 %array.idx, 0 -; CHECK: %abc = and i1 true, true -; CHECK: br i1 %abc, label %in.bounds, label %out.of.bounds.loopexit11 - -; CHECK: in.bounds: -; CHECK: [[continue_mainloop_cond:[^ ]+]] = icmp slt i32 %idx.next, [[exit_mainloop_at]] -; CHECK: br i1 [[continue_mainloop_cond]], label %loop, label %main.exit.selector - -; CHECK: main.exit.selector: -; CHECK: [[mainloop_its_left:[^ ]+]] = icmp slt i32 %idx.next.lcssa, %n -; CHECK: br i1 [[mainloop_its_left]], label %main.pseudo.exit, label %exit.loopexit - -; CHECK: in.bounds.preloop: -; CHECK: [[continue_preloop_cond:[^ ]+]] = icmp slt i32 %idx.next.preloop, [[exit_preloop_at]] -; CHECK: br i1 [[continue_preloop_cond]], label %loop.preloop, label %preloop.exit.selector - -; CHECK: preloop.exit.selector: -; CHECK: [[preloop_its_left:[^ ]+]] = icmp slt i32 %idx.next.preloop.lcssa, %n -; CHECK: br i1 [[preloop_its_left]], label %preloop.pseudo.exit, label %exit.loopexit - -; CHECK: in.bounds.postloop: -; CHECK: %next.postloop = icmp slt i32 %idx.next.postloop, %n -; CHECK: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/skip-profitability-checks.ll b/llvm/test/Transforms/IRCE/skip-profitability-checks.ll deleted file mode 100644 index aec625cb27a..00000000000 --- a/llvm/test/Transforms/IRCE/skip-profitability-checks.ll +++ /dev/null @@ -1,32 +0,0 @@ -; RUN: opt -irce-skip-profitability-checks -S -verify-loop-info -irce < %s | FileCheck %s -; RUN: opt -irce-skip-profitability-checks -S -verify-loop-info -passes='require<branch-prob>,loop(irce)' < %s | FileCheck %s - -define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { -; CHECK-LABEL: @single_access_no_preloop_no_offset( -; CHECK: main.exit.selector: - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 1, i32 64} diff --git a/llvm/test/Transforms/IRCE/stride_more_than_1.ll b/llvm/test/Transforms/IRCE/stride_more_than_1.ll deleted file mode 100644 index 8aaecac7d30..00000000000 --- a/llvm/test/Transforms/IRCE/stride_more_than_1.ll +++ /dev/null @@ -1,481 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -; IV = 0; IV <s 100; IV += 7; 0 <= Len <= 50. IRCE is allowed. -define void @test_01(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_01( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop.preheader: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add i32 %idx, 7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp slt i32 %idx.next, 100 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp slt i32 %idx.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop, label %main.exit.selector -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, 100 -; CHECK-NEXT: br i1 [[COND3]], label %main.pseudo.exit, label %exit -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 7 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, 100 -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = 0; IV <s MAX_INT - 7; IV += 7; 0 <= Len <= 50. IRCE is allowed. -define void @test_02(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_02( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop.preheader: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add i32 %idx, 7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp slt i32 %idx.next, 2147483640 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp slt i32 %idx.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop, label %main.exit.selector -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, 2147483640 -; CHECK-NEXT: br i1 [[COND3]], label %main.pseudo.exit, label %exit -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 7 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, 2147483640 -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 2147483640 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 7. This is the greatest -; value of Len for which IRCE is allowed. -define void @test_03(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_03( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp slt i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop.preheader: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add i32 %idx, 7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp slt i32 %idx.next, 2147483647 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp slt i32 %idx.next, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop, label %main.exit.selector -; CHECK: main.exit.selector: -; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, 2147483647 -; CHECK-NEXT: br i1 [[COND3]], label %main.pseudo.exit, label %exit -; CHECK: main.pseudo.exit: -; CHECK-NEXT: %idx.copy = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 0, %entry ], [ %idx.next.lcssa, %main.exit.selector ] -; CHECK-NEXT: br label %postloop -; CHECK: postloop: -; CHECK-NEXT: br label %loop.postloop -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 7 -; CHECK-NEXT: %abc.postloop = icmp slt i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.postloop: -; CHECK-NEXT: %addr.postloop = getelementptr i32, i32* %arr, i32 %idx.postloop -; CHECK-NEXT: store i32 0, i32* %addr.postloop -; CHECK-NEXT: %next.postloop = icmp slt i32 %idx.next.postloop, 2147483647 -; CHECK-NEXT: br i1 %next.postloop, label %loop.postloop, label %exit.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !1 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 2147483647 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 6. IRCE is allowed -; because the branch would fail once idx.next == MAX_INT - 1 keeping the -; access in bounds. -define void @test_04(i32* %arr, i32* %a_len_ptr) { - ; CHECK: @test_04( - ; CHECK: loop: - ; CHECK: [[IV:%[^ ]+]] = phi i32 - ; CHECK: [[IDX_NEXT:%[^ ]+]] = add i32 [[IV]], 7 - - ; CHECK: main.exit.selector: - ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ [[IDX_NEXT]], %in.bounds ] - ; CHECK: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 2147483647 - ; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %exit - - ; CHECK: loop.postloop: - ; CHECK: [[IDX_POST:%[^ ]+]] = phi i32 - ; CHECK: [[COND_POST:%[^ ]+]] = icmp slt i32 [[IDX_POST]], %exit.mainloop.at - ; CHECK: br i1 [[COND_POST]], label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !2 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, 2147483647 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = 100; IV >s -1; IV -= 7; 0 <= Len <= 50. IRCE is allowed. -define void @test_05(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_05( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr -; CHECK-NEXT: %exit.preloop.at = add i32 %len, -1 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp sgt i32 100, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: loop.preloop.preheader: -; CHECK-NEXT: br label %loop.preloop -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp sgt i32 %idx.next, -1 -; CHECK-NEXT: br i1 %next, label %loop, label %exit.loopexit -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 100, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -7 -; CHECK-NEXT: %abc.preloop = icmp slt i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp sgt i32 %idx.next.preloop, -1 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp sgt i32 %idx.next.preloop, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop, label %preloop.exit.selector -; CHECK: preloop.exit.selector: -; CHECK-NEXT: %idx.next.preloop.lcssa = phi i32 [ %idx.next.preloop, %in.bounds.preloop ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp sgt i32 %idx.next.preloop.lcssa, -1 -; CHECK-NEXT: br i1 [[COND3]], label %preloop.pseudo.exit, label %exit -; CHECK: preloop.pseudo.exit: -; CHECK-NEXT: %idx.preloop.copy = phi i32 [ 100, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 100, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: br label %mainloop - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp sgt i32 %idx.next, -1 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = MAX_INT - 7; IV >u 6; IV -= 7; 10 <= Len <= 50. IRCE is allowed. -define void @test_06(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_06( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr -; CHECK-NEXT: %exit.preloop.at = add i32 %len, -1 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 2147483640, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: loop.preloop.preheader: -; CHECK-NEXT: br label %loop.preloop -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp ugt i32 %idx.next, 6 -; CHECK-NEXT: br i1 %next, label %loop, label %exit.loopexit -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 2147483640, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -7 -; CHECK-NEXT: %abc.preloop = icmp slt i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp ugt i32 %idx.next.preloop, 6 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 %idx.next.preloop, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop, label %preloop.exit.selector -; CHECK: preloop.exit.selector: -; CHECK-NEXT: %idx.next.preloop.lcssa = phi i32 [ %idx.next.preloop, %in.bounds.preloop ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp ugt i32 %idx.next.preloop.lcssa, 6 -; CHECK-NEXT: br i1 [[COND3]], label %preloop.pseudo.exit, label %exit -; CHECK: preloop.pseudo.exit: -; CHECK-NEXT: %idx.preloop.copy = phi i32 [ 2147483640, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 2147483640, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: br label %mainloop - -entry: - %len = load i32, i32* %a_len_ptr, !range !3 - br label %loop - -loop: - %idx = phi i32 [ 2147483640, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 6 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = MAX_INT - 7; IV >u 5; IV -= 7; 10 <= Len <= 50. IRCE is not allowed, -; because we can cross the 0 border. -define void @test_07(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_07( - -entry: - %len = load i32, i32* %a_len_ptr, !range !3 - br label %loop - -loop: - %idx = phi i32 [ 2147483640, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 5 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; IV = MAX_INT; IV >u 6; IV -= 7; 10 <= Len <= 50. IRCE is allowed. -define void @test_08(i32* %arr, i32* %a_len_ptr) { - -; CHECK: @test_08( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr -; CHECK-NEXT: %exit.preloop.at = add i32 %len, -1 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 2147483647, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND1]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: loop.preloop.preheader: -; CHECK-NEXT: br label %loop.preloop -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -7 -; CHECK-NEXT: %abc = icmp slt i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK: in.bounds: -; CHECK-NEXT: %addr = getelementptr i32, i32* %arr, i32 %idx -; CHECK-NEXT: store i32 0, i32* %addr -; CHECK-NEXT: %next = icmp ugt i32 %idx.next, 6 -; CHECK-NEXT: br i1 %next, label %loop, label %exit.loopexit -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 2147483647, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -7 -; CHECK-NEXT: %abc.preloop = icmp slt i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit -; CHECK: in.bounds.preloop: -; CHECK-NEXT: %addr.preloop = getelementptr i32, i32* %arr, i32 %idx.preloop -; CHECK-NEXT: store i32 0, i32* %addr.preloop -; CHECK-NEXT: %next.preloop = icmp ugt i32 %idx.next.preloop, 6 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 %idx.next.preloop, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop, label %preloop.exit.selector -; CHECK: preloop.exit.selector: -; CHECK-NEXT: %idx.next.preloop.lcssa = phi i32 [ %idx.next.preloop, %in.bounds.preloop ] -; CHECK-NEXT: [[COND3:%[^ ]+]] = icmp ugt i32 %idx.next.preloop.lcssa, 6 -; CHECK-NEXT: br i1 [[COND3]], label %preloop.pseudo.exit, label %exit -; CHECK: preloop.pseudo.exit: -; CHECK-NEXT: %idx.preloop.copy = phi i32 [ 2147483647, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: %indvar.end = phi i32 [ 2147483647, %entry ], [ %idx.next.preloop.lcssa, %preloop.exit.selector ] -; CHECK-NEXT: br label %mainloop - -entry: - %len = load i32, i32* %a_len_ptr, !range !3 - br label %loop - -loop: - %idx = phi i32 [ 2147483647, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -7 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 6 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 50} -!1 = !{i32 0, i32 2147483640} -!2 = !{i32 0, i32 2147483641} -!3 = !{i32 10, i32 50} diff --git a/llvm/test/Transforms/IRCE/unhandled.ll b/llvm/test/Transforms/IRCE/unhandled.ll deleted file mode 100644 index db4ac84d746..00000000000 --- a/llvm/test/Transforms/IRCE/unhandled.ll +++ /dev/null @@ -1,100 +0,0 @@ -; RUN: opt -irce-print-changed-loops -verify-loop-info -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -irce-print-changed-loops -verify-loop-info -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK-NOT: constrained Loop at depth - -; Demonstrates that we don't currently handle the general expression -; `A * I + B'. - -define void @general_affine_expressions(i32 *%arr, i32 *%a_len_ptr, i32 %n, - i32 %scale, i32 %offset) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %idx.mul = mul i32 %idx, %scale - %array.idx = add i32 %idx.mul, %offset - %abc.high = icmp slt i32 %array.idx, %len - %abc.low = icmp sge i32 %array.idx, 0 - %abc = and i1 %abc.low, %abc.high - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %array.idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - - out.of.bounds: - ret void - - exit: - ret void -} - -; Check that we do the right thing for a loop that could not be -; simplified due to an indirectbr. - -define void @multiple_latches(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %n.add.1 = add i32 %n, 1 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ], [ %idx.next, %continue ] - %idx.next = add i32 %idx, 1 - %idx.next2 = add i32 %idx, 2 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %continue - - continue: - %next2 = icmp slt i32 %idx.next, %n.add.1 - %dest = select i1 %next2, i8* blockaddress(@multiple_latches, %loop), i8* blockaddress(@multiple_latches, %exit) - indirectbr i8* %dest, [ label %loop, label %exit] - - out.of.bounds: - ret void - - exit: - ret void -} - -define void @already_cloned(i32 *%arr, i32 *%a_len_ptr, i32 %n) { - entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - - loop: - %idx = phi i32 [ 0, %entry ] , [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - - in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit, !irce.loop.clone !{} - - out.of.bounds: - ret void - - exit: - ret void -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} diff --git a/llvm/test/Transforms/IRCE/unsigned_comparisons_ugt.ll b/llvm/test/Transforms/IRCE/unsigned_comparisons_ugt.ll deleted file mode 100644 index 8f00c733569..00000000000 --- a/llvm/test/Transforms/IRCE/unsigned_comparisons_ugt.ll +++ /dev/null @@ -1,264 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -; UGT condition for increasing loop. -define void @test_01(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_01( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 100 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; UGT condition for decreasing loop. -define void @test_02(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_02( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1 -; CHECK-NEXT: %umax = select i1 [[COND1]], i32 %len, i32 1 -; CHECK-NEXT: %exit.preloop.at = add i32 %umax, -1 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 100, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.postloop: -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 100, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 0 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check SINT_MAX + 1, test is similar to test_01. -define void @test_03(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_03( -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 2147483648 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check SINT_MAX + 1, test is similar to test_02. -define void @test_04(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_04( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1 -; CHECK-NEXT: %umax = select i1 [[COND1]], i32 %len, i32 1 -; CHECK-NEXT: %exit.preloop.at = add i32 %umax, -1 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 -2147483648, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.postloop: -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ -2147483648, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 0 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Increasing loop, UINT_MAX. Negative test: we cannot add 1 to UINT_MAX. -define void @test_05(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_05( -; CHECK-NOT: loop.preloop: -; CHECK-NOT: loop.postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 4294967295 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Decreasing loop, UINT_MAX. Positive test. -define void @test_06(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_06( -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add nuw i32 %idx, -1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.postloop: -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ -1, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add nuw i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nuw i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ugt i32 %idx.next, 0 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 50} diff --git a/llvm/test/Transforms/IRCE/unsigned_comparisons_ult.ll b/llvm/test/Transforms/IRCE/unsigned_comparisons_ult.ll deleted file mode 100644 index dc59c11df1b..00000000000 --- a/llvm/test/Transforms/IRCE/unsigned_comparisons_ult.ll +++ /dev/null @@ -1,391 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> -; CHECK-NOT: irce: in function test_09: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -; ULT condition for increasing loop. -define void @test_01(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_01 -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; ULT condition for decreasing loops. -define void @test_02(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_02( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1 -; CHECK-NEXT: %umax = select i1 [[COND1]], i32 %len, i32 1 -; CHECK-NEXT: %exit.preloop.at = add i32 %umax, -1 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 100, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.postloop: -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ 100, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 1 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check SINT_MAX. -define void @test_03(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_03 -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 2147483647 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check SINT_MAX + 1, test is similar to test_01. -define void @test_04(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_04 -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 2147483648 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Check SINT_MAX + 1, test is similar to test_02. -define void @test_05(i32* %arr, i32* %a_len_ptr) #0 { -; CHECK: test_05( -; CHECK: entry: -; CHECK-NEXT: %len = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND1:%[^ ]+]] = icmp ugt i32 %len, 1 -; CHECK-NEXT: %umax = select i1 [[COND1]], i32 %len, i32 1 -; CHECK-NEXT: %exit.preloop.at = add i32 %umax, -1 -; CHECK-NEXT: [[COND2:%[^ ]+]] = icmp ugt i32 -2147483648, %exit.preloop.at -; CHECK-NEXT: br i1 [[COND2]], label %loop.preloop.preheader, label %preloop.pseudo.exit -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.preloop.copy, %mainloop ], [ %idx.next, %in.bounds ] -; CHECK-NEXT: %idx.next = add i32 %idx, -1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %len -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.postloop: -; CHECK: loop.preloop: -; CHECK-NEXT: %idx.preloop = phi i32 [ %idx.next.preloop, %in.bounds.preloop ], [ -2147483648, %loop.preloop.preheader ] -; CHECK-NEXT: %idx.next.preloop = add i32 %idx.preloop, -1 -; CHECK-NEXT: %abc.preloop = icmp ult i32 %idx.preloop, %len -; CHECK-NEXT: br i1 %abc.preloop, label %in.bounds.preloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 1 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Increasing loop, UINT_MAX. Positive test. -define void @test_06(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_06 -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add nuw nsw i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add nuw nsw i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nsw nuw i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 4294967295 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Decreasing loop, UINT_MAX. Negative test: we cannot substract -1 from 0. -define void @test_07(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_07( -; CHECK-NOT: loop.preloop: -; CHECK-NOT: loop.postloop: - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add nuw i32 %idx, -1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 0 - br i1 %next, label %exit, label %loop - -out.of.bounds: - ret void - -exit: - ret void -} - -; Unsigned walking through signed border is allowed. -; Iteration space [0; UINT_MAX - 99), the fact that SINT_MAX is within this -; range does not prevent us from performing IRCE. - -define void @test_08(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_08 -; CHECK: entry: -; CHECK-NEXT: %exit.mainloop.at = load i32, i32* %a_len_ptr, !range !0 -; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 0, %exit.mainloop.at -; CHECK-NEXT: br i1 [[COND]], label %loop.preheader, label %main.pseudo.exit -; CHECK: loop: -; CHECK-NEXT: %idx = phi i32 [ %idx.next, %in.bounds ], [ 0, %loop.preheader ] -; CHECK-NEXT: %idx.next = add i32 %idx, 1 -; CHECK-NEXT: %abc = icmp ult i32 %idx, %exit.mainloop.at -; CHECK-NEXT: br i1 true, label %in.bounds, label %out.of.bounds.loopexit1 -; CHECK-NOT: loop.preloop: -; CHECK: loop.postloop: -; CHECK-NEXT: %idx.postloop = phi i32 [ %idx.copy, %postloop ], [ %idx.next.postloop, %in.bounds.postloop ] -; CHECK-NEXT: %idx.next.postloop = add i32 %idx.postloop, 1 -; CHECK-NEXT: %abc.postloop = icmp ult i32 %idx.postloop, %exit.mainloop.at -; CHECK-NEXT: br i1 %abc.postloop, label %in.bounds.postloop, label %out.of.bounds.loopexit - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, -100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -; Walking through the border of unsigned range is not allowed -; (iteration space [-100; 100)). Negative test. - -define void @test_09(i32* %arr, i32* %a_len_ptr) #0 { - -; CHECK: test_09 -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK-NOT: br i1 false -; CHECK-NOT: br i1 true - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - br label %loop - -loop: - %idx = phi i32 [ -100, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp ult i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds - -in.bounds: - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp ult i32 %idx.next, 100 - br i1 %next, label %loop, label %exit - -out.of.bounds: - ret void - -exit: - ret void -} - -!0 = !{i32 0, i32 50} diff --git a/llvm/test/Transforms/IRCE/variable-loop-bounds.ll b/llvm/test/Transforms/IRCE/variable-loop-bounds.ll deleted file mode 100644 index 5749b2c2d41..00000000000 --- a/llvm/test/Transforms/IRCE/variable-loop-bounds.ll +++ /dev/null @@ -1,354 +0,0 @@ -; RUN: opt -irce -S -verify-loop-info -irce-print-changed-loops -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s - -; CHECK: irce: in function test_inc_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> -; CHECK: irce: in function test_inc_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> -; CHECK: irce: in function test_inc_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> -; CHECK: irce: in function test_inc_ult: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> -; CHECK: irce: in function signed_var_imm_dec_sgt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> -; CHECK-NOT: irce: in function signed_var_imm_dec_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> -; CHECK: irce: in function signed_var_imm_dec_sge: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> -; CHECK: irce: in function signed_var_imm_dec_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> -; CHECK-NOT: irce: in function signed_var_imm_dec_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> - -; CHECK-LABEL: test_inc_eq( -; CHECK: main.exit.selector: -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N -; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit -define void @test_inc_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { -entry: - %cmp16 = icmp sgt i32 %N, 0 - br i1 %cmp16, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: - ret void - -for.body: - %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] - %cmp1 = icmp ult i32 %i.017, 512 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 - %1 = load i32, i32* %arrayidx2, align 4 - br i1 %cmp1, label %if.then, label %if.else - -if.then: - %sub = sub i32 %0, %1 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %sub, %2 - store i32 %add, i32* %arrayidx3, align 4 - br label %for.inc - -if.else: - %add6 = add nsw i32 %1, %0 - %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 - store i32 %add6, i32* %arrayidx7, align 4 - br label %for.inc - -for.inc: - %inc = add nuw nsw i32 %i.017, 1 - %exitcond = icmp eq i32 %inc, %N - br i1 %exitcond, label %for.cond.cleanup, label %for.body -} - -; CHECK-LABEL: test_inc_ne -; CHECK: main.exit.selector: -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N -; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit -define void @test_inc_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { -entry: - %cmp16 = icmp sgt i32 %N, 0 - br i1 %cmp16, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: - ret void - -for.body: - %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] - %cmp1 = icmp ult i32 %i.017, 512 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 - %1 = load i32, i32* %arrayidx2, align 4 - br i1 %cmp1, label %if.then, label %if.else - -if.then: - %sub = sub i32 %0, %1 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %sub, %2 - store i32 %add, i32* %arrayidx3, align 4 - br label %for.inc - -if.else: - %add6 = add nsw i32 %1, %0 - %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 - store i32 %add6, i32* %arrayidx7, align 4 - br label %for.inc - -for.inc: - %inc = add nuw nsw i32 %i.017, 1 - %exitcond = icmp ne i32 %inc, %N - br i1 %exitcond, label %for.body, label %for.cond.cleanup -} - -; CHECK-LABEL: test_inc_slt( -; CHECK: main.exit.selector: -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], %N -; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit -define void @test_inc_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { -entry: - %cmp16 = icmp sgt i32 %N, 0 - br i1 %cmp16, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: - ret void - -for.body: - %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] - %cmp1 = icmp ult i32 %i.017, 512 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 - %1 = load i32, i32* %arrayidx2, align 4 - br i1 %cmp1, label %if.then, label %if.else - -if.then: - %sub = sub i32 %0, %1 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %sub, %2 - store i32 %add, i32* %arrayidx3, align 4 - br label %for.inc - -if.else: - %add6 = add nsw i32 %1, %0 - %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 - store i32 %add6, i32* %arrayidx7, align 4 - br label %for.inc - -for.inc: - %inc = add nuw nsw i32 %i.017, 1 - %exitcond = icmp slt i32 %inc, %N - br i1 %exitcond, label %for.body, label %for.cond.cleanup -} - -; CHECK-LABEL: test_inc_ult -; CHECK: main.exit.selector: -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N -; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit -define void @test_inc_ult(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { -entry: - %cmp16 = icmp ugt i32 %N, 0 - br i1 %cmp16, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: - ret void - -for.body: - %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] - %cmp1 = icmp ult i32 %i.017, 512 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 - %1 = load i32, i32* %arrayidx2, align 4 - br i1 %cmp1, label %if.then, label %if.else - -if.then: - %sub = sub i32 %0, %1 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %sub, %2 - store i32 %add, i32* %arrayidx3, align 4 - br label %for.inc - -if.else: - %add6 = add nsw i32 %1, %0 - %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 - store i32 %add6, i32* %arrayidx7, align 4 - br label %for.inc - -for.inc: - %inc = add nuw nsw i32 %i.017, 1 - %exitcond = icmp ult i32 %inc, %N - br i1 %exitcond, label %for.body, label %for.cond.cleanup -} - -; CHECK-LABEL: signed_var_imm_dec_sgt( -; CHECK: main.exit.selector: -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M -; CHECK: br i1 [[COND]] -define void @signed_var_imm_dec_sgt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { -entry: - %cmp14 = icmp slt i32 %M, 1024 - br i1 %cmp14, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: ; preds = %for.inc, %entry - ret void - -for.body: ; preds = %entry, %for.inc - %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] - %cmp1 = icmp slt i32 %iv, 1024 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv - %1 = load i32, i32* %arrayidx2, align 4 - %mul = mul nsw i32 %1, %0 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv - br i1 %cmp1, label %for.inc, label %if.else - -if.else: ; preds = %for.body - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %2, %mul - br label %for.inc - -for.inc: ; preds = %for.body, %if.else - %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] - store i32 %storemerge, i32* %arrayidx3, align 4 - %dec = add nsw i32 %iv, -1 - %cmp = icmp sgt i32 %dec, %M - br i1 %cmp, label %for.body, label %for.cond.cleanup -} - -; CHECK-LABEL: signed_var_imm_dec_sge( -; CHECK: main.exit.selector: ; preds = %for.inc -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %iv, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M -; CHECK: br i1 [[COND]] -define void @signed_var_imm_dec_sge(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { -entry: - %cmp14 = icmp sgt i32 %M, 1024 - br i1 %cmp14, label %for.cond.cleanup, label %for.body - -for.cond.cleanup: ; preds = %for.inc, %entry - ret void - -for.body: ; preds = %entry, %for.inc - %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] - %cmp1 = icmp slt i32 %iv, 1024 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv - %1 = load i32, i32* %arrayidx2, align 4 - %mul = mul nsw i32 %1, %0 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv - br i1 %cmp1, label %for.inc, label %if.else - -if.else: ; preds = %for.body - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %2, %mul - br label %for.inc - -for.inc: ; preds = %for.body, %if.else - %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] - store i32 %storemerge, i32* %arrayidx3, align 4 - %dec = add nsw i32 %iv, -1 - %cmp = icmp sgt i32 %iv, %M - br i1 %cmp, label %for.body, label %for.cond.cleanup -} - -define void @signed_var_imm_dec_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { -entry: - %cmp14 = icmp sgt i32 %M, 1024 - br i1 %cmp14, label %for.cond.cleanup, label %for.body - -for.cond.cleanup: ; preds = %for.inc, %entry - ret void - -for.body: ; preds = %entry, %for.inc - %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] - %cmp1 = icmp slt i32 %iv, 1024 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv - %1 = load i32, i32* %arrayidx2, align 4 - %mul = mul nsw i32 %1, %0 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv - br i1 %cmp1, label %for.inc, label %if.else - -if.else: ; preds = %for.body - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %2, %mul - br label %for.inc - -for.inc: ; preds = %for.body, %if.else - %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] - store i32 %storemerge, i32* %arrayidx3, align 4 - %dec = add nsw i32 %iv, -1 - %cmp = icmp slt i32 %iv, %M - br i1 %cmp, label %for.cond.cleanup, label %for.body -} - -; CHECK-LABEL: signed_var_imm_dec_ne( -; CHECK: main.exit.selector: ; preds = %for.inc -; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ] -; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M -; CHECK: br i1 [[COND]] -define void @signed_var_imm_dec_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { -entry: - %cmp14 = icmp slt i32 %M, 1024 - br i1 %cmp14, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: ; preds = %for.inc, %entry - ret void - -for.body: ; preds = %entry, %for.inc - %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] - %cmp1 = icmp slt i32 %iv, 1024 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv - %1 = load i32, i32* %arrayidx2, align 4 - %mul = mul nsw i32 %1, %0 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv - br i1 %cmp1, label %for.inc, label %if.else - -if.else: ; preds = %for.body - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %2, %mul - br label %for.inc - -for.inc: ; preds = %for.body, %if.else - %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] - store i32 %storemerge, i32* %arrayidx3, align 4 - %dec = add nsw i32 %iv, -1 - %cmp = icmp ne i32 %dec, %M - br i1 %cmp, label %for.body, label %for.cond.cleanup -} - -define void @signed_var_imm_dec_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { -entry: - %cmp14 = icmp slt i32 %M, 1024 - br i1 %cmp14, label %for.body, label %for.cond.cleanup - -for.cond.cleanup: ; preds = %for.inc, %entry - ret void - -for.body: ; preds = %entry, %for.inc - %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] - %cmp1 = icmp slt i32 %iv, 1024 - %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv - %0 = load i32, i32* %arrayidx, align 4 - %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv - %1 = load i32, i32* %arrayidx2, align 4 - %mul = mul nsw i32 %1, %0 - %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv - br i1 %cmp1, label %for.inc, label %if.else - -if.else: ; preds = %for.body - %2 = load i32, i32* %arrayidx3, align 4 - %add = add nsw i32 %2, %mul - br label %for.inc - -for.inc: ; preds = %for.body, %if.else - %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] - store i32 %storemerge, i32* %arrayidx3, align 4 - %dec = add nsw i32 %iv, -1 - %cmp = icmp eq i32 %dec, %M - br i1 %cmp, label %for.cond.cleanup, label %for.body -} diff --git a/llvm/test/Transforms/IRCE/wide_indvar.ll b/llvm/test/Transforms/IRCE/wide_indvar.ll deleted file mode 100644 index 55580a10a6f..00000000000 --- a/llvm/test/Transforms/IRCE/wide_indvar.ll +++ /dev/null @@ -1,459 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s - -; Check that we can remove trivially non-failing range check. -define i32 @test_increasing_slt_slt_wide_simple_no_postloop() { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_no_postloop( -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp slt i64 %iv, 100 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp slt i32 %narrow.iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; This range check fails on the last iteration, so it needs a postloop. -define i32 @test_increasing_slt_slt_wide_simple_postloop() { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_postloop( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp slt i64 %wide.narrow.iv, 99 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp slt i64 %iv, 99 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp slt i32 %narrow.iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; General case. If both %N and %M are non-negative, we do not need a preloop. -define i32 @test_increasing_slt_slt_wide_non-negative(i32* %n_ptr, i64* %m_ptr) { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_non-negative( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp slt i64 %wide.narrow.iv, %exit.mainloop.at -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M = load i64, i64* %m_ptr, !range !1 - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp slt i64 %iv, %M - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp slt i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; General case. Even though %M may be negative, we do not need a preloop because -; we make a non-negativity runtime check against M and do not go to main loop if -; M was negative. -define i32 @test_increasing_slt_slt_wide_general(i32* %n_ptr, i64* %m_ptr) { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_general( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp slt i64 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M = load i64, i64* %m_ptr - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp slt i64 %iv, %M - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp slt i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; General case with preloop. -define i32 @test_increasing_slt_slt_wide_general_preloop(i32* %n_ptr, i64* %m_ptr) { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_general_preloop( -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp slt i64 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: preloop -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M = load i64, i64* %m_ptr - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp slt i64 %iv, %M - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv to i32 - %latch.cond = icmp slt i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; Same as above, multiple checks. -define i32 @test_increasing_slt_slt_wide_multiple_checks(i32* %n_ptr, i64* %m1_ptr, i64* %m2_ptr, i64* %m3_ptr, i64* %m4_ptr) { -; CHECK-LABEL: @test_increasing_slt_slt_wide_multiple_checks( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: %c1 = and i1 true, true -; CHECK: %c2 = and i1 %c1, true -; CHECK: %rc = and i1 %c2, true -; CHECK: br i1 %rc, label %backedge, label %check_failed.loopexit -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp slt i64 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M1 = load i64, i64* %m1_ptr - %M2 = load i64, i64* %m2_ptr - %M3 = load i64, i64* %m3_ptr - %M4 = load i64, i64* %m4_ptr - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp slt i64 %iv, %M1 - %rc2 = icmp slt i64 %iv, %M2 - %rc3 = icmp slt i64 %iv, %M3 - %rc4 = icmp slt i64 %iv, %M4 - %c1 = and i1 %rc1, %rc2 - %c2 = and i1 %c1, %rc3 - %rc = and i1 %c2, %rc4 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp slt i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; Wide IV against narrow range check. We don't currently support it. -define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() { - -; CHECK-LABEL: @test_increasing_slt_slt_wide_simple_negtest_narrow_rc( -; CHECK-NOT: i1 true -; CHECK-NOT: main - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %narrow.iv = trunc i64 %iv to i32 - %rc = icmp slt i32 %narrow.iv, 101 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %latch.cond = icmp slt i64 %iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; Check that we can remove trivially non-failing range check. -define i32 @test_increasing_ult_ult_wide_simple_no_postloop() { - -; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_no_postloop( -; CHECK-NOT: preloop -; CHECK-NOT: postloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp ult i64 %iv, 100 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp ult i32 %narrow.iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; This range check fails on the last iteration, so it needs a postloop. -define i32 @test_increasing_ult_ult_wide_simple_postloop() { - -; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_postloop( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp ult i64 %wide.narrow.iv, 99 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp ult i64 %iv, 99 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp ult i32 %narrow.iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; General case. If both %N and %M are non-negative, we do not need a preloop. -define i32 @test_increasing_ult_ult_wide_non-negative(i32* %n_ptr, i64* %m_ptr) { - -; CHECK-LABEL: @test_increasing_ult_ult_wide_non-negative( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp ult i64 %wide.narrow.iv, %exit.mainloop.at -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M = load i64, i64* %m_ptr, !range !1 - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp ult i64 %iv, %M - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp ult i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; General case. Even though %M may be negative, we do not need a preloop because -; we make a non-negativity runtime check against M and do not go to main loop if -; M was negative. -define i32 @test_increasing_ult_ult_wide_general(i32* %n_ptr, i64* %m_ptr) { - -; CHECK-LABEL: @test_increasing_ult_ult_wide_general( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: br i1 true, label %backedge, label %check_failed -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp ult i64 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M = load i64, i64* %m_ptr - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc = icmp ult i64 %iv, %M - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp ult i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; Same as above, multiple checks. -define i32 @test_increasing_ult_ult_wide_multiple_checks(i32* %n_ptr, i64* %m1_ptr, i64* %m2_ptr, i64* %m3_ptr, i64* %m4_ptr) { -; CHECK-LABEL: @test_increasing_ult_ult_wide_multiple_checks( -; CHECK-NOT: preloop -; CHECK: loop: -; CHECK: %c1 = and i1 true, true -; CHECK: %c2 = and i1 %c1, true -; CHECK: %rc = and i1 %c2, true -; CHECK: br i1 %rc, label %backedge, label %check_failed.loopexit -; CHECK: backedge -; CHECK: [[COND:%[^ ]+]] = icmp ult i64 -; CHECK: br i1 [[COND]], label %loop, label %main.exit.selector -; CHECK: postloop - -entry: - %N = load i32, i32* %n_ptr, !range !2 - %M1 = load i64, i64* %m1_ptr - %M2 = load i64, i64* %m2_ptr - %M3 = load i64, i64* %m3_ptr - %M4 = load i64, i64* %m4_ptr - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %rc1 = icmp ult i64 %iv, %M1 - %rc2 = icmp ult i64 %iv, %M2 - %rc3 = icmp ult i64 %iv, %M3 - %rc4 = icmp ult i64 %iv, %M4 - %c1 = and i1 %rc1, %rc2 - %c2 = and i1 %c1, %rc3 - %rc = and i1 %c2, %rc4 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %narrow.iv = trunc i64 %iv.next to i32 - %latch.cond = icmp ult i32 %narrow.iv, %N - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -; Wide IV against narrow range check. We don't currently support it. -define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() { - -; CHECK-LABEL: @test_increasing_ult_ult_wide_simple_negtest_narrow_rc( -; CHECK-NOT: i1 true -; CHECK-NOT: main - -entry: - br label %loop - -loop: - %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] - %narrow.iv = trunc i64 %iv to i32 - %rc = icmp ult i32 %narrow.iv, 101 - br i1 %rc, label %backedge, label %check_failed - -backedge: - %iv.next = add i64 %iv, 1 - %latch.cond = icmp ult i64 %iv, 100 - br i1 %latch.cond, label %loop, label %exit - -exit: - ret i32 %narrow.iv - -check_failed: - ret i32 -1 -} - -!0 = !{i32 0, i32 2147483647} -!1 = !{i64 0, i64 9223372036854775807} -!2 = !{i32 1, i32 2147483647} diff --git a/llvm/test/Transforms/IRCE/with-parent-loops.ll b/llvm/test/Transforms/IRCE/with-parent-loops.ll deleted file mode 100644 index 16c20b1948d..00000000000 --- a/llvm/test/Transforms/IRCE/with-parent-loops.ll +++ /dev/null @@ -1,346 +0,0 @@ -; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s -; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' < %s 2>&1 | FileCheck %s - -; This test checks if we update the LoopInfo correctly in the presence -; of parents, uncles and cousins. - -; Function Attrs: alwaysinline -define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 { -; CHECK: irce: in function inner_loop: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting> - -entry: - %len = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check = icmp sgt i32 %n, 0 - br i1 %first.itr.check, label %loop, label %exit - -loop: ; preds = %in.bounds, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ] - %idx.next = add i32 %idx, 1 - %abc = icmp slt i32 %idx, %len - br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1 - -in.bounds: ; preds = %loop - %addr = getelementptr i32, i32* %arr, i32 %idx - store i32 0, i32* %addr - %next = icmp slt i32 %idx.next, %n - br i1 %next, label %loop, label %exit - -out.of.bounds: ; preds = %loop - ret void - -exit: ; preds = %in.bounds, %entry - ret void -} - -; Function Attrs: alwaysinline -define void @with_parent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 { -; CHECK: irce: in function with_parent: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting> - -entry: - br label %loop - -loop: ; preds = %inner_loop.exit, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit ] - %idx.next = add i32 %idx, 1 - %next = icmp ult i32 %idx.next, %parent.count - %len.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i, label %loop.i, label %exit.i - -loop.i: ; preds = %in.bounds.i, %loop - %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ] - %idx.next.i = add i32 %idx.i, 1 - %abc.i = icmp slt i32 %idx.i, %len.i - br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1 - -in.bounds.i: ; preds = %loop.i - %addr.i = getelementptr i32, i32* %arr, i32 %idx.i - store i32 0, i32* %addr.i - %next.i = icmp slt i32 %idx.next.i, %n - br i1 %next.i, label %loop.i, label %exit.i - -out.of.bounds.i: ; preds = %loop.i - br label %inner_loop.exit - -exit.i: ; preds = %in.bounds.i, %loop - br label %inner_loop.exit - -inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i - br i1 %next, label %loop, label %exit - -exit: ; preds = %inner_loop.exit - ret void -} - -; Function Attrs: alwaysinline -define void @with_grandparent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 { -; CHECK: irce: in function with_grandparent: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting> - -entry: - br label %loop - -loop: ; preds = %with_parent.exit, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ] - %idx.next = add i32 %idx, 1 - %next = icmp ult i32 %idx.next, %grandparent.count - br label %loop.i - -loop.i: ; preds = %inner_loop.exit.i, %loop - %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ] - %idx.next.i = add i32 %idx.i, 1 - %next.i = icmp ult i32 %idx.next.i, %parent.count - %len.i.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i - -loop.i.i: ; preds = %in.bounds.i.i, %loop.i - %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ] - %idx.next.i.i = add i32 %idx.i.i, 1 - %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i - br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1 - -in.bounds.i.i: ; preds = %loop.i.i - %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i - store i32 0, i32* %addr.i.i - %next.i.i = icmp slt i32 %idx.next.i.i, %n - br i1 %next.i.i, label %loop.i.i, label %exit.i.i - -out.of.bounds.i.i: ; preds = %loop.i.i - br label %inner_loop.exit.i - -exit.i.i: ; preds = %in.bounds.i.i, %loop.i - br label %inner_loop.exit.i - -inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i - br i1 %next.i, label %loop.i, label %with_parent.exit - -with_parent.exit: ; preds = %inner_loop.exit.i - br i1 %next, label %loop, label %exit - -exit: ; preds = %with_parent.exit - ret void -} - -; Function Attrs: alwaysinline -define void @with_sibling(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 { -; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting> -; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i6<header><exiting>,%in.bounds.i9<latch><exiting> - -entry: - br label %loop - -loop: ; preds = %inner_loop.exit12, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit12 ] - %idx.next = add i32 %idx, 1 - %next = icmp ult i32 %idx.next, %parent.count - %len.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i, label %loop.i, label %exit.i - -loop.i: ; preds = %in.bounds.i, %loop - %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ] - %idx.next.i = add i32 %idx.i, 1 - %abc.i = icmp slt i32 %idx.i, %len.i - br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1 - -in.bounds.i: ; preds = %loop.i - %addr.i = getelementptr i32, i32* %arr, i32 %idx.i - store i32 0, i32* %addr.i - %next.i = icmp slt i32 %idx.next.i, %n - br i1 %next.i, label %loop.i, label %exit.i - -out.of.bounds.i: ; preds = %loop.i - br label %inner_loop.exit - -exit.i: ; preds = %in.bounds.i, %loop - br label %inner_loop.exit - -inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i - %len.i1 = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i2 = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i2, label %loop.i6, label %exit.i11 - -loop.i6: ; preds = %in.bounds.i9, %inner_loop.exit - %idx.i3 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i4, %in.bounds.i9 ] - %idx.next.i4 = add i32 %idx.i3, 1 - %abc.i5 = icmp slt i32 %idx.i3, %len.i1 - br i1 %abc.i5, label %in.bounds.i9, label %out.of.bounds.i10, !prof !1 - -in.bounds.i9: ; preds = %loop.i6 - %addr.i7 = getelementptr i32, i32* %arr, i32 %idx.i3 - store i32 0, i32* %addr.i7 - %next.i8 = icmp slt i32 %idx.next.i4, %n - br i1 %next.i8, label %loop.i6, label %exit.i11 - -out.of.bounds.i10: ; preds = %loop.i6 - br label %inner_loop.exit12 - -exit.i11: ; preds = %in.bounds.i9, %inner_loop.exit - br label %inner_loop.exit12 - -inner_loop.exit12: ; preds = %exit.i11, %out.of.bounds.i10 - br i1 %next, label %loop, label %exit - -exit: ; preds = %inner_loop.exit12 - ret void -} - -; Function Attrs: alwaysinline -define void @with_cousin(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 { -; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting> -; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i10<header><exiting>,%in.bounds.i.i13<latch><exiting> - -entry: - br label %loop - -loop: ; preds = %with_parent.exit17, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit17 ] - %idx.next = add i32 %idx, 1 - %next = icmp ult i32 %idx.next, %grandparent.count - br label %loop.i - -loop.i: ; preds = %inner_loop.exit.i, %loop - %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ] - %idx.next.i = add i32 %idx.i, 1 - %next.i = icmp ult i32 %idx.next.i, %parent.count - %len.i.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i - -loop.i.i: ; preds = %in.bounds.i.i, %loop.i - %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ] - %idx.next.i.i = add i32 %idx.i.i, 1 - %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i - br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1 - -in.bounds.i.i: ; preds = %loop.i.i - %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i - store i32 0, i32* %addr.i.i - %next.i.i = icmp slt i32 %idx.next.i.i, %n - br i1 %next.i.i, label %loop.i.i, label %exit.i.i - -out.of.bounds.i.i: ; preds = %loop.i.i - br label %inner_loop.exit.i - -exit.i.i: ; preds = %in.bounds.i.i, %loop.i - br label %inner_loop.exit.i - -inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i - br i1 %next.i, label %loop.i, label %with_parent.exit - -with_parent.exit: ; preds = %inner_loop.exit.i - br label %loop.i6 - -loop.i6: ; preds = %inner_loop.exit.i16, %with_parent.exit - %idx.i1 = phi i32 [ 0, %with_parent.exit ], [ %idx.next.i2, %inner_loop.exit.i16 ] - %idx.next.i2 = add i32 %idx.i1, 1 - %next.i3 = icmp ult i32 %idx.next.i2, %parent.count - %len.i.i4 = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i.i5 = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i.i5, label %loop.i.i10, label %exit.i.i15 - -loop.i.i10: ; preds = %in.bounds.i.i13, %loop.i6 - %idx.i.i7 = phi i32 [ 0, %loop.i6 ], [ %idx.next.i.i8, %in.bounds.i.i13 ] - %idx.next.i.i8 = add i32 %idx.i.i7, 1 - %abc.i.i9 = icmp slt i32 %idx.i.i7, %len.i.i4 - br i1 %abc.i.i9, label %in.bounds.i.i13, label %out.of.bounds.i.i14, !prof !1 - -in.bounds.i.i13: ; preds = %loop.i.i10 - %addr.i.i11 = getelementptr i32, i32* %arr, i32 %idx.i.i7 - store i32 0, i32* %addr.i.i11 - %next.i.i12 = icmp slt i32 %idx.next.i.i8, %n - br i1 %next.i.i12, label %loop.i.i10, label %exit.i.i15 - -out.of.bounds.i.i14: ; preds = %loop.i.i10 - br label %inner_loop.exit.i16 - -exit.i.i15: ; preds = %in.bounds.i.i13, %loop.i6 - br label %inner_loop.exit.i16 - -inner_loop.exit.i16: ; preds = %exit.i.i15, %out.of.bounds.i.i14 - br i1 %next.i3, label %loop.i6, label %with_parent.exit17 - -with_parent.exit17: ; preds = %inner_loop.exit.i16 - br i1 %next, label %loop, label %exit - -exit: ; preds = %with_parent.exit17 - ret void -} - -; Function Attrs: alwaysinline -define void @with_uncle(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 { -; CHECK: irce: in function with_uncle: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting> -; CHECK: irce: in function with_uncle: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting> - -entry: - br label %loop - -loop: ; preds = %with_parent.exit, %entry - %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ] - %idx.next = add i32 %idx, 1 - %next = icmp ult i32 %idx.next, %grandparent.count - %len.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i, label %loop.i, label %exit.i - -loop.i: ; preds = %in.bounds.i, %loop - %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ] - %idx.next.i = add i32 %idx.i, 1 - %abc.i = icmp slt i32 %idx.i, %len.i - br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1 - -in.bounds.i: ; preds = %loop.i - %addr.i = getelementptr i32, i32* %arr, i32 %idx.i - store i32 0, i32* %addr.i - %next.i = icmp slt i32 %idx.next.i, %n - br i1 %next.i, label %loop.i, label %exit.i - -out.of.bounds.i: ; preds = %loop.i - br label %inner_loop.exit - -exit.i: ; preds = %in.bounds.i, %loop - br label %inner_loop.exit - -inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i - br label %loop.i4 - -loop.i4: ; preds = %inner_loop.exit.i, %inner_loop.exit - %idx.i1 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i2, %inner_loop.exit.i ] - %idx.next.i2 = add i32 %idx.i1, 1 - %next.i3 = icmp ult i32 %idx.next.i2, %parent.count - %len.i.i = load i32, i32* %a_len_ptr, !range !0 - %first.itr.check.i.i = icmp sgt i32 %n, 0 - br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i - -loop.i.i: ; preds = %in.bounds.i.i, %loop.i4 - %idx.i.i = phi i32 [ 0, %loop.i4 ], [ %idx.next.i.i, %in.bounds.i.i ] - %idx.next.i.i = add i32 %idx.i.i, 1 - %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i - br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1 - -in.bounds.i.i: ; preds = %loop.i.i - %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i - store i32 0, i32* %addr.i.i - %next.i.i = icmp slt i32 %idx.next.i.i, %n - br i1 %next.i.i, label %loop.i.i, label %exit.i.i - -out.of.bounds.i.i: ; preds = %loop.i.i - br label %inner_loop.exit.i - -exit.i.i: ; preds = %in.bounds.i.i, %loop.i4 - br label %inner_loop.exit.i - -inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i - br i1 %next.i3, label %loop.i4, label %with_parent.exit - -with_parent.exit: ; preds = %inner_loop.exit.i - br i1 %next, label %loop, label %exit - -exit: ; preds = %with_parent.exit - ret void -} - -attributes #0 = { alwaysinline } - -!0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 64, i32 4} |