[SimpleLoopUnswitch] Drop uses of instructions before block deletion
authorDaniil Suchkov <suc-daniil@yandex.ru>
Mon, 25 May 2020 08:06:12 +0000 (15:06 +0700)
committerDaniil Suchkov <suc-daniil@yandex.ru>
Wed, 27 May 2020 11:25:18 +0000 (18:25 +0700)
Currently if instructions defined in a block are used in unreachable
blocks and SimpleLoopUnswitch attempts deleting the block, it triggers
assertion "Uses remain when a value is destroyed!".
This patch fixes it by replacing all uses of instructions from BB with
undefs before BB deletion.

Reviewed By: asbirlea

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

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/dead-blocks-uses-in-unreachablel-blocks.ll

index 914fadc..6c6d6ca 100644 (file)
@@ -1574,6 +1574,11 @@ static void deleteDeadBlocksFromLoop(Loop &L,
     // Check that the dominator tree has already been updated.
     assert(!DT.getNode(BB) && "Should already have cleared domtree!");
     LI.changeLoopFor(BB, nullptr);
+    // Drop all uses of the instructions to make sure we won't have dangling
+    // uses in other blocks.
+    for (auto &I : *BB)
+      if (!I.use_empty())
+        I.replaceAllUsesWith(UndefValue::get(I.getType()));
     BB->dropAllReferences();
   }
 
index 4dec9a3..2756e10 100644 (file)
@@ -1,4 +1,3 @@
-; XFAIL: *
 ; REQUIRES: asserts
 ; RUN: opt < %s -passes='unswitch<nontrivial>' -disable-output
 ; RUN: opt < %s -simple-loop-unswitch -enable-nontrivial-unswitch -disable-output