diff options
author | Stepan Dyatkovskiy <stpworld@narod.ru> | 2011-12-14 19:19:17 +0000 |
---|---|---|
committer | Stepan Dyatkovskiy <stpworld@narod.ru> | 2011-12-14 19:19:17 +0000 |
commit | ac12ef4ad22de941655c889f319a4c6923b77620 (patch) | |
tree | 89457c1e92f9aebe82a0b83dfbed493d5a05dcdf /test | |
parent | f9096e450bb6047ab330c94749f5e80178a62b09 (diff) |
Fix for bug #11429: Wrong behaviour for switches. Small improvement for code size heuristics.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
3 files changed, 313 insertions, 0 deletions
diff --git a/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll new file mode 100644 index 0000000000..8389fe4643 --- /dev/null +++ b/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll @@ -0,0 +1,91 @@ +; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s +; RUN: opt -S -loop-unswitch -verify-loop-info -verify-dom-info %s | FileCheck %s + +; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted +; STATS: 2 loop-unswitch - Number of switches unswitched + +; CHECK: %1 = icmp eq i32 %c, 1 +; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge + +; CHECK: ..split_crit_edge: ; preds = %0 +; CHECK-NEXT: br label %.split + +; CHECK: .split.us: ; preds = %0 +; CHECK-NEXT: br label %loop_begin.us + +; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us +; CHECK-NEXT: %var_val.us = load i32* %var +; CHECK-NEXT: switch i32 1, label %default.us-lcssa.us [ +; CHECK-NEXT: i32 1, label %inc.us + +; CHECK: inc.us: ; preds = %loop_begin.us +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us + +; CHECK: .split: ; preds = %..split_crit_edge +; CHECK-NEXT: %2 = icmp eq i32 %c, 2 +; CHECK-NEXT: br i1 %2, label %.split.split.us, label %.split..split.split_crit_edge + +; CHECK: .split..split.split_crit_edge: ; preds = %.split +; CHECK-NEXT: br label %.split.split + +; CHECK: .split.split.us: ; preds = %.split +; CHECK-NEXT: br label %loop_begin.us1 + +; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us5, %.split.split.us +; CHECK-NEXT: %var_val.us2 = load i32* %var +; CHECK-NEXT: switch i32 2, label %default.us-lcssa.us-lcssa.us [ +; CHECK-NEXT: i32 1, label %inc.us3 +; CHECK-NEXT: i32 2, label %dec.us4 +; CHECK-NEXT: ] + +; CHECK: dec.us4: ; preds = %loop_begin.us1 +; CHECK-NEXT: call void @decf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us5 + +; CHECK: .split.split: ; preds = %.split..split.split_crit_edge +; CHECK-NEXT: br label %loop_begin + +; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split +; CHECK-NEXT: %var_val = load i32* %var +; CHECK-NEXT: switch i32 %c, label %default.us-lcssa.us-lcssa [ +; CHECK-NEXT: i32 1, label %inc +; CHECK-NEXT: i32 2, label %dec +; CHECK-NEXT: ] + +; CHECK: inc: ; preds = %loop_begin +; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc.split + +; CHECK: dec: ; preds = %loop_begin +; CHECK-NEXT: br i1 true, label %us-unreachable6, label %dec.split + +define i32 @test(i32* %var) { + %mem = alloca i32 + store i32 2, i32* %mem + %c = load i32* %mem + + br label %loop_begin + +loop_begin: + + %var_val = load i32* %var + + switch i32 %c, label %default [ + i32 1, label %inc + i32 2, label %dec + ] + +inc: + call void @incf() noreturn nounwind + br label %loop_begin +dec: + call void @decf() noreturn nounwind + br label %loop_begin +default: + br label %loop_exit +loop_exit: + ret i32 0 +} + +declare void @incf() noreturn +declare void @decf() noreturn diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll new file mode 100644 index 0000000000..21c0ec3e22 --- /dev/null +++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll @@ -0,0 +1,84 @@ +; RUN: opt -loop-unswitch -loop-unswitch-threshold 30 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s +; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 30 -verify-loop-info -verify-dom-info %s | FileCheck %s + +; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted +; STATS: 1 loop-unswitch - Number of switches unswitched + +; ModuleID = '../llvm/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll' + +; CHECK: %1 = icmp eq i32 %c, 1 +; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge + +; CHECK: ..split_crit_edge: ; preds = %0 +; CHECK-NEXT: br label %.split + +; CHECK: .split.us: ; preds = %0 +; CHECK-NEXT: br label %loop_begin.us + +; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us +; CHECK: switch i32 1, label %second_switch.us [ +; CHECK-NEXT: i32 1, label %inc.us + +; CHECK: inc.us: ; preds = %second_switch.us, %loop_begin.us +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us + +; CHECK: second_switch.us: ; preds = %loop_begin.us +; CHECK-NEXT: switch i32 %d, label %default.us [ +; CHECK-NEXT: i32 1, label %inc.us +; CHECK-NEXT: ] + +; CHECK: .split: ; preds = %..split_crit_edge +; CHECK-NEXT: br label %loop_begin + +; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split +; CHECK: switch i32 %c, label %second_switch [ +; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge +; CHECK-NEXT: ] + +; CHECK: loop_begin.inc_crit_edge: ; preds = %loop_begin +; CHECK-NEXT: br i1 true, label %us-unreachable, label %inc + +; CHECK: second_switch: ; preds = %loop_begin +; CHECK-NEXT: switch i32 %d, label %default [ +; CHECK-NEXT: i32 1, label %inc +; CHECK-NEXT: ] + +; CHECK: inc: ; preds = %loop_begin.inc_crit_edge, %second_switch +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge + +define i32 @test(i32* %var) { + %mem = alloca i32 + store i32 2, i32* %mem + %c = load i32* %mem + %d = load i32* %mem + + br label %loop_begin + +loop_begin: + + %var_val = load i32* %var + + switch i32 %c, label %second_switch [ + i32 1, label %inc + ] + +second_switch: + switch i32 %d, label %default [ + i32 1, label %inc + ] + +inc: + call void @incf() noreturn nounwind + br label %loop_begin + +default: + br label %loop_begin + +loop_exit: + ret i32 0 +} + +declare void @incf() noreturn +declare void @decf() noreturn diff --git a/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll new file mode 100644 index 0000000000..1b186d6bec --- /dev/null +++ b/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches.ll @@ -0,0 +1,138 @@ +; RUN: opt -loop-unswitch -loop-unswitch-threshold 1000 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s +; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 1000 -verify-loop-info -verify-dom-info %s | FileCheck %s + +; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted +; STATS: 3 loop-unswitch - Number of switches unswitched + +; CHECK: %1 = icmp eq i32 %c, 1 +; CHECK-NEXT: br i1 %1, label %.split.us, label %..split_crit_edge + +; CHECK: ..split_crit_edge: ; preds = %0 +; CHECK-NEXT: br label %.split + +; CHECK: .split.us: ; preds = %0 +; CHECK-NEXT: %2 = icmp eq i32 %d, 1 +; CHECK-NEXT: br i1 %2, label %.split.us.split.us, label %.split.us..split.us.split_crit_edge + +; CHECK: .split.us..split.us.split_crit_edge: ; preds = %.split.us +; CHECK-NEXT: br label %.split.us.split + +; CHECK: .split.us.split.us: ; preds = %.split.us +; CHECK-NEXT: br label %loop_begin.us.us + +; CHECK: loop_begin.us.us: ; preds = %loop_begin.backedge.us.us, %.split.us.split.us +; CHECK-NEXT: %var_val.us.us = load i32* %var +; CHECK-NEXT: switch i32 1, label %second_switch.us.us [ +; CHECK-NEXT: i32 1, label %inc.us.us + +; CHECK: inc.us.us: ; preds = %second_switch.us.us, %loop_begin.us.us +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us.us + +; CHECK: second_switch.us.us: ; preds = %loop_begin.us.us +; CHECK-NEXT: switch i32 1, label %default.us.us [ +; CHECK-NEXT: i32 1, label %inc.us.us + +; CHECK: .split.us.split: ; preds = %.split.us..split.us.split_crit_edge +; CHECK-NEXT: br label %loop_begin.us + +; CHECK: loop_begin.us: ; preds = %loop_begin.backedge.us, %.split.us.split +; CHECK-NEXT: %var_val.us = load i32* %var +; CHECK-NEXT: switch i32 1, label %second_switch.us [ +; CHECK-NEXT: i32 1, label %inc.us + +; CHECK: inc.us: ; preds = %second_switch.us.inc.us_crit_edge, %loop_begin.us +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us + +; CHECK: second_switch.us: ; preds = %loop_begin.us +; CHECK-NEXT: switch i32 %d, label %default.us [ +; CHECK-NEXT: i32 1, label %second_switch.us.inc.us_crit_edge +; CHECK-NEXT: ] + +; CHECK: second_switch.us.inc.us_crit_edge: ; preds = %second_switch.us +; CHECK-NEXT: br i1 true, label %us-unreachable8, label %inc.us + +; CHECK: .split: ; preds = %..split_crit_edge +; CHECK-NEXT: %3 = icmp eq i32 %d, 1 +; CHECK-NEXT: br i1 %3, label %.split.split.us, label %.split..split.split_crit_edge + +; CHECK: .split..split.split_crit_edge: ; preds = %.split +; CHECK-NEXT: br label %.split.split + +; CHECK: .split.split.us: ; preds = %.split +; CHECK-NEXT: br label %loop_begin.us1 + +; CHECK: loop_begin.us1: ; preds = %loop_begin.backedge.us6, %.split.split.us +; CHECK-NEXT: %var_val.us2 = load i32* %var +; CHECK-NEXT: switch i32 %c, label %second_switch.us4 [ +; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge.us +; CHECK-NEXT: ] + +; CHECK: inc.us3: ; preds = %loop_begin.inc_crit_edge.us, %second_switch.us4 +; CHECK-NEXT: call void @incf() noreturn nounwind +; CHECK-NEXT: br label %loop_begin.backedge.us6 + +; CHECK: second_switch.us4: ; preds = %loop_begin.us1 +; CHECK-NEXT: switch i32 1, label %default.us5 [ +; CHECK-NEXT: i32 1, label %inc.us3 +; CHECK-NEXT: ] + +; CHECK: loop_begin.inc_crit_edge.us: ; preds = %loop_begin.us1 +; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa.us, label %inc.us3 + +; CHECK: .split.split: ; preds = %.split..split.split_crit_edge +; CHECK-NEXT: br label %loop_begin + +; CHECK: loop_begin: ; preds = %loop_begin.backedge, %.split.split +; CHECK-NEXT: %var_val = load i32* %var +; CHECK-NEXT: switch i32 %c, label %second_switch [ +; CHECK-NEXT: i32 1, label %loop_begin.inc_crit_edge +; CHECK-NEXT: ] + +; CHECK: loop_begin.inc_crit_edge: ; preds = %loop_begin +; CHECK-NEXT: br i1 true, label %us-unreachable.us-lcssa, label %inc + +; CHECK: second_switch: ; preds = %loop_begin +; CHECK-NEXT: switch i32 %d, label %default [ +; CHECK-NEXT: i32 1, label %second_switch.inc_crit_edge +; CHECK-NEXT: ] + +; CHECK: second_switch.inc_crit_edge: ; preds = %second_switch +; CHECK-NEXT: br i1 true, label %us-unreachable7, label %inc + + +define i32 @test(i32* %var) { + %mem = alloca i32 + store i32 2, i32* %mem + %c = load i32* %mem + %d = load i32* %mem + + br label %loop_begin + +loop_begin: + + %var_val = load i32* %var + + switch i32 %c, label %second_switch [ + i32 1, label %inc + ] + +second_switch: + switch i32 %d, label %default [ + i32 1, label %inc + ] + +inc: + call void @incf() noreturn nounwind + br label %loop_begin + +default: + br label %loop_begin + +loop_exit: + ret i32 0 +} + +declare void @incf() noreturn +declare void @decf() noreturn |