Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -494,6 +494,14 @@ const DataLayout &DL = BB->getModule()->getDataLayout(); + // We're about to scan backwards. Preserve the initial invariant_start + // intrinsic marking on this load, for subsequent instructions. + // First, compute the info to preserve. + // Then, actually preserve the info before backward scanning starts. + InvariantInfo &InvInfo = BB->getModule()->getInvariantInfo(); + PreservedInvariantInfo Preserved(isLoad ? QueryInst : nullptr, DL, InvInfo); + PreserveInvariantInfo PIO(Preserved); + // Create a numbered basic block to lazily compute and cache instruction // positions inside a BB. This is used to provide fast queries for relative // position between two instructions in a BB and can be used by @@ -504,10 +512,15 @@ while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; - if (IntrinsicInst *II = dyn_cast(Inst)) + if (IntrinsicInst *II = dyn_cast(Inst)) { // Debug intrinsics don't (and can't) cause dependencies. if (isa(II)) continue; + // Same for invariant intrinsics, which may also unset preserved + // invariant info. + if (BackwardScanInvariantIntrinsic(II, Preserved, InvInfo)) continue; + } + // Limit the amount of scanning we do so we don't end up with quadratic // running time on extreme testcases. --Limit; Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -2282,6 +2282,13 @@ if (isa(I)) return false; + + // Also ignore invariant intrinsics, after processing them. + if (IntrinsicInst *II = dyn_cast(I)) { + InvariantInfo &InvInfo = I->getModule()->getInvariantInfo(); + if (processInvariantIntrinsic(II, InvInfo)) return false; + } + // If the instruction can be easily simplified then do so now in preference // to value numbering it. Value numbering often exposes redundancies, for // example if it determines that %y is equal to %x then the instruction