[llvm] r373513 - [Local] Handle terminators with users in removeUnreachableBlocks.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 2 12:38:24 PDT 2019


Author: fhahn
Date: Wed Oct  2 12:38:24 2019
New Revision: 373513

URL: http://llvm.org/viewvc/llvm-project?rev=373513&view=rev
Log:
[Local] Handle terminators with users in removeUnreachableBlocks.

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.

Reviewers: brzycki, asbirlea, davide, spatel

Reviewed By: asbirlea

Differential Revision: https://reviews.llvm.org/D68327

Modified:
    llvm/trunk/lib/Transforms/Utils/Local.cpp
    llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp

Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=373513&r1=373512&r2=373513&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed Oct  2 12:38:24 2019
@@ -2246,9 +2246,13 @@ bool llvm::removeUnreachableBlocks(Funct
     }
     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.");

Modified: llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp?rev=373513&r1=373512&r2=373513&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp Wed Oct  2 12:38:24 2019
@@ -867,6 +867,36 @@ TEST(Local, RemoveUnreachableBlocks) {
       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 @@ TEST(Local, RemoveUnreachableBlocks) {
   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"(




More information about the llvm-commits mailing list