From 353f7b5433cbf32347fa8363852871132a1072a4 Mon Sep 17 00:00:00 2001 From: Alexandros Lamprineas Date: Mon, 16 Jul 2018 07:51:27 +0000 Subject: [PATCH] [MemorySSAUpdater] Remove deleted trivial Phis from active workset Bug fix for PR37808. The regression test is a reduced version of the original reproducer attached to the bug report. As stated in the report, the problem was that InsertedPHIs was keeping dangling pointers to deleted Memory-Phis. MemoryPhis are created eagerly and sometimes get zapped shortly afterwards. I've used WeakVH instead of an expensive removal operation from the active workset. Differential Revision: https://reviews.llvm.org/D48372 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337149 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/MemorySSAUpdater.h | 8 +++++-- lib/Analysis/MemorySSAUpdater.cpp | 19 +++++++++------ test/Transforms/GVNHoist/pr37808.ll | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 test/Transforms/GVNHoist/pr37808.ll diff --git a/include/llvm/Analysis/MemorySSAUpdater.h b/include/llvm/Analysis/MemorySSAUpdater.h index cf6a2e4a315..a17bd811d70 100644 --- a/include/llvm/Analysis/MemorySSAUpdater.h +++ b/include/llvm/Analysis/MemorySSAUpdater.h @@ -60,7 +60,11 @@ class raw_ostream; class MemorySSAUpdater { private: MemorySSA *MSSA; - SmallVector InsertedPHIs; + + /// We use WeakVH rather than a costly deletion to deal with dangling pointers. + /// MemoryPhis are created eagerly and sometimes get zapped shortly afterwards. + SmallVector InsertedPHIs; + SmallPtrSet VisitedBlocks; SmallSet, 8> NonOptPhis; @@ -207,7 +211,7 @@ private: MemoryAccess *recursePhi(MemoryAccess *Phi); template MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands); - void fixupDefs(const SmallVectorImpl &); + void fixupDefs(const SmallVectorImpl &); }; } // end namespace llvm diff --git a/lib/Analysis/MemorySSAUpdater.cpp b/lib/Analysis/MemorySSAUpdater.cpp index 581fdf50d8b..8ab5f743c98 100644 --- a/lib/Analysis/MemorySSAUpdater.cpp +++ b/lib/Analysis/MemorySSAUpdater.cpp @@ -278,8 +278,7 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { // above and reset ourselves. MD->setDefiningAccess(DefBefore); - SmallVector FixupList(InsertedPHIs.begin(), - InsertedPHIs.end()); + SmallVector FixupList(InsertedPHIs.begin(), InsertedPHIs.end()); if (!DefBeforeSameBlock) { // If there was a local def before us, we must have the same effect it // did. Because every may-def is the same, any phis/etc we would create, it @@ -300,7 +299,7 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { fixupDefs(FixupList); FixupList.clear(); // Put any new phis on the fixup list, and process them - FixupList.append(InsertedPHIs.end() - StartingPHISize, InsertedPHIs.end()); + FixupList.append(InsertedPHIs.begin() + StartingPHISize, InsertedPHIs.end()); } // Now that all fixups are done, rename all uses if we are asked. if (RenameUses) { @@ -317,15 +316,21 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { MSSA->renamePass(MD->getBlock(), FirstDef, Visited); // We just inserted a phi into this block, so the incoming value will become // the phi anyway, so it does not matter what we pass. - for (auto *MP : InsertedPHIs) - MSSA->renamePass(MP->getBlock(), nullptr, Visited); + for (auto &MP : InsertedPHIs) { + MemoryPhi *Phi = dyn_cast_or_null(MP); + if (Phi) + MSSA->renamePass(Phi->getBlock(), nullptr, Visited); + } } } -void MemorySSAUpdater::fixupDefs(const SmallVectorImpl &Vars) { +void MemorySSAUpdater::fixupDefs(const SmallVectorImpl &Vars) { SmallPtrSet Seen; SmallVector Worklist; - for (auto *NewDef : Vars) { + for (auto &Var : Vars) { + MemoryAccess *NewDef = dyn_cast_or_null(Var); + if (!NewDef) + continue; // First, see if there is a local def after the operand. auto *Defs = MSSA->getWritableBlockDefs(NewDef->getBlock()); auto DefIter = NewDef->getDefsIterator(); diff --git a/test/Transforms/GVNHoist/pr37808.ll b/test/Transforms/GVNHoist/pr37808.ll new file mode 100644 index 00000000000..5705c6b89a3 --- /dev/null +++ b/test/Transforms/GVNHoist/pr37808.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -gvn-hoist -S | FileCheck %s + +define void @func() { +; CHECK-LABEL: @func() +; CHECK: bb6: +; CHECK: store i64 0, i64* undef, align 8 +; CHECK: bb7: +; CHECK-NOT: store i64 0, i64* undef, align 8 +; CHECK: bb8: +; CHECK-NOT: store i64 0, i64* undef, align 8 + +entry: + br label %bb1 + +bb1: + br label %bb2 + +bb2: + br label %bb3 + +bb3: + br i1 undef, label %bb4, label %bb2 + +bb4: + br i1 undef, label %bb5, label %bb3 + +bb5: + br label %bb6 + +bb6: + br i1 undef, label %bb7, label %bb8 + +bb7: + store i64 0, i64* undef, align 8 + unreachable + +bb8: + store i64 0, i64* undef, align 8 + ret void +} -- 2.11.0