Index: llvm/trunk/include/llvm/Transforms/Scalar/GVN.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar/GVN.h +++ llvm/trunk/include/llvm/Transforms/Scalar/GVN.h @@ -27,6 +27,7 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include @@ -180,7 +181,12 @@ // Map the block to reversed postorder traversal number. It is used to // find back edge easily. - DenseMap BlockRPONumber; + DenseMap, uint32_t> BlockRPONumber; + + // This is set 'true' initially and also when new blocks have been added to + // the function being analyzed. This boolean is used to control the updating + // of BlockRPONumber prior to accessing the contents of BlockRPONumber. + bool InvalidBlockRPONumbers = true; using LoadDepVect = SmallVector; using AvailValInBlkVect = SmallVector; Index: llvm/trunk/lib/Transforms/Scalar/GVN.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp @@ -1645,10 +1645,12 @@ } void GVN::assignBlockRPONumber(Function &F) { + BlockRPONumber.clear(); uint32_t NextBlockNumber = 1; ReversePostOrderTraversal RPOT(&F); for (BasicBlock *BB : RPOT) BlockRPONumber[BB] = NextBlockNumber++; + InvalidBlockRPONumbers = false; } // Tries to replace instruction with const, using information from @@ -1992,6 +1994,7 @@ ICF = &ImplicitCFT; VN.setMemDep(MD); ORE = RunORE; + InvalidBlockRPONumbers = true; bool Changed = false; bool ShouldContinue = true; @@ -2021,7 +2024,6 @@ // Fabricate val-num for dead-code in order to suppress assertion in // performPRE(). assignValNumForDeadCode(); - assignBlockRPONumber(F); bool PREChanged = true; while (PREChanged) { PREChanged = performPRE(F); @@ -2183,6 +2185,10 @@ BasicBlock *PREPred = nullptr; BasicBlock *CurrentBlock = CurInst->getParent(); + // Update the RPO numbers for this function. + if (InvalidBlockRPONumbers) + assignBlockRPONumber(*CurrentBlock->getParent()); + SmallVector, 8> predMap; for (BasicBlock *P : predecessors(CurrentBlock)) { // We're not interested in PRE where blocks with predecessors that are @@ -2194,6 +2200,8 @@ // It is not safe to do PRE when P->CurrentBlock is a loop backedge, and // when CurInst has operand defined in CurrentBlock (so it may be defined // by phi in the loop header). + assert(BlockRPONumber.count(P) && BlockRPONumber.count(CurrentBlock) && + "Invalid BlockRPONumber map."); if (BlockRPONumber[P] >= BlockRPONumber[CurrentBlock] && llvm::any_of(CurInst->operands(), [&](const Use &U) { if (auto *Inst = dyn_cast(U.get())) @@ -2341,6 +2349,7 @@ SplitCriticalEdge(Pred, Succ, CriticalEdgeSplittingOptions(DT)); if (MD) MD->invalidateCachedPredecessors(); + InvalidBlockRPONumbers = true; return BB; } @@ -2355,6 +2364,7 @@ CriticalEdgeSplittingOptions(DT)); } while (!toSplit.empty()); if (MD) MD->invalidateCachedPredecessors(); + InvalidBlockRPONumbers = true; return true; } @@ -2381,6 +2391,7 @@ BlockRPONumber.clear(); TableAllocator.Reset(); ICF->clear(); + InvalidBlockRPONumbers = true; } /// Verify that the specified instruction does not occur in our