From 074728a2a901cf2e7fa54443ba37b72d8f43d7f5 Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Wed, 16 May 2018 04:52:18 +0000 Subject: [ObjCARC] Prevent code motion into a catchswitch A catchswitch must be the only non-phi instruction in its basic block; attempting to move a retain or release into a catchswitch basic block will result in invalid IR. Explicitly mark a CFG hazard in this case to prevent the code motion. Differential Revision: https://reviews.llvm.org/D46482 llvm-svn: 332430 --- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 1 + llvm/lib/Transforms/ObjCARC/PtrState.cpp | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'llvm/lib/Transforms/ObjCARC') diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index db09cc3487a..8d657f8b258 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -1592,6 +1592,7 @@ bool ObjCARCOpt::PairUpRetainsAndReleases( assert(It != Retains.end()); const RRInfo &NewRetainRRI = It->second; KnownSafeTD &= NewRetainRRI.KnownSafe; + CFGHazardAfflicted |= NewRetainRRI.CFGHazardAfflicted; for (Instruction *NewRetainRelease : NewRetainRRI.Calls) { auto Jt = Releases.find(NewRetainRelease); if (Jt == Releases.end()) diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index b6c48529de4..8a7b6a74fae 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp +++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp @@ -268,6 +268,11 @@ void BottomUpPtrState::HandlePotentialUse(BasicBlock *BB, Instruction *Inst, if (isa(Inst)) { const auto IP = BB->getFirstInsertionPt(); InsertAfter = IP == BB->end() ? std::prev(BB->end()) : IP; + if (isa(InsertAfter)) + // A catchswitch must be the only non-phi instruction in its basic + // block, so attempting to insert an instruction into such a block would + // produce invalid IR. + SetCFGHazardAfflicted(true); } else { InsertAfter = std::next(Inst->getIterator()); } -- cgit v1.2.3