diff options
Diffstat (limited to 'llvm/test/Transforms/GuardWidening/basic-loop.ll')
| -rw-r--r-- | llvm/test/Transforms/GuardWidening/basic-loop.ll | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/llvm/test/Transforms/GuardWidening/basic-loop.ll b/llvm/test/Transforms/GuardWidening/basic-loop.ll new file mode 100644 index 00000000000..8129a789f33 --- /dev/null +++ b/llvm/test/Transforms/GuardWidening/basic-loop.ll @@ -0,0 +1,138 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -loop-guard-widening < %s | FileCheck %s +; RUN: opt -S -passes="loop(guard-widening)" < %s | FileCheck %s + +declare void @llvm.experimental.guard(i1,...) + +@G = external global i32 + +; Show that we can widen into early checks within a loop, and in the process +; expose optimization oppurtunities. +define void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) { +; CHECK-LABEL: @widen_within_loop( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: store i32 0, i32* @G +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] +; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ] +; CHECK-NEXT: store i32 1, i32* @G +; CHECK-NEXT: store i32 2, i32* @G +; CHECK-NEXT: store i32 3, i32* @G +; CHECK-NEXT: br label [[LOOP]] +; +entry: + br label %loop + +loop: + store i32 0, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] + store i32 1, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ] + store i32 2, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] + store i32 3, i32* @G + br label %loop +} + +define void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) { +; CHECK-LABEL: @widen_into_preheader( +; CHECK-NEXT: entry: +; CHECK-NEXT: store i32 0, i32* @G +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] +; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: store i32 1, i32* @G +; CHECK-NEXT: store i32 2, i32* @G +; CHECK-NEXT: store i32 3, i32* @G +; CHECK-NEXT: br label [[LOOP]] +; +entry: + store i32 0, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] + br label %loop + +loop: + store i32 1, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ] + store i32 2, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] + store i32 3, i32* @G + br label %loop +} + +define void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) { +; CHECK-LABEL: @dont_widen_over_common_exit( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: store i32 0, i32* @G +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ] +; CHECK-NEXT: store i32 1, i32* @G +; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]] +; CHECK: backedge: +; CHECK-NEXT: store i32 2, i32* @G +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ] +; CHECK-NEXT: store i32 3, i32* @G +; CHECK-NEXT: br label [[LOOP]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + store i32 0, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] + store i32 1, i32* @G + br i1 %cond_1, label %backedge, label %exit + +backedge: + store i32 2, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] + store i32 3, i32* @G + br label %loop + +exit: + ret void +} + +define void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) { +; CHECK-LABEL: @widen_over_common_exit_to_ph( +; CHECK-NEXT: entry: +; CHECK-NEXT: store i32 0, i32* @G +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: store i32 1, i32* @G +; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]] +; CHECK: backedge: +; CHECK-NEXT: store i32 2, i32* @G +; CHECK-NEXT: store i32 3, i32* @G +; CHECK-NEXT: br label [[LOOP]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + store i32 0, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] + br label %loop + +loop: + store i32 1, i32* @G + br i1 %cond_1, label %backedge, label %exit + +backedge: + store i32 2, i32* @G + call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] + store i32 3, i32* @G + br label %loop + +exit: + ret void +} + |

