diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-08-26 23:56:46 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-08-26 23:56:46 +0000 |
| commit | 98a2dabc08fd89375f3af4158eb55575be58f13c (patch) | |
| tree | fd49a855569c92ec67de35a095dd28fe9f9f143d /llvm/test/Transforms/SimplifyCFG | |
| parent | a06c7e6da7f7367103d5522617cceb2525f2b431 (diff) | |
| download | bcm5719-llvm-98a2dabc08fd89375f3af4158eb55575be58f13c.tar.gz bcm5719-llvm-98a2dabc08fd89375f3af4158eb55575be58f13c.zip | |
[SimplifyCFG] Prune code from a provably unreachable switch default
As Sanjoy pointed out over in http://reviews.llvm.org/D11819, a switch on an icmp should always be able to become a branch instruction. This patch generalizes that notion slightly to prove that the default case of a switch is unreachable if the cases completely cover all possible bit patterns in the condition. Once that's done, the switch to branch conversion kicks in just fine.
Note: Duplicate case values are disallowed by the LangRef and verifier.
Differential Revision: http://reviews.llvm.org/D11995
llvm-svn: 246125
Diffstat (limited to 'llvm/test/Transforms/SimplifyCFG')
| -rw-r--r-- | llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll b/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll new file mode 100644 index 00000000000..b54ea881d8b --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/switch-dead-default.ll @@ -0,0 +1,87 @@ +; RUN: opt %s -S -simplifycfg | FileCheck %s +declare void @foo(i32) + +define void @test(i1 %a) { +; CHECK-LABEL @test +; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false + switch i1 %a, label %default [i1 1, label %true + i1 0, label %false] +true: + call void @foo(i32 1) + ret void +false: + call void @foo(i32 3) + ret void +default: + call void @foo(i32 2) + ret void +} + +define void @test2(i2 %a) { +; CHECK-LABEL @test2 + switch i2 %a, label %default [i2 0, label %case0 + i2 1, label %case1 + i2 2, label %case2 + i2 3, label %case3] +case0: + call void @foo(i32 0) + ret void +case1: + call void @foo(i32 1) + ret void +case2: + call void @foo(i32 2) + ret void +case3: + call void @foo(i32 3) + ret void +default: +; CHECK-LABEL: default1: +; CHECK-NEXT: unreachable + call void @foo(i32 4) + ret void +} + +; This one is a negative test - we know the value of the default, +; but that's about it +define void @test3(i2 %a) { +; CHECK-LABEL @test3 + switch i2 %a, label %default [i2 0, label %case0 + i2 1, label %case1 + i2 2, label %case2] + +case0: + call void @foo(i32 0) + ret void +case1: + call void @foo(i32 1) + ret void +case2: + call void @foo(i32 2) + ret void +default: +; CHECK-LABEL: default: +; CHECK-NEXT: call void @foo + call void @foo(i32 0) + ret void +} + +; Negative test - check for possible overflow when computing +; number of possible cases. +define void @test4(i128 %a) { +; CHECK-LABEL @test4 + switch i128 %a, label %default [i128 0, label %case0 + i128 1, label %case1] + +case0: + call void @foo(i32 0) + ret void +case1: + call void @foo(i32 1) + ret void +default: +; CHECK-LABEL: default: +; CHECK-NEXT: call void @foo + call void @foo(i32 0) + ret void +} |

