diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1368,13 +1368,19 @@ // If we don't have PhiInfo then just look at the operands of the phi itself // FIXME: Remove this once we can guarantee that we have PhiInfo always SmallPtrSet UniqueSrc; + Value *OnePhi = nullptr; for (Value *PV1 : PN->incoming_values()) { - if (isa(PV1)) - // If any of the source itself is a PHI, return MayAlias conservatively - // to avoid compile time explosion. The worst possible case is if both - // sides are PHI nodes. In which case, this is O(m x n) time where 'm' - // and 'n' are the number of PHI sources. - return MayAlias; + if (isa(PV1)) { + if (OnePhi && OnePhi != PV1) { + // To control potential compile time explosion, we choose to be + // conserviate when we have more than one Phi input. It is important + // that we handle the single phi case as that lets us handle LCSSA + // phi nodes and (combined with the recursive phi handling) simple + // pointer induction variable patterns. + return MayAlias; + } + OnePhi = PV1; + } if (CheckForRecPhi(PV1)) continue; @@ -1382,6 +1388,11 @@ if (UniqueSrc.insert(PV1).second) V1Srcs.push_back(PV1); } + + if (OnePhi && UniqueSrc.size() > 1) + // Out of an abundance of caution, allow only the trivial lcssa and + // recursive phi cases. + return MayAlias; } // If V1Srcs is empty then that means that the phi has no underlying non-phi diff --git a/llvm/test/Analysis/BasicAA/recphi.ll b/llvm/test/Analysis/BasicAA/recphi.ll --- a/llvm/test/Analysis/BasicAA/recphi.ll +++ b/llvm/test/Analysis/BasicAA/recphi.ll @@ -296,9 +296,9 @@ ; CHECK: NoAlias: i8* %a, i8* %p.base ; CHECK: NoAlias: i8* %a, i8* %p.outer ; CHECK: NoAlias: i8* %a, i8* %p.outer.next -; CHECK: MayAlias: i8* %a, i8* %p.inner +; NO-PHI-VALUES: NoAlias: i8* %a, i8* %p.inner +; PHI-VALUES: MayAlias: i8* %a, i8* %p.inner ; CHECK: NoAlias: i8* %a, i8* %p.inner.next -; TODO: %p.inner does not alias %a define void @nested_loop3(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 @@ -351,9 +351,9 @@ ; CHECK: NoAlias: i8* %a, i8* %p.base ; CHECK: NoAlias: i8* %a, i8* %p1 ; CHECK: NoAlias: i8* %a, i8* %p1.next -; CHECK: MayAlias: i8* %a, i8* %p2 +; NO-PHI-VALUES: NoAlias: i8* %a, i8* %p2 +; PHI-VALUES: MayAlias: i8* %a, i8* %p2 ; CHECK: NoAlias: i8* %a, i8* %p2.next -; TODO: %p2 does not alias %a define void @sibling_loop2(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8