[PATCH] D109428: [SImplifyCFG] SwitchInst processing redirecting the UB edges from the BB with the phiNode, that contains the UB, to the new BB.

Dmitry Bakunevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 12 23:38:23 PDT 2021


dbakunevich updated this revision to Diff 372173.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109428/new/

https://reviews.llvm.org/D109428

Files:
  llvm/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/test/Transforms/SimplifyCFG/switch_ub.ll


Index: llvm/test/Transforms/SimplifyCFG/switch_ub.ll
===================================================================
--- llvm/test/Transforms/SimplifyCFG/switch_ub.ll
+++ llvm/test/Transforms/SimplifyCFG/switch_ub.ll
@@ -6,19 +6,12 @@
 define i32 @test_01(i32* %p, i32 %x, i1 %cond) {
 ; CHECK-LABEL: @test_01(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]]
-; CHECK:       pred:
-; CHECK-NEXT:    switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [
-; CHECK-NEXT:    i32 42, label [[BB]]
-; CHECK-NEXT:    i32 123456, label [[BB]]
-; CHECK-NEXT:    i32 -654321, label [[BB]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]]
 ; CHECK:       common.ret:
-; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[PRED]] ]
+; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
 ; CHECK:       bb:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ null, [[PRED]] ], [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[R]] = load i32, i32* [[PHI]], align 4
+; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
 ; CHECK-NEXT:    br label [[COMMON_RET]]
 ;
 entry:
@@ -42,19 +35,12 @@
 define i32 @test_02(i32* %p, i32 %x, i1 %cond) {
 ; CHECK-LABEL: @test_02(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]]
-; CHECK:       pred:
-; CHECK-NEXT:    switch i32 [[X:%.*]], label [[BB]] [
-; CHECK-NEXT:    i32 42, label [[COMMON_RET:%.*]]
-; CHECK-NEXT:    i32 123456, label [[COMMON_RET]]
-; CHECK-NEXT:    i32 -654321, label [[COMMON_RET]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]]
 ; CHECK:       common.ret:
-; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ]
+; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
 ; CHECK:       bb:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[R]] = load i32, i32* [[PHI]], align 4
+; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
 ; CHECK-NEXT:    br label [[COMMON_RET]]
 ;
 entry:
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6609,12 +6609,33 @@
           }
           BI->eraseFromParent();
           if (DTU)
-            DTU->applyUpdates({{DominatorTree::Delete, Predecessor, BB}});
+            DTU->applyUpdates({ { DominatorTree::Delete, Predecessor, BB } });
+          return true;
+        } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
+          // Create the new block in which will redirect the edges that
+          // lead to undefine behavior
+          BasicBlock *Unreachable = BasicBlock::Create(
+              Predecessor->getContext(), "unreachable", BB->getParent(), BB);
+          Builder.SetInsertPoint(Unreachable);
+          // The new block contains only one instruction: Unreachable
+          Builder.CreateUnreachable();
+          for (auto &Case : SI->cases())
+            if (Case.getCaseSuccessor() == BB) {
+              BB->removePredecessor(Predecessor);
+              Case.setSuccessor(Unreachable);
+            }
+          if (SI->getDefaultDest() == BB) {
+            BB->removePredecessor(Predecessor);
+            SI->setDefaultDest(Unreachable);
+          }
+
+          if (DTU)
+            DTU->applyUpdates(
+                { { DominatorTree::Delete, Predecessor, BB },
+                  { DominatorTree::Insert, Predecessor, Unreachable } });
           return true;
         }
-        // TODO: SwitchInst.
       }
-
   return false;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109428.372173.patch
Type: text/x-patch
Size: 4001 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210913/cffa8b9d/attachment.bin>


More information about the llvm-commits mailing list