summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll')
-rw-r--r--llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll502
1 files changed, 0 insertions, 502 deletions
diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
deleted file mode 100644
index 333378a0984..00000000000
--- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
+++ /dev/null
@@ -1,502 +0,0 @@
-; Specifically exercise the cost modeling for non-trivial loop unswitching.
-;
-; RUN: opt -passes='loop(unswitch),verify<loops>' -enable-nontrivial-unswitch -unswitch-threshold=5 -S < %s | FileCheck %s
-; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -unswitch-threshold=5 -S < %s | FileCheck %s
-; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -unswitch-threshold=5 -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
-
-declare void @a()
-declare void @b()
-declare void @x()
-
-; First establish enough code size in the duplicated 'loop_begin' block to
-; suppress unswitching.
-define void @test_no_unswitch(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_no_unswitch(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label %loop_begin
-;
-; We shouldn't have unswitched into any other block either.
-; CHECK-NOT: br i1 %cond
-
-loop_begin:
- call void @x()
- call void @x()
- call void @x()
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- call void @a()
- br label %loop_latch
-
-loop_b:
- call void @b()
- br label %loop_latch
-
-loop_latch:
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-}
-
-; Now check that the smaller formulation of 'loop_begin' does in fact unswitch
-; with our low threshold.
-define void @test_unswitch(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_unswitch(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- call void @a()
- br label %loop_latch
-; The 'loop_a' unswitched loop.
-;
-; CHECK: entry.split.us:
-; CHECK-NEXT: br label %loop_begin.us
-;
-; CHECK: loop_begin.us:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_a.us
-;
-; CHECK: loop_a.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_latch.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us
-;
-; CHECK: loop_exit.split.us:
-; CHECK-NEXT: br label %loop_exit
-
-loop_b:
- call void @b()
- br label %loop_latch
-; The 'loop_b' unswitched loop.
-;
-; CHECK: entry.split:
-; CHECK-NEXT: br label %loop_begin
-;
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_b
-;
-; CHECK: loop_b:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: br label %loop_latch
-;
-; CHECK: loop_latch:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin, label %loop_exit.split
-;
-; CHECK: loop_exit.split:
-; CHECK-NEXT: br label %loop_exit
-
-loop_latch:
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-; CHECK: loop_exit:
-; CHECK-NEXT: ret void
-}
-
-; Check that even with large amounts of code on either side of the unswitched
-; branch, if that code would be kept in only one of the unswitched clones it
-; doesn't contribute to the cost.
-define void @test_unswitch_non_dup_code(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_unswitch_non_dup_code(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- call void @a()
- call void @a()
- call void @a()
- call void @a()
- br label %loop_latch
-; The 'loop_a' unswitched loop.
-;
-; CHECK: entry.split.us:
-; CHECK-NEXT: br label %loop_begin.us
-;
-; CHECK: loop_begin.us:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_a.us
-;
-; CHECK: loop_a.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_latch.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us
-;
-; CHECK: loop_exit.split.us:
-; CHECK-NEXT: br label %loop_exit
-
-loop_b:
- call void @b()
- call void @b()
- call void @b()
- call void @b()
- br label %loop_latch
-; The 'loop_b' unswitched loop.
-;
-; CHECK: entry.split:
-; CHECK-NEXT: br label %loop_begin
-;
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_b
-;
-; CHECK: loop_b:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: br label %loop_latch
-;
-; CHECK: loop_latch:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin, label %loop_exit.split
-;
-; CHECK: loop_exit.split:
-; CHECK-NEXT: br label %loop_exit
-
-loop_latch:
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-; CHECK: loop_exit:
-; CHECK-NEXT: ret void
-}
-
-; Much like with non-duplicated code directly in the successor, we also won't
-; duplicate even interesting CFGs.
-define void @test_unswitch_non_dup_code_in_cfg(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- %v1 = load i1, i1* %ptr
- br i1 %v1, label %loop_a_a, label %loop_a_b
-
-loop_a_a:
- call void @a()
- br label %loop_latch
-
-loop_a_b:
- call void @a()
- br label %loop_latch
-; The 'loop_a' unswitched loop.
-;
-; CHECK: entry.split.us:
-; CHECK-NEXT: br label %loop_begin.us
-;
-; CHECK: loop_begin.us:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_a.us
-;
-; CHECK: loop_a.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_a_a.us, label %loop_a_b.us
-;
-; CHECK: loop_a_b.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_a_a.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_latch.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us
-;
-; CHECK: loop_exit.split.us:
-; CHECK-NEXT: br label %loop_exit
-
-loop_b:
- %v2 = load i1, i1* %ptr
- br i1 %v2, label %loop_b_a, label %loop_b_b
-
-loop_b_a:
- call void @b()
- br label %loop_latch
-
-loop_b_b:
- call void @b()
- br label %loop_latch
-; The 'loop_b' unswitched loop.
-;
-; CHECK: entry.split:
-; CHECK-NEXT: br label %loop_begin
-;
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_b
-;
-; CHECK: loop_b:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_b_a, label %loop_b_b
-;
-; CHECK: loop_b_a:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: br label %loop_latch
-;
-; CHECK: loop_b_b:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: br label %loop_latch
-;
-; CHECK: loop_latch:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin, label %loop_exit.split
-;
-; CHECK: loop_exit.split:
-; CHECK-NEXT: br label %loop_exit
-
-loop_latch:
- %v3 = load i1, i1* %ptr
- br i1 %v3, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-; CHECK: loop_exit:
-; CHECK-NEXT: ret void
-}
-
-; Check that even if there is *some* non-duplicated code on one side of an
-; unswitch, we don't count any other code in the loop that will in fact have to
-; be duplicated.
-define void @test_no_unswitch_non_dup_code(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_no_unswitch_non_dup_code(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label %loop_begin
-;
-; We shouldn't have unswitched into any other block either.
-; CHECK-NOT: br i1 %cond
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- %v1 = load i1, i1* %ptr
- br i1 %v1, label %loop_a_a, label %loop_a_b
-
-loop_a_a:
- call void @a()
- br label %loop_latch
-
-loop_a_b:
- call void @a()
- br label %loop_latch
-
-loop_b:
- %v2 = load i1, i1* %ptr
- br i1 %v2, label %loop_b_a, label %loop_b_b
-
-loop_b_a:
- call void @b()
- br label %loop_latch
-
-loop_b_b:
- call void @b()
- br label %loop_latch
-
-loop_latch:
- call void @x()
- call void @x()
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-}
-
-; Check that we still unswitch when the exit block contains lots of code, even
-; though we do clone the exit block as part of unswitching. This should work
-; because we should split the exit block before anything inside it.
-define void @test_unswitch_large_exit(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_unswitch_large_exit(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b
-
-loop_a:
- call void @a()
- br label %loop_latch
-; The 'loop_a' unswitched loop.
-;
-; CHECK: entry.split.us:
-; CHECK-NEXT: br label %loop_begin.us
-;
-; CHECK: loop_begin.us:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_a.us
-;
-; CHECK: loop_a.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_latch.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us
-;
-; CHECK: loop_exit.split.us:
-; CHECK-NEXT: br label %loop_exit
-
-loop_b:
- call void @b()
- br label %loop_latch
-; The 'loop_b' unswitched loop.
-;
-; CHECK: entry.split:
-; CHECK-NEXT: br label %loop_begin
-;
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_b
-;
-; CHECK: loop_b:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: br label %loop_latch
-;
-; CHECK: loop_latch:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin, label %loop_exit.split
-;
-; CHECK: loop_exit.split:
-; CHECK-NEXT: br label %loop_exit
-
-loop_latch:
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- call void @x()
- call void @x()
- call void @x()
- call void @x()
- ret void
-; CHECK: loop_exit:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: ret void
-}
-
-; Check that we handle a dedicated exit edge unswitch which is still
-; non-trivial and has lots of code in the exit.
-define void @test_unswitch_dedicated_exiting(i1* %ptr, i1 %cond) {
-; CHECK-LABEL: @test_unswitch_dedicated_exiting(
-entry:
- br label %loop_begin
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
-
-loop_begin:
- call void @x()
- br i1 %cond, label %loop_a, label %loop_b_exit
-
-loop_a:
- call void @a()
- br label %loop_latch
-; The 'loop_a' unswitched loop.
-;
-; CHECK: entry.split.us:
-; CHECK-NEXT: br label %loop_begin.us
-;
-; CHECK: loop_begin.us:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_a.us
-;
-; CHECK: loop_a.us:
-; CHECK-NEXT: call void @a()
-; CHECK-NEXT: br label %loop_latch.us
-;
-; CHECK: loop_latch.us:
-; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr
-; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us
-;
-; CHECK: loop_exit.split.us:
-; CHECK-NEXT: br label %loop_exit
-
-loop_b_exit:
- call void @b()
- call void @b()
- call void @b()
- call void @b()
- ret void
-; The 'loop_b_exit' unswitched exit path.
-;
-; CHECK: entry.split:
-; CHECK-NEXT: br label %loop_begin
-;
-; CHECK: loop_begin:
-; CHECK-NEXT: call void @x()
-; CHECK-NEXT: br label %loop_b_exit
-;
-; CHECK: loop_b_exit:
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: call void @b()
-; CHECK-NEXT: ret void
-
-loop_latch:
- %v = load i1, i1* %ptr
- br i1 %v, label %loop_begin, label %loop_exit
-
-loop_exit:
- ret void
-; CHECK: loop_exit:
-; CHECK-NEXT: ret void
-}
OpenPOWER on IntegriCloud