[PATCH] D11995: [SimplifyCFG] Prune code from a provably unreachable switch default

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 17:32:57 PDT 2015


reames updated this revision to Diff 32010.
reames added a comment.

Revised per review comments.


http://reviews.llvm.org/D11995

Files:
  lib/Transforms/Utils/SimplifyCFG.cpp
  test/Transforms/SimplifyCFG/switch-dead-default.ll

Index: test/Transforms/SimplifyCFG/switch-dead-default.ll
===================================================================
--- test/Transforms/SimplifyCFG/switch-dead-default.ll
+++ test/Transforms/SimplifyCFG/switch-dead-default.ll
@@ -0,0 +1,67 @@
+; 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
+}  
Index: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyCFG.cpp
+++ lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3248,6 +3248,23 @@
     }
   }
 
+  // If we can prove that the cases must cover all possible values, the 
+  // default destination becomes dead and we can remove it.
+  bool HasDefault =
+    !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
+  if (HasDefault && Bits < 64 /* avoid overflow */ &&  
+      SI->getNumCases() == (1ULL << Bits)) {
+    DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n");
+    BasicBlock *NewDefault = SplitBlockPredecessors(SI->getDefaultDest(),
+                                                    SI->getParent(), "");
+    SI->setDefaultDest(NewDefault);
+    SplitBlock(NewDefault, NewDefault->begin());
+    auto *OldTI = NewDefault->getTerminator();
+    new UnreachableInst(SI->getContext(), OldTI);
+    EraseTerminatorInstAndDCECond(OldTI);
+    return true;
+  }
+
   SmallVector<uint64_t, 8> Weights;
   bool HasWeight = HasBranchWeights(SI);
   if (HasWeight) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11995.32010.patch
Type: text/x-patch
Size: 2898 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150813/9f5a2ef1/attachment.bin>


More information about the llvm-commits mailing list