Index: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp +++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp @@ -960,15 +960,25 @@ BlocksToProcess.end()); IDFs.setDefiningBlocks(DefiningBlocks); IDFs.calculate(IDFBlocks); + + SmallSetVector PhisToFill; + // First create all needed Phis. + for (auto *BBIDF : IDFBlocks) + if (!MSSA->getMemoryAccess(BBIDF)) { + auto *IDFPhi = MSSA->createMemoryPhi(BBIDF); + InsertedPhis.push_back(IDFPhi); + PhisToFill.insert(IDFPhi); + } + // Then update or insert their correct incoming values. for (auto *BBIDF : IDFBlocks) { - if (auto *IDFPhi = MSSA->getMemoryAccess(BBIDF)) { + auto *IDFPhi = MSSA->getMemoryAccess(BBIDF); + assert(IDFPhi && "Phi must exist"); + if (!PhisToFill.count(IDFPhi)) { // Update existing Phi. // FIXME: some updates may be redundant, try to optimize and skip some. for (unsigned I = 0, E = IDFPhi->getNumIncomingValues(); I < E; ++I) IDFPhi->setIncomingValue(I, GetLastDef(IDFPhi->getIncomingBlock(I))); } else { - IDFPhi = MSSA->createMemoryPhi(BBIDF); - InsertedPhis.push_back(IDFPhi); for (auto &Pair : children({GD, BBIDF})) { BasicBlock *Pi = Pair.second; IDFPhi->addIncoming(GetLastDef(Pi), Pi); Index: llvm/trunk/test/Analysis/MemorySSA/update_unroll.ll =================================================================== --- llvm/trunk/test/Analysis/MemorySSA/update_unroll.ll +++ llvm/trunk/test/Analysis/MemorySSA/update_unroll.ll @@ -0,0 +1,51 @@ +; RUN: opt -enable-mssa-loop-dependency -verify-memoryssa -loop-rotate -S %s | FileCheck %s +; REQUIRES: asserts + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-grtev4-linux-gnu" + +; Check verification passes after loop rotate, when adding phis in blocks +; receiving incoming edges and adding phis in IDF blocks. +; CHECK-LABEL: @f +define void @f() align 32 { +entry: + br label %while.cond.outer + +while.cond80.while.cond.loopexit_crit_edge: ; preds = %if.else99 + br label %while.cond.outer + +while.cond.outer: ; preds = %while.cond80.while.cond.loopexit_crit_edge, %entry + br i1 undef, label %while.cond.outer.return.loopexit2_crit_edge, label %while.body.lr.ph + +while.body.lr.ph: ; preds = %while.cond.outer + br label %while.body + +while.body: ; preds = %while.body.lr.ph + br i1 undef, label %if.then42, label %if.end61 + +if.then42: ; preds = %while.body + br label %return.loopexit2 + +if.end61: ; preds = %while.body + br label %while.body82 + +while.body82: ; preds = %if.end61 + br i1 undef, label %return.loopexit, label %if.else99 + +if.else99: ; preds = %while.body82 + store i32 0, i32* inttoptr (i64 44 to i32*), align 4 + br label %while.cond80.while.cond.loopexit_crit_edge + +return.loopexit: ; preds = %while.body82 + br label %return + +while.cond.outer.return.loopexit2_crit_edge: ; preds = %while.cond.outer + br label %return.loopexit2 + +return.loopexit2: ; preds = %while.cond.outer.return.loopexit2_crit_edge, %if.then42 + br label %return + +return: ; preds = %return.loopexit2, %return.loopexit + ret void +} +