From 81b03a38899a9e94b2a8cbf07dac58473b97cedc Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 1 Nov 2017 09:48:12 +0000 Subject: [PATCH] [CodeExtractor] Fix iterator invalidation in findOrCreateBlockForHoisting. Summary: By replacing branches to CommonExitBlock, we remove the node from CommonExitBlock's predecessors, invalidating the iterator. The problem is exposed when the common exit block has multiple predecessors and needs to sink lifetime info. The modification in the test case trigger the issue. Reviewers: davidxl, davide, wmi Reviewed By: davidxl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39112 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317084 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/CodeExtractor.cpp | 4 +++- test/Transforms/CodeExtractor/live_shrink_hoist.ll | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Utils/CodeExtractor.cpp b/lib/Transforms/Utils/CodeExtractor.cpp index 0bcf58bd490..557171e1a28 100644 --- a/lib/Transforms/Utils/CodeExtractor.cpp +++ b/lib/Transforms/Utils/CodeExtractor.cpp @@ -307,7 +307,9 @@ CodeExtractor::findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock) { BasicBlock *NewExitBlock = CommonExitBlock->splitBasicBlock( CommonExitBlock->getFirstNonPHI()->getIterator()); - for (auto *Pred : predecessors(CommonExitBlock)) { + for (auto PI = pred_begin(CommonExitBlock), PE = pred_end(CommonExitBlock); + PI != PE;) { + BasicBlock *Pred = *PI++; if (Blocks.count(Pred)) continue; Pred->getTerminator()->replaceUsesOfWith(CommonExitBlock, NewExitBlock); diff --git a/test/Transforms/CodeExtractor/live_shrink_hoist.ll b/test/Transforms/CodeExtractor/live_shrink_hoist.ll index d1b310f0176..1f57146c941 100644 --- a/test/Transforms/CodeExtractor/live_shrink_hoist.ll +++ b/test/Transforms/CodeExtractor/live_shrink_hoist.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -partial-inliner -max-num-inline-blocks=2 -skip-partial-inlining-cost-analysis < %s | FileCheck %s +; RUN: opt -S -partial-inliner -max-num-inline-blocks=3 -skip-partial-inlining-cost-analysis < %s | FileCheck %s ; RUN: opt -S -passes=partial-inliner -max-num-inline-blocks=2 -skip-partial-inlining-cost-analysis < %s | FileCheck %s %class.A = type { i32 } @@ -16,6 +16,10 @@ bb: br i1 %tmp3, label %bb4, label %bb9 bb4: ; preds = %bb + %foo = icmp eq i32 %tmp2, 0 + br i1 %foo, label %bb5, label %bb9 + +bb5: ; preds = %bb4 call void @_ZN1A7memfuncEv(%class.A* nonnull %tmp) %tmp5 = getelementptr inbounds %class.A, %class.A* %tmp, i64 0, i32 0 %tmp6 = load i32, i32* %tmp5, align 4, !tbaa !6 -- 2.11.0