diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp --- a/llvm/lib/Analysis/MemorySSA.cpp +++ b/llvm/lib/Analysis/MemorySSA.cpp @@ -2625,21 +2625,20 @@ } bool upward_defs_iterator::IsGuaranteedLoopInvariant(const Value *Ptr) const { - auto IsGuaranteedLoopInvariantBase = [](const Value *Ptr) { + // TODO: Increase limit? + const unsigned MaxGEPToLookup = 2; + for (unsigned I = 0; I < MaxGEPToLookup; I++) { Ptr = Ptr->stripPointerCasts(); - if (!isa(Ptr)) - return true; - return isa(Ptr); - }; - - Ptr = Ptr->stripPointerCasts(); - if (auto *I = dyn_cast(Ptr)) { - if (I->getParent()->isEntryBlock()) + if (auto *I = dyn_cast(Ptr)) { + if (isa(Ptr) || I->getParent()->isEntryBlock()) + return true; + if (auto *GEP = dyn_cast(Ptr)) { + if (!GEP->hasAllConstantIndices()) + return false; + Ptr = GEP->getPointerOperand(); + } + } else return true; } - if (auto *GEP = dyn_cast(Ptr)) { - return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) && - GEP->hasAllConstantIndices(); - } - return IsGuaranteedLoopInvariantBase(Ptr); + return false; } diff --git a/llvm/test/Analysis/MemorySSA/loop-invariant.ll b/llvm/test/Analysis/MemorySSA/loop-invariant.ll --- a/llvm/test/Analysis/MemorySSA/loop-invariant.ll +++ b/llvm/test/Analysis/MemorySSA/loop-invariant.ll @@ -1,10 +1,10 @@ ; RUN: opt -passes='print' -disable-output < %s 2>&1 | FileCheck %s -; TODO: The load's MemoryUse can be defined by liveOnEntry. Since +; The load's MemoryUse can be defined by liveOnEntry. Since ; %p2 is a loop invariant and the MemoryLoc of load instr and store inst in ; loop block are NoAlias ; -; CHECK: MemoryUse(2) +; CHECK: MemoryUse(liveOnEntry) ; CHECK: %val = load i32, ptr %p2 define void @gep(ptr %ptr) { entry: @@ -24,7 +24,8 @@ br label %loop } -; CHECK: MemoryUse(2) +; CHECK: %x = phi i32 [ 0, %tmp ], [ %x.inc, %loop ] +; CHECK-NEXT: MemoryUse(liveOnEntry) ; CHECK-NEXT: %val = load i32, ptr %p2 define void @load_entry_block(ptr %ptr, ptr %addr) { entry: