[PATCH] D67672: Don't use invalidated iterators in FlattenCFGPass
Jakub Kuderski via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 17 11:34:30 PDT 2019
kuhar created this revision.
kuhar added reviewers: dblaikie, tstellar, davide.
Herald added a subscriber: hiraditya.
Herald added a reviewer: grosser.
Herald added a project: LLVM.
FlattenCFG may erase unnecessary blocks, which also invalidates iterators to those erased blocks.
Before this patch, `iterativelyFlattenCFG` could try to increment a BB iterator after that BB has been removed and crash.
This patch makes FlattenCFGPass use `WeakVH` to skip over erased blocks.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D67672
Files:
llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
llvm/test/Transforms/Util/flattencfg.ll
Index: llvm/test/Transforms/Util/flattencfg.ll
===================================================================
--- llvm/test/Transforms/Util/flattencfg.ll
+++ llvm/test/Transforms/Util/flattencfg.ll
@@ -24,3 +24,33 @@
exit: ; preds = %entry, %b0, %b1
ret void
}
+
+; CHECK-LABEL: @test_not_crash2
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %0 = fcmp ult float %a
+; CHECK-NEXT: %1 = fcmp ult float %b
+; CHECK-NEXT: [[COND:%[a-z0-9]+]] = or i1 %0, %1
+; CHECK-NEXT: br i1 [[COND]], label %bb4, label %bb3
+; CHECK: bb3:
+; CHECK-NEXT: br label %bb4
+; CHECK: bb4:
+; CHECK-NEXT: ret void
+define void @test_not_crash2(float %a, float %b) #0 {
+entry:
+ %0 = fcmp ult float %a, 1.000000e+00
+ br i1 %0, label %bb0, label %bb1
+
+bb3: ; preds = %bb0
+ br label %bb4
+
+bb4: ; preds = %bb0, %bb3
+ ret void
+
+bb1: ; preds = %entry
+ br label %bb0
+
+bb0: ; preds = %bb1, %entry
+ %1 = fcmp ult float %b, 1.000000e+00
+ br i1 %1, label %bb4, label %bb3
+}
+
Index: llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
+++ llvm/lib/Transforms/Scalar/FlattenCFGPass.cpp
@@ -11,10 +11,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Transforms/Utils/Local.h"
#include "llvm/IR/CFG.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
+
using namespace llvm;
#define DEBUG_TYPE "flattencfg"
@@ -52,15 +54,23 @@
static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {
bool Changed = false;
bool LocalChange = true;
+
+ // Use block handles instead of iterating over function blocks directly
+ // to avoid using iterators invalidated by erasing blocks.
+ std::vector<WeakVH> Blocks;
+ Blocks.reserve(F.size());
+ for (auto &BB : F)
+ Blocks.push_back(&BB);
+
while (LocalChange) {
LocalChange = false;
- // Loop over all of the basic blocks and remove them if they are unneeded...
- //
- for (Function::iterator BBIt = F.begin(); BBIt != F.end();) {
- if (FlattenCFG(&*BBIt++, AA)) {
- LocalChange = true;
- }
+ // Loop over all of the basic blocks and try to flatten them.
+ for (WeakVH &BlockHandle : Blocks) {
+ // Skip blocks erased by FlattenCFG.
+ if (auto *BB = cast_or_null<BasicBlock>(BlockHandle))
+ if (FlattenCFG(BB, AA))
+ LocalChange = true;
}
Changed |= LocalChange;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67672.220545.patch
Type: text/x-patch
Size: 2841 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190917/d07f4797/attachment.bin>
More information about the llvm-commits
mailing list