[PATCH] D78277: [SimpleLoopUnswitch] Update DefaultExit condition to check unreachable is not empty.

Alina Sbirlea via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 00:47:55 PDT 2020


asbirlea created this revision.
asbirlea added a reviewer: chandlerc.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Update the check for the default exit block to not only check that the
terminator is not unreachable, but also check that unreachable block has
*only* the unreachable instruction.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78277

Files:
  llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
  llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll


Index: llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
===================================================================
--- llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
+++ llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
@@ -1243,3 +1243,52 @@
 ; CHECK:       loopexit:
 ; CHECK-NEXT:    ret
 }
+
+declare void @f()
+declare void @g()
+define void @test_unswitch_switch_with_nonempty_unreachable() {
+; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable()
+entry:
+  br label %loop
+
+loop:
+  %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
+  br label %for.cond
+
+for.cond:
+  switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
+    i32 0, label %for.cond
+    i32 1, label %NonEmptyUnreachableBlock
+    i32 2, label %loop.loopexit
+  ]
+
+loop.loopexit:
+  unreachable
+
+NonEmptyUnreachableBlock:
+  call void @f()
+  call void @g()
+  unreachable
+
+; CHECK:loop:
+; CHECK-NEXT:  %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
+; CHECK-NEXT:  switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
+; CHECK-NEXT:    i32 1, label %NonEmptyUnreachableBlock
+; CHECK-NEXT:    i32 2, label %loop.loopexit
+; CHECK-NEXT:    i32 0, label %loop.split
+; CHECK-NEXT:  ]
+
+; CHECK:loop.split:
+; CHECK-NEXT:  br label %for.cond
+
+; CHECK:for.cond:
+; CHECK-NEXT:  br label %for.cond
+
+; CHECK:loop.loopexit:
+; CHECK-NEXT:  unreachable
+
+; CHECK:NonEmptyUnreachableBlock:
+; CHECK-NEXT:  call void @f()
+; CHECK-NEXT:  call void @g()
+; CHECK-NEXT:  unreachable
+}
Index: llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -598,6 +598,17 @@
 
   auto *ParentBB = SI.getParent();
 
+  auto ArePhisLoopInvAndNotUnreachable = [&](BasicBlock *BBToCheck) {
+    bool isLoopExitAndPhisInvariant =
+        !L.contains(BBToCheck) &&
+        areLoopExitPHIsLoopInvariant(L, *ParentBB, *BBToCheck);
+    auto *TI = BBToCheck->getTerminator();
+    bool isUnreachable = isa<UnreachableInst>(TI);
+    bool isNotEmptyUnreachable =
+        !isUnreachable || (isUnreachable && (&*BBToCheck->begin() != TI));
+    return isLoopExitAndPhisInvariant && isNotEmptyUnreachable;
+  };
+
   SmallVector<int, 4> ExitCaseIndices;
   for (auto Case : SI.cases()) {
     auto *SuccBB = Case.getCaseSuccessor();
@@ -608,9 +619,7 @@
   BasicBlock *DefaultExitBB = nullptr;
   SwitchInstProfUpdateWrapper::CaseWeightOpt DefaultCaseWeight =
       SwitchInstProfUpdateWrapper::getSuccessorWeight(SI, 0);
-  if (!L.contains(SI.getDefaultDest()) &&
-      areLoopExitPHIsLoopInvariant(L, *ParentBB, *SI.getDefaultDest()) &&
-      !isa<UnreachableInst>(SI.getDefaultDest()->getTerminator())) {
+  if (ArePhisLoopInvAndNotUnreachable(SI.getDefaultDest())) {
     DefaultExitBB = SI.getDefaultDest();
   } else if (ExitCaseIndices.empty())
     return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78277.257978.patch
Type: text/x-patch
Size: 3008 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200416/1ba9f7ed/attachment.bin>


More information about the llvm-commits mailing list