[llvm] 831636b - [SimplifyCFG] SUCCESS! Teach createUnreachableSwitchDefault() to preserve DomTree

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 31 16:26:12 PST 2020


Author: Roman Lebedev
Date: 2021-01-01T03:25:25+03:00
New Revision: 831636b0e6321500fd7bf3f32e8663369152a956

URL: https://github.com/llvm/llvm-project/commit/831636b0e6321500fd7bf3f32e8663369152a956
DIFF: https://github.com/llvm/llvm-project/commit/831636b0e6321500fd7bf3f32e8663369152a956.diff

LOG: [SimplifyCFG] SUCCESS! Teach createUnreachableSwitchDefault() to preserve DomTree

This pretty much concludes patch series for updating SimplifyCFG
to preserve DomTree. All 318 dedicated `-simplifycfg` tests now pass
with `-simplifycfg-require-and-preserve-domtree=1`.

There are a few leftovers that apparently don't have good test coverage.
I do not yet know what gaps in test coverage will the wider-scale testing
reveal, but the default flip might be close.

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index f513db3783fb..53353cd5e923 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4783,15 +4783,29 @@ static bool CasesAreContiguous(SmallVectorImpl<ConstantInt *> &Cases) {
   return true;
 }
 
-static void createUnreachableSwitchDefault(SwitchInst *Switch) {
+static void createUnreachableSwitchDefault(SwitchInst *Switch,
+                                           DomTreeUpdater *DTU) {
   LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n");
+  auto *BB = Switch->getParent();
   BasicBlock *NewDefaultBlock =
-     SplitBlockPredecessors(Switch->getDefaultDest(), Switch->getParent(), "");
+      SplitBlockPredecessors(Switch->getDefaultDest(), Switch->getParent(), "",
+                             DTU ? &DTU->getDomTree() : nullptr);
+  auto *OrigDefaultBlock = Switch->getDefaultDest();
   Switch->setDefaultDest(&*NewDefaultBlock);
-  SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front());
+  if (DTU)
+    DTU->applyUpdatesPermissive(
+        {{DominatorTree::Delete, BB, OrigDefaultBlock},
+         {DominatorTree::Insert, BB, &*NewDefaultBlock}});
+  SplitBlock(&*NewDefaultBlock, &NewDefaultBlock->front(),
+             DTU ? &DTU->getDomTree() : nullptr);
+  SmallVector<DominatorTree::UpdateType, 2> Updates;
+  for (auto *Successor : successors(NewDefaultBlock))
+    Updates.push_back({DominatorTree::Delete, NewDefaultBlock, Successor});
   auto *NewTerminator = NewDefaultBlock->getTerminator();
   new UnreachableInst(Switch->getContext(), NewTerminator);
   EraseTerminatorAndDCECond(NewTerminator);
+  if (DTU)
+    DTU->applyUpdatesPermissive(Updates);
 }
 
 /// Turn a switch with two reachable destinations into an integer range
@@ -4803,6 +4817,8 @@ bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI,
   bool HasDefault =
       !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
 
+  auto *BB = SI->getParent();
+
   // Partition the cases into two sets with 
diff erent destinations.
   BasicBlock *DestA = HasDefault ? SI->getDefaultDest() : nullptr;
   BasicBlock *DestB = nullptr;
@@ -4906,11 +4922,17 @@ bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI,
   // Clean up the default block - it may have phis or other instructions before
   // the unreachable terminator.
   if (!HasDefault)
-    createUnreachableSwitchDefault(SI);
+    createUnreachableSwitchDefault(SI, DTU);
+
+  auto *UnreachableDefault = SI->getDefaultDest();
 
   // Drop the switch.
   SI->eraseFromParent();
 
+  if (!HasDefault && DTU)
+    DTU->applyUpdatesPermissive(
+        {{DominatorTree::Delete, BB, UnreachableDefault}});
+
   return true;
 }
 
@@ -4957,7 +4979,7 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
   if (HasDefault && DeadCases.empty() &&
       NumUnknownBits < 64 /* avoid overflow */ &&
       SI->getNumCases() == (1ULL << NumUnknownBits)) {
-    createUnreachableSwitchDefault(SI);
+    createUnreachableSwitchDefault(SI, /*DTU=*/nullptr);
     return true;
   }
 

diff  --git a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
index d99e84b6b940..7125575b2f33 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt %s -simplifycfg -S | FileCheck %s
+; RUN: opt %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
 
 declare i32 @f(i32)
 


        


More information about the llvm-commits mailing list