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/GuardWidening/basic.ll | |
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/GuardWidening/basic.ll')
-rw-r--r-- | llvm/test/Transforms/GuardWidening/basic.ll | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/llvm/test/Transforms/GuardWidening/basic.ll b/llvm/test/Transforms/GuardWidening/basic.ll deleted file mode 100644 index ab18ed7362a..00000000000 --- a/llvm/test/Transforms/GuardWidening/basic.ll +++ /dev/null @@ -1,407 +0,0 @@ -; RUN: opt -S -guard-widening < %s | FileCheck %s -; RUN: opt -S -passes=guard-widening < %s | FileCheck %s - -declare void @llvm.experimental.guard(i1,...) - -; Basic test case: we wide the first check to check both the -; conditions. -define void @f_0(i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_0( -entry: -; CHECK: %wide.chk = and i1 %cond_0, %cond_1 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: ret void - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void -} - -; Same as @f_0, but with using a more general notion of postdominance. -define void @f_1(i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_1( -entry: -; CHECK: %wide.chk = and i1 %cond_0, %cond_1 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: - br label %merge - -right: - br label %merge - -merge: -; CHECK: merge: -; CHECK-NOT: call void (i1, ...) @llvm.experimental.guard( -; CHECK: ret void - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void -} - -; Like @f_1, but we have some code we need to hoist before we can -; widen a dominanting check. -define void @f_2(i32 %a, i32 %b) { -; CHECK-LABEL: @f_2( -entry: -; CHECK: %cond_0 = icmp ult i32 %a, 10 -; CHECK: %cond_1 = icmp ult i32 %b, 10 -; CHECK: %wide.chk = and i1 %cond_0, %cond_1 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_0 = icmp ult i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: - br label %merge - -right: - br label %merge - -merge: - %cond_1 = icmp ult i32 %b, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void -} - -; Negative test: don't hoist stuff out of control flow -; indiscriminately, since that can make us do more work than needed. -define void @f_3(i32 %a, i32 %b) { -; CHECK-LABEL: @f_3( -entry: -; CHECK: %cond_0 = icmp ult i32 %a, 10 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_0 = icmp ult i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: -; CHECK: left: -; CHECK: %cond_1 = icmp ult i32 %b, 10 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] -; CHECK: ret void - - %cond_1 = icmp ult i32 %b, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void - -right: - ret void -} - -; But hoisting out of control flow is fine if it makes a loop computed -; condition loop invariant. This behavior may require some tuning in -; the future. -define void @f_4(i32 %a, i32 %b) { -; CHECK-LABEL: @f_4( -entry: -; CHECK: %cond_0 = icmp ult i32 %a, 10 -; CHECK: %cond_1 = icmp ult i32 %b, 10 -; CHECK: %wide.chk = and i1 %cond_0, %cond_1 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %loop, label %leave - - %cond_0 = icmp ult i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %loop, label %leave - -loop: - %cond_1 = icmp ult i32 %b, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - br i1 undef, label %loop, label %leave - -leave: - ret void -} - -; Hoisting out of control flow is also fine if we can widen the -; dominating check without doing any extra work. -define void @f_5(i32 %a) { -; CHECK-LABEL: @f_5( -entry: -; CHECK: %wide.chk = icmp uge i32 %a, 11 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_0 = icmp ugt i32 %a, 7 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: - %cond_1 = icmp ugt i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void - -right: - ret void -} - -; Negative test: the load from %a can be safely speculated to before -; the first guard, but there is no guarantee that it will produce the -; same value. -define void @f_6(i1* dereferenceable(32) %a, i1* %b, i1 %unknown) { -; CHECK-LABEL: @f_6( -; CHECK: call void (i1, ...) @llvm.experimental.guard( -; CHECK: call void (i1, ...) @llvm.experimental.guard( -; CHECK: ret void -entry: - %cond_0 = load i1, i1* %a - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - store i1 %unknown, i1* %b - %cond_1 = load i1, i1* %a - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void -} - -; All else equal, we try to widen the earliest guard we can. This -; heuristic can use some tuning. -define void @f_7(i32 %a, i1* %cond_buf) { -; CHECK-LABEL: @f_7( -entry: -; CHECK: %cond_1 = load volatile i1, i1* %cond_buf -; CHECK: %cond_3 = icmp ult i32 %a, 7 -; CHECK: %wide.chk = and i1 %cond_1, %cond_3 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: %cond_2 = load volatile i1, i1* %cond_buf -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_1 = load volatile i1, i1* %cond_buf - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - %cond_2 = load volatile i1, i1* %cond_buf - call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: - %cond_3 = icmp ult i32 %a, 7 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ] - br label %left - -right: - ret void -} - -; In this case the earliest dominating guard is in a loop, and we -; don't want to put extra work in there. This heuristic can use some -; tuning. -define void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) { -; CHECK-LABEL: @f_8( -entry: - br label %loop - -loop: - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - br i1 undef, label %loop, label %leave - -leave: -; CHECK: leave: -; CHECK: %cond_3 = icmp ult i32 %a, 7 -; CHECK: %wide.chk = and i1 %cond_2, %cond_3 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %loop2, label %leave2 - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ] - br i1 undef, label %loop2, label %leave2 - -loop2: - %cond_3 = icmp ult i32 %a, 7 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ] - br label %loop2 - -leave2: - ret void -} - -; In cases like these where there isn't any "obviously profitable" -; widening sites, we refuse to do anything. -define void @f_9(i32 %a, i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_9( -entry: - br label %first_loop - -first_loop: -; CHECK: first_loop: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: br i1 undef, label %first_loop, label %second_loop - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %first_loop, label %second_loop - -second_loop: -; CHECK: second_loop: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] -; CHECK: br label %second_loop - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - br label %second_loop -} - -; Same situation as in @f_9: no "obviously profitable" widening sites, -; so we refuse to do anything. -define void @f_10(i32 %a, i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_10( -entry: - br label %loop - -loop: -; CHECK: loop: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: br i1 undef, label %loop, label %no_loop - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %loop, label %no_loop - -no_loop: -; CHECK: no_loop: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] -; CHECK: ret void - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void -} - -; With guards in loops, we're okay hoisting out the guard into the -; containing loop. -define void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_11( -entry: - br label %inner - -inner: -; CHECK: inner: -; CHECK: %wide.chk = and i1 %cond_0, %cond_1 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %inner, label %outer - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %inner, label %outer - -outer: - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - br label %inner -} - -; Checks that we are adequately guarded against exponential-time -; behavior when hoisting code. -define void @f_12(i32 %a0) { -; CHECK-LABEL: @f_12 - -; Eliding the earlier 29 multiplications for brevity -; CHECK: %a30 = mul i32 %a29, %a29 -; CHECK-NEXT: %cond = trunc i32 %a30 to i1 -; CHECK-NEXT: %wide.chk = and i1 true, %cond -; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK-NEXT: ret void - -entry: - call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] - %a1 = mul i32 %a0, %a0 - %a2 = mul i32 %a1, %a1 - %a3 = mul i32 %a2, %a2 - %a4 = mul i32 %a3, %a3 - %a5 = mul i32 %a4, %a4 - %a6 = mul i32 %a5, %a5 - %a7 = mul i32 %a6, %a6 - %a8 = mul i32 %a7, %a7 - %a9 = mul i32 %a8, %a8 - %a10 = mul i32 %a9, %a9 - %a11 = mul i32 %a10, %a10 - %a12 = mul i32 %a11, %a11 - %a13 = mul i32 %a12, %a12 - %a14 = mul i32 %a13, %a13 - %a15 = mul i32 %a14, %a14 - %a16 = mul i32 %a15, %a15 - %a17 = mul i32 %a16, %a16 - %a18 = mul i32 %a17, %a17 - %a19 = mul i32 %a18, %a18 - %a20 = mul i32 %a19, %a19 - %a21 = mul i32 %a20, %a20 - %a22 = mul i32 %a21, %a21 - %a23 = mul i32 %a22, %a22 - %a24 = mul i32 %a23, %a23 - %a25 = mul i32 %a24, %a24 - %a26 = mul i32 %a25, %a25 - %a27 = mul i32 %a26, %a26 - %a28 = mul i32 %a27, %a27 - %a29 = mul i32 %a28, %a28 - %a30 = mul i32 %a29, %a29 - %cond = trunc i32 %a30 to i1 - call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] - ret void -} - -define void @f_13(i32 %a) { -; CHECK-LABEL: @f_13( -entry: -; CHECK: %wide.chk = icmp ult i32 %a, 10 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_0 = icmp ult i32 %a, 14 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: - %cond_1 = icmp slt i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void - -right: - ret void -} - -define void @f_14(i32 %a) { -; CHECK-LABEL: @f_14( -entry: -; CHECK: %cond_0 = icmp ult i32 %a, 14 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: br i1 undef, label %left, label %right - - %cond_0 = icmp ult i32 %a, 14 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - br i1 undef, label %left, label %right - -left: -; CHECK: left: -; CHECK: %cond_1 = icmp sgt i32 %a, 10 -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - - %cond_1 = icmp sgt i32 %a, 10 - call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ] - ret void - -right: - ret void -} - -; Make sure we do not widen guard by trivial true conditions into something. -define void @f_15(i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_15( -entry: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] -; CHECK: ret void - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] - ret void -} - -; Make sure we do not widen guard by trivial false conditions into something. -define void @f_16(i1 %cond_0, i1 %cond_1) { -; CHECK-LABEL: @f_16( -entry: -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] -; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] -; CHECK: ret void - - call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ] - call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] - ret void -} |