Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -1328,12 +1328,14 @@ } // If this load follows a GEP, see if we can PRE the indices before analyzing. - if (GetElementPtrInst *GEP = dyn_cast(LI->getOperand(0))) { - for (GetElementPtrInst::op_iterator OI = GEP->idx_begin(), - OE = GEP->idx_end(); - OI != OE; ++OI) - if (Instruction *I = dyn_cast(OI->get())) - performScalarPRE(I); + if (EnablePRE) { + if (auto GEP = dyn_cast(LI->getOperand(0))) { + for (GetElementPtrInst::op_iterator OI = GEP->idx_begin(), + OE = GEP->idx_end(); + OI != OE; ++OI) + if (Instruction *I = dyn_cast(OI->get())) + performScalarPRE(I); + } } // Step 2: Analyze the availability of the load @@ -1645,6 +1647,11 @@ } void GVN::assignBlockRPONumber(Function &F) { + // Initialize BlockRPONumber if it has never been populated, or + // if some blocks have been split and added to F. + if (F.size() == BlockRPONumber.size()) + return; + BlockRPONumber.clear(); uint32_t NextBlockNumber = 1; ReversePostOrderTraversal RPOT(&F); for (BasicBlock *BB : RPOT) @@ -2021,7 +2028,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); @@ -2143,6 +2149,7 @@ } bool GVN::performScalarPRE(Instruction *CurInst) { + assert(EnablePRE && "GVN: Calling performScalarPRE with -enable-pre=false."); if (isa(CurInst) || CurInst->isTerminator() || isa(CurInst) || CurInst->getType()->isVoidTy() || CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() || @@ -2184,6 +2191,9 @@ BasicBlock *PREPred = nullptr; BasicBlock *CurrentBlock = CurInst->getParent(); + // Update the RPO numbers for this function. + assignBlockRPONumber(*CurrentBlock->getParent()); + SmallVector, 8> predMap; for (BasicBlock *P : predecessors(CurrentBlock)) { // We're not interested in PRE where blocks with predecessors that are Index: test/Transforms/GVN/nonescaping-malloc.ll =================================================================== --- test/Transforms/GVN/nonescaping-malloc.ll +++ test/Transforms/GVN/nonescaping-malloc.ll @@ -2,6 +2,10 @@ ; RUN: opt < %s -basicaa -gvn -stats -disable-output 2>&1 | FileCheck %s ; rdar://7363102 +; Sanity check that GVN::performScalarPRE is not called with +; enable-pre=false (asserts) +; RUN: opt < %s -basicaa -gvn -enable-pre=false -disable-output 2>&1 + ; CHECK: Number of loads deleted ; GVN should be able to eliminate load %tmp22.i, because it is redundant with