Index: lib/Transforms/Utils/GlobalStatus.cpp =================================================================== --- lib/Transforms/Utils/GlobalStatus.cpp +++ lib/Transforms/Utils/GlobalStatus.cpp @@ -60,7 +60,7 @@ } static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, - SmallPtrSetImpl &PhiUsers) { + SmallPtrSetImpl &VisitedUsers) { if (const GlobalVariable *GV = dyn_cast(V)) if (GV->isExternallyInitialized()) GS.StoredType = GlobalStatus::StoredOnce; @@ -75,7 +75,8 @@ if (!isa(CE->getType())) return true; - if (analyzeGlobalAux(CE, GS, PhiUsers)) + // FIXME: Do we need to add constexpr selects to VisitedUsers? + if (analyzeGlobalAux(CE, GS, VisitedUsers)) return true; } else if (const Instruction *I = dyn_cast(UR)) { if (!GS.HasMultipleAccessingFunctions) { @@ -137,20 +138,18 @@ GS.StoredType = GlobalStatus::Stored; } } - } else if (isa(I)) { - if (analyzeGlobalAux(I, GS, PhiUsers)) + } else if (isa(I) || isa(I)) { + // Skip over bitcasts and GEPs; we don't care about the type or offset + // of the pointer. + if (analyzeGlobalAux(I, GS, VisitedUsers)) return true; - } else if (isa(I)) { - if (analyzeGlobalAux(I, GS, PhiUsers)) - return true; - } else if (isa(I)) { - if (analyzeGlobalAux(I, GS, PhiUsers)) - return true; - } else if (const PHINode *PN = dyn_cast(I)) { - // PHI nodes we can check just like select or GEP instructions, but we - // have to be careful about infinite recursion. - if (PhiUsers.insert(PN).second) // Not already visited. - if (analyzeGlobalAux(I, GS, PhiUsers)) + } else if (isa(I) || isa(I)) { + // Look through selects and PHIs to find if the pointer is + // conditionally accessed. Make sure we only visit an instruction + // once; otherwise, we can get infinite recursion or exponential + // compile time. + if (VisitedUsers.insert(I).second) + if (analyzeGlobalAux(I, GS, VisitedUsers)) return true; } else if (isa(I)) { GS.IsCompared = true; @@ -191,6 +190,6 @@ GlobalStatus::GlobalStatus() = default; bool GlobalStatus::analyzeGlobal(const Value *V, GlobalStatus &GS) { - SmallPtrSet PhiUsers; - return analyzeGlobalAux(V, GS, PhiUsers); + SmallPtrSet VisitedUsers; + return analyzeGlobalAux(V, GS, VisitedUsers); }