Commit a80b6c15 authored by Florian Hahn's avatar Florian Hahn
Browse files

[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

llvm-svn: 373513
parent c78c0e08
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -2246,9 +2246,13 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
    }
    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.");
+32 −0
Original line number Diff line number Diff line
@@ -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"(