Index: lib/Transforms/Scalar/GVNHoist.cpp =================================================================== --- lib/Transforms/Scalar/GVNHoist.cpp +++ lib/Transforms/Scalar/GVNHoist.cpp @@ -44,6 +44,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" @@ -256,8 +257,8 @@ class GVNHoist { public: GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, - MemoryDependenceResults *MD, MemorySSA *MSSA) - : DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA), + MemoryDependenceResults *MD, MemorySSA *MSSA, LoopInfo *LInfo) + : DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA), LInfo(LInfo), MSSAUpdater(llvm::make_unique(MSSA)) {} bool run(Function &F) { @@ -333,6 +334,7 @@ AliasAnalysis *AA; MemoryDependenceResults *MD; MemorySSA *MSSA; + LoopInfo *LInfo; std::unique_ptr MSSAUpdater; DenseMap DFSNumber; BBSideEffectsSet BBSideEffects; @@ -795,8 +797,9 @@ for (auto IDFB : IDFBlocks) { // TODO: Prune out useless CHI insertions. for (unsigned i = 0; i < V.size(); ++i) { CHIArg C = {VN, nullptr, nullptr}; - if (DT->dominates(IDFB, V[i]->getParent())) { // Ignore spurious PDFs. - // InValue[V[i]->getParent()].push_back(std::make_pair(VN, V[i])); + const BasicBlock *B = V[i]->getParent(); + if (DT->dominates(IDFB, V[i]->getParent()) && // Ignore spurious PDFs. + LInfo->getLoopFor(IDFB) == LInfo->getLoopFor(B)) { OutValue[IDFB].push_back(C); DEBUG(dbgs() << "\nInsertion a CHI for BB: " << IDFB->getName() << ", for Insn: " << *V[i]); @@ -1156,13 +1159,15 @@ auto &AA = getAnalysis().getAAResults(); auto &MD = getAnalysis().getMemDep(); auto &MSSA = getAnalysis().getMSSA(); + auto &LInfo = getAnalysis().getLoopInfo(); - GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA); + GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA, &LInfo); return G.run(F); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -1181,7 +1186,8 @@ AliasAnalysis &AA = AM.getResult(F); MemoryDependenceResults &MD = AM.getResult(F); MemorySSA &MSSA = AM.getResult(F).getMSSA(); - GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA); + LoopInfo &LInfo = AM.getResult(F); + GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA, &LInfo); if (!G.run(F)) return PreservedAnalyses::all(); @@ -1199,6 +1205,7 @@ INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(GVNHoistLegacyPass, "gvn-hoist", "Early GVN Hoisting of Expressions", false, false) Index: test/Transforms/GVNHoist/pr35222-hoist-load.ll =================================================================== --- /dev/null +++ test/Transforms/GVNHoist/pr35222-hoist-load.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -gvn-hoist < %s | FileCheck %s +; CHECK: load +; CHECK: load +; Check that the load is not hoisted because the call can potentially +; modify the global + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + +@heap = external global i32, align 4 + +define i32 @build_tree() unnamed_addr { +entry: + br label %do.body + +do.body: ; preds = %do.body, %entry + %tmp9 = load i32, i32* @heap, align 4 + %cmp = call i1 @pqdownheap(i32 %tmp9) + br i1 %cmp, label %do.body, label %do.end + +do.end: ; preds = %do.body + %tmp20 = load i32, i32* @heap, align 4 + ret i32 %tmp20 +} + +declare i1 @pqdownheap(i32)