[PATCH] D68327: [Local] Handle terminators with users in removeUnreachableBlocks.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 2 03:14:32 PDT 2019


fhahn created this revision.
fhahn added reviewers: brzycki, asbirlea, davide, spatel.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Terminators like invoke can have users outside the current basic block.
We have to replace those users with undef, before replacing the
terminator.

This fixes a crash exposed by rL373430 <https://reviews.llvm.org/rL373430>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68327

Files:
  llvm/lib/Transforms/Utils/Local.cpp
  llvm/unittests/Transforms/Utils/LocalTest.cpp


Index: llvm/unittests/Transforms/Utils/LocalTest.cpp
===================================================================
--- llvm/unittests/Transforms/Utils/LocalTest.cpp
+++ llvm/unittests/Transforms/Utils/LocalTest.cpp
@@ -867,6 +867,36 @@
       bb2:
         br label %bb1
       }
+
+      declare i32 @__gxx_personality_v0(...)
+
+      define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+      entry:
+        br i1 undef, label %invoke.block, label %exit
+
+      invoke.block:
+        %cond = invoke zeroext i1 @invokable()
+                to label %continue.block unwind label %lpad.block
+
+      continue.block:
+        br i1 %cond, label %if.then, label %if.end
+
+      if.then:
+        unreachable
+
+      if.end:
+        unreachable
+
+      lpad.block:
+        %lp = landingpad { i8*, i32 }
+                catch i8* null
+        br label %exit
+
+      exit:
+        ret void
+      }
+
+      declare i1 @invokable()
       )");
 
   auto runEager = [&](Function &F, DominatorTree *DT) {
@@ -890,12 +920,14 @@
   runWithDomTree(*M, "br_self_loop", runEager);
   runWithDomTree(*M, "br_constant", runEager);
   runWithDomTree(*M, "br_loop", runEager);
+  runWithDomTree(*M, "invoke_terminator", runEager);
 
   // Test removeUnreachableBlocks under Lazy UpdateStrategy.
   runWithDomTree(*M, "br_simple", runLazy);
   runWithDomTree(*M, "br_self_loop", runLazy);
   runWithDomTree(*M, "br_constant", runLazy);
   runWithDomTree(*M, "br_loop", runLazy);
+  runWithDomTree(*M, "invoke_terminator", runLazy);
 
   M = parseIR(C,
               R"(
Index: llvm/lib/Transforms/Utils/Local.cpp
===================================================================
--- llvm/lib/Transforms/Utils/Local.cpp
+++ llvm/lib/Transforms/Utils/Local.cpp
@@ -2250,9 +2250,13 @@
       LVI->eraseBlock(BB);
     BB->dropAllReferences();
     if (DTU) {
-      // Remove the terminator of BB to clear the successor list of BB.
-      if (BB->getTerminator())
-        BB->getInstList().pop_back();
+      Instruction *TI = BB->getTerminator();
+      assert(TI && "Basic block should have a terminator");
+      // Terminators like invoke can have users. We have to replace their users, before
+      // removing them.
+      if (!TI->use_empty())
+        TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
+      TI->eraseFromParent();
       new UnreachableInst(BB->getContext(), BB);
       assert(succ_empty(BB) && "The successor list of BB isn't empty before "
                                "applying corresponding DTU updates.");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68327.222790.patch
Type: text/x-patch
Size: 2601 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191002/6a24221c/attachment.bin>


More information about the llvm-commits mailing list