Index: include/llvm/Analysis/AliasAnalysis.h =================================================================== --- include/llvm/Analysis/AliasAnalysis.h +++ include/llvm/Analysis/AliasAnalysis.h @@ -95,18 +95,48 @@ /// /// This is no access at all, a modification, a reference, or both /// a modification and a reference. These are specifically structured such that -/// they form a two bit matrix and bit-tests for 'mod' or 'ref' work with any -/// of the possible values. +/// they form a two bit matrix and bit-tests for 'mod' or 'ref' +/// work with any of the possible values. + enum ModRefInfo { /// The access neither references nor modifies the value stored in memory. MRI_NoModRef = 0, - /// The access references the value stored in memory. + /// The access may reference the value stored in memory. MRI_Ref = 1, - /// The access modifies the value stored in memory. + /// The access may modify the value stored in memory. MRI_Mod = 2, - /// The access both references and modifies the value stored in memory. - MRI_ModRef = MRI_Ref | MRI_Mod + /// The access may reference and may modify the value stored in memory. + MRI_ModRef = MRI_Ref | MRI_Mod, }; +static inline bool isNoModRef(ModRefInfo MRI) { return MRI == MRI_NoModRef; } +static inline bool modOrRefSet(ModRefInfo MRI) { return MRI & MRI_ModRef; } +static inline bool modAndRefSet(ModRefInfo MRI) { + return (MRI & MRI_ModRef) == MRI_ModRef; +} +static inline bool modSet(ModRefInfo MRI) { return MRI & MRI_Mod; } +static inline bool refSet(ModRefInfo MRI) { return MRI & MRI_Ref; } + +static inline ModRefInfo setRef(ModRefInfo MRI) { + return ModRefInfo(MRI | MRI_Ref); +} +static inline ModRefInfo setMod(ModRefInfo MRI) { + return ModRefInfo(MRI | MRI_Mod); +} +static inline ModRefInfo setModAndRef(ModRefInfo MRI) { + return ModRefInfo(MRI | MRI_ModRef); +} +static inline ModRefInfo clearMod(ModRefInfo MRI) { + return ModRefInfo(MRI & MRI_Ref); +} +static inline ModRefInfo clearRef(ModRefInfo MRI) { + return ModRefInfo(MRI & MRI_Mod); +} +static inline ModRefInfo modRefUnion(ModRefInfo MRI1, ModRefInfo MRI2) { + return ModRefInfo(MRI1 | MRI2); +} +static inline ModRefInfo modRefIntersection(ModRefInfo MRI1, ModRefInfo MRI2) { + return ModRefInfo(MRI1 & MRI2); +} /// The locations at which a function might access memory. /// @@ -570,7 +600,7 @@ /// \brief Return information about whether a particular call site modifies /// or reads the specified memory location \p MemLoc before instruction \p I - /// in a BasicBlock. A ordered basic block \p OBB can be used to speed up + /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up /// instruction ordering queries inside the BasicBlock containing \p I. ModRefInfo callCapturesBefore(const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT, Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -122,10 +122,10 @@ ModRefInfo Result = MRI_ModRef; for (const auto &AA : AAs) { - Result = ModRefInfo(Result & AA->getArgModRefInfo(CS, ArgIdx)); + Result = modRefIntersection(Result, AA->getArgModRefInfo(CS, ArgIdx)); // Early-exit the moment we reach the bottom of the lattice. - if (Result == MRI_NoModRef) + if (isNoModRef(Result)) return Result; } @@ -146,8 +146,9 @@ // is that if the call references what this instruction // defines, it must be clobbered by this location. const MemoryLocation DefLoc = MemoryLocation::get(I); - if (getModRefInfo(Call, DefLoc) != MRI_NoModRef) - return MRI_ModRef; + ModRefInfo MR = getModRefInfo(Call, DefLoc); + if (modOrRefSet(MR)) + return setModAndRef(MR); } return MRI_NoModRef; } @@ -157,10 +158,10 @@ ModRefInfo Result = MRI_ModRef; for (const auto &AA : AAs) { - Result = ModRefInfo(Result & AA->getModRefInfo(CS, Loc)); + Result = modRefIntersection(Result, AA->getModRefInfo(CS, Loc)); // Early-exit the moment we reach the bottom of the lattice. - if (Result == MRI_NoModRef) + if (isNoModRef(Result)) return Result; } @@ -172,9 +173,9 @@ return MRI_NoModRef; if (onlyReadsMemory(MRB)) - Result = ModRefInfo(Result & MRI_Ref); + Result = clearMod(Result); else if (doesNotReadMemory(MRB)) - Result = ModRefInfo(Result & MRI_Mod); + Result = clearRef(Result); if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) { bool DoesAlias = false; @@ -190,20 +191,21 @@ if (ArgAlias != NoAlias) { ModRefInfo ArgMask = getArgModRefInfo(CS, ArgIdx); DoesAlias = true; - AllArgsMask = ModRefInfo(AllArgsMask | ArgMask); + AllArgsMask = modRefUnion(AllArgsMask, ArgMask); } } } + // Return MRI_NoModRef if no alias found with any argument. if (!DoesAlias) return MRI_NoModRef; - Result = ModRefInfo(Result & AllArgsMask); + // Logical & between other AA analyses and argument analysis. + Result = modRefIntersection(Result, AllArgsMask); } // If Loc is a constant memory location, the call definitely could not // modify the memory location. - if ((Result & MRI_Mod) && - pointsToConstantMemory(Loc, /*OrLocal*/ false)) - Result = ModRefInfo(Result & ~MRI_Mod); + if (modSet(Result) && pointsToConstantMemory(Loc, /*OrLocal*/ false)) + Result = clearMod(Result); return Result; } @@ -213,10 +215,10 @@ ModRefInfo Result = MRI_ModRef; for (const auto &AA : AAs) { - Result = ModRefInfo(Result & AA->getModRefInfo(CS1, CS2)); + Result = modRefIntersection(Result, AA->getModRefInfo(CS1, CS2)); // Early-exit the moment we reach the bottom of the lattice. - if (Result == MRI_NoModRef) + if (isNoModRef(Result)) return Result; } @@ -239,9 +241,9 @@ // If CS1 only reads memory, the only dependence on CS2 can be // from CS1 reading memory written by CS2. if (onlyReadsMemory(CS1B)) - Result = ModRefInfo(Result & MRI_Ref); + Result = clearMod(Result); else if (doesNotReadMemory(CS1B)) - Result = ModRefInfo(Result & MRI_Mod); + Result = clearRef(Result); // If CS2 only access memory through arguments, accumulate the mod/ref // information from CS1's references to the memory referenced by @@ -256,19 +258,26 @@ unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); - // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence - // of CS1 on that location is the inverse. - ModRefInfo ArgMask = getArgModRefInfo(CS2, CS2ArgIdx); - if (ArgMask == MRI_Mod) + // ArgModRefCS2 indicates what CS2 might do to CS2ArgLoc, and the + // dependence of CS1 on that location is the inverse: + // - If CS2 modifies location, dependence exists if CS1 reads or writes. + // - If CS2 only reads location, dependence exists if CS1 writes. + ModRefInfo ArgModRefCS2 = getArgModRefInfo(CS2, CS2ArgIdx); + ModRefInfo ArgMask; + if (modSet(ArgModRefCS2)) ArgMask = MRI_ModRef; - else if (ArgMask == MRI_Ref) + else if (refSet(ArgModRefCS2)) ArgMask = MRI_Mod; - ArgMask = ModRefInfo(ArgMask & getModRefInfo(CS1, CS2ArgLoc)); + // ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use + // above ArgMask to update dependence info. + ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc); + ArgMask = modRefIntersection(ArgMask, ModRefCS1); - R = ModRefInfo((R | ArgMask) & Result); - if (R == Result) + R = modRefIntersection(modRefUnion(R, ArgMask), Result); + if (R == Result) { break; + } } } return R; @@ -286,19 +295,19 @@ unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); - // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod - // CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1 - // might Ref, then we care only about a Mod by CS2. - ModRefInfo ArgMask = getArgModRefInfo(CS1, CS1ArgIdx); - ModRefInfo ArgR = getModRefInfo(CS2, CS1ArgLoc); - if (((ArgMask & MRI_Mod) != MRI_NoModRef && - (ArgR & MRI_ModRef) != MRI_NoModRef) || - ((ArgMask & MRI_Ref) != MRI_NoModRef && - (ArgR & MRI_Mod) != MRI_NoModRef)) - R = ModRefInfo((R | ArgMask) & Result); - - if (R == Result) + // ArgModRefCS1 indicates what CS1 might do to CS1ArgLoc; if CS1 might + // Mod CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If + // CS1 might Ref, then we care only about a Mod by CS2. + ModRefInfo ArgModRefCS1 = getArgModRefInfo(CS1, CS1ArgIdx); + ModRefInfo ModRefCS2 = getModRefInfo(CS2, CS1ArgLoc); + if ((modSet(ArgModRefCS1) && modOrRefSet(ModRefCS2)) || + (refSet(ArgModRefCS1) && modSet(ModRefCS2))) { + R = modRefIntersection(modRefUnion(R, ArgModRefCS1), Result); + } + + if (R == Result) { break; + } } } return R; @@ -347,9 +356,13 @@ // If the load address doesn't alias the given address, it doesn't read // or write the specified memory. - if (Loc.Ptr && !alias(MemoryLocation::get(L), Loc)) - return MRI_NoModRef; - + if (Loc.Ptr) { + AliasResult AR = alias(MemoryLocation::get(L), Loc); + if (AR == NoAlias) + return MRI_NoModRef; + if (AR == MustAlias) + return MRI_Ref; + } // Otherwise, a load just reads. return MRI_Ref; } @@ -361,9 +374,10 @@ return MRI_ModRef; if (Loc.Ptr) { + AliasResult AR = alias(MemoryLocation::get(S), Loc); // If the store address cannot alias the pointer in question, then the // specified memory cannot be modified by the store. - if (!alias(MemoryLocation::get(S), Loc)) + if (AR == NoAlias) return MRI_NoModRef; // If the pointer is a pointer to constant memory, then it could not have @@ -387,9 +401,10 @@ ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc) { if (Loc.Ptr) { + AliasResult AR = alias(MemoryLocation::get(V), Loc); // If the va_arg address cannot alias the pointer in question, then the // specified memory cannot be accessed by the va_arg. - if (!alias(MemoryLocation::get(V), Loc)) + if (AR == NoAlias) return MRI_NoModRef; // If the pointer is a pointer to constant memory, then it could not have @@ -434,9 +449,13 @@ if (isStrongerThanMonotonic(CX->getSuccessOrdering())) return MRI_ModRef; - // If the cmpxchg address does not alias the location, it does not access it. - if (Loc.Ptr && !alias(MemoryLocation::get(CX), Loc)) - return MRI_NoModRef; + if (Loc.Ptr) { + AliasResult AR = alias(MemoryLocation::get(CX), Loc); + // If the cmpxchg address does not alias the location, it does not access + // it. + if (AR == NoAlias) + return MRI_NoModRef; + } return MRI_ModRef; } @@ -447,16 +466,20 @@ if (isStrongerThanMonotonic(RMW->getOrdering())) return MRI_ModRef; - // If the atomicrmw address does not alias the location, it does not access it. - if (Loc.Ptr && !alias(MemoryLocation::get(RMW), Loc)) - return MRI_NoModRef; + if (Loc.Ptr) { + AliasResult AR = alias(MemoryLocation::get(RMW), Loc); + // If the atomicrmw address does not alias the location, it does not access + // it. + if (AR == NoAlias) + return MRI_NoModRef; + } return MRI_ModRef; } /// \brief Return information about whether a particular call site modifies /// or reads the specified memory location \p MemLoc before instruction \p I -/// in a BasicBlock. A ordered basic block \p OBB can be used to speed up +/// in a BasicBlock. An ordered basic block \p OBB can be used to speed up /// instruction-ordering queries inside the BasicBlock containing \p I. /// FIXME: this is really just shoring-up a deficiency in alias analysis. /// BasicAA isn't willing to spend linear time determining whether an alloca @@ -487,6 +510,7 @@ unsigned ArgNo = 0; ModRefInfo R = MRI_NoModRef; + // Set flag only if no May found and all operands processed. for (auto CI = CS.data_operands_begin(), CE = CS.data_operands_end(); CI != CE; ++CI, ++ArgNo) { // Only look at the no-capture or byval pointer arguments. If this @@ -497,11 +521,12 @@ ArgNo < CS.getNumArgOperands() && !CS.isByValArgument(ArgNo))) continue; + AliasResult AR = alias(MemoryLocation(*CI), MemoryLocation(Object)); // If this is a no-capture pointer argument, see if we can tell that it // is impossible to alias the pointer we're checking. If not, we have to // assume that the call could touch the pointer, even though it doesn't // escape. - if (isNoAlias(MemoryLocation(*CI), MemoryLocation(Object))) + if (AR == NoAlias) continue; if (CS.doesNotAccessMemory(ArgNo)) continue; @@ -538,7 +563,7 @@ ++E; // Convert from inclusive to exclusive range. for (; I != E; ++I) // Check every instruction in range - if (getModRefInfo(&*I, Loc) & Mode) + if (modRefIntersection(getModRefInfo(&*I, Loc), Mode)) return true; return false; } Index: lib/Analysis/AliasAnalysisEvaluator.cpp =================================================================== --- lib/Analysis/AliasAnalysisEvaluator.cpp +++ lib/Analysis/AliasAnalysisEvaluator.cpp @@ -31,8 +31,8 @@ static cl::opt PrintMustAlias("print-must-aliases", cl::ReallyHidden); static cl::opt PrintNoModRef("print-no-modref", cl::ReallyHidden); -static cl::opt PrintMod("print-mod", cl::ReallyHidden); static cl::opt PrintRef("print-ref", cl::ReallyHidden); +static cl::opt PrintMod("print-mod", cl::ReallyHidden); static cl::opt PrintModRef("print-modref", cl::ReallyHidden); static cl::opt EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden); @@ -249,14 +249,14 @@ F.getParent()); ++NoModRefCount; break; - case MRI_Mod: - PrintModRefResults("Just Mod", PrintMod, I, Pointer, F.getParent()); - ++ModCount; - break; case MRI_Ref: PrintModRefResults("Just Ref", PrintRef, I, Pointer, F.getParent()); ++RefCount; break; + case MRI_Mod: + PrintModRefResults("Just Mod", PrintMod, I, Pointer, F.getParent()); + ++ModCount; + break; case MRI_ModRef: PrintModRefResults("Both ModRef", PrintModRef, I, Pointer, F.getParent()); @@ -276,14 +276,14 @@ PrintModRefResults("NoModRef", PrintNoModRef, *C, *D, F.getParent()); ++NoModRefCount; break; - case MRI_Mod: - PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent()); - ++ModCount; - break; case MRI_Ref: PrintModRefResults("Just Ref", PrintRef, *C, *D, F.getParent()); ++RefCount; break; + case MRI_Mod: + PrintModRefResults("Just Mod", PrintMod, *C, *D, F.getParent()); + ++ModCount; + break; case MRI_ModRef: PrintModRefResults("Both ModRef", PrintModRef, *C, *D, F.getParent()); ++ModRefCount; @@ -325,7 +325,7 @@ } // Display the summary for mod/ref analysis - int64_t ModRefSum = NoModRefCount + ModCount + RefCount + ModRefCount; + int64_t ModRefSum = NoModRefCount + RefCount + ModCount + ModRefCount; if (ModRefSum == 0) { errs() << " Alias Analysis Mod/Ref Evaluator Summary: no " "mod/ref!\n"; Index: lib/Analysis/AliasSetTracker.cpp =================================================================== --- lib/Analysis/AliasSetTracker.cpp +++ lib/Analysis/AliasSetTracker.cpp @@ -211,8 +211,8 @@ if (!UnknownInsts.empty()) { for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) if (auto *Inst = getUnknownInst(i)) - if (AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)) != - MRI_NoModRef) + if (modOrRefSet( + AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)))) return true; } @@ -231,15 +231,15 @@ for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { if (auto *UnknownInst = getUnknownInst(i)) { ImmutableCallSite C1(UnknownInst), C2(Inst); - if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef || - AA.getModRefInfo(C2, C1) != MRI_NoModRef) + if (!C1 || !C2 || modOrRefSet(AA.getModRefInfo(C1, C2)) || + modOrRefSet(AA.getModRefInfo(C2, C1))) return true; } } for (iterator I = begin(), E = end(); I != E; ++I) - if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(), - I.getAAInfo())) != MRI_NoModRef) + if (modOrRefSet(AA.getModRefInfo( + Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))) return true; return false; Index: lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- lib/Analysis/BasicAliasAnalysis.cpp +++ lib/Analysis/BasicAliasAnalysis.cpp @@ -809,12 +809,12 @@ // Operand aliases 'Object', but call doesn't modify it. Strengthen // initial assumption and keep looking in case if there are more aliases. if (CS.onlyReadsMemory(OperandNo)) { - Result = static_cast(Result | MRI_Ref); + Result = setRef(Result); continue; } // Operand aliases 'Object' but call only writes into it. if (CS.doesNotReadMemory(OperandNo)) { - Result = static_cast(Result | MRI_Mod); + Result = setMod(Result); continue; } // This operand aliases 'Object' and call reads and writes into it. @@ -832,7 +832,7 @@ // routines do not read values visible in the IR. TODO: Consider special // casing realloc and strdup routines which access only their arguments as // well. Or alternatively, replace all of this with inaccessiblememonly once - // that's implemented fully. + // that's implemented fully. auto *Inst = CS.getInstruction(); if (isMallocOrCallocLikeFn(Inst, &TLI)) { // Be conservative if the accessed pointer may alias the allocation - @@ -860,9 +860,9 @@ // It's also possible for Loc to alias both src and dest, or neither. ModRefInfo rv = MRI_NoModRef; if (SrcAA != NoAlias) - rv = static_cast(rv | MRI_Ref); + rv = setRef(rv); if (DestAA != NoAlias) - rv = static_cast(rv | MRI_Mod); + rv = setMod(rv); return rv; } Index: lib/Analysis/GlobalsModRef.cpp =================================================================== --- lib/Analysis/GlobalsModRef.cpp +++ lib/Analysis/GlobalsModRef.cpp @@ -84,6 +84,7 @@ /// The bit that flags that this function may read any global. This is /// chosen to mix together with ModRefInfo bits. + /// FIXME: This assumes ModRefInfo lattice will remain 4 bits! enum { MayReadAnyGlobal = 4 }; /// Checks to document the invariants of the bit packing here. @@ -230,9 +231,9 @@ FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior; if (FunctionInfo *FI = getFunctionInfo(F)) { - if (FI->getModRefInfo() == MRI_NoModRef) + if (!modOrRefSet(FI->getModRefInfo())) Min = FMRB_DoesNotAccessMemory; - else if ((FI->getModRefInfo() & MRI_Mod) == 0) + else if (!modSet(FI->getModRefInfo())) Min = FMRB_OnlyReadsMemory; } @@ -246,9 +247,9 @@ if (!CS.hasOperandBundles()) if (const Function *F = CS.getCalledFunction()) if (FunctionInfo *FI = getFunctionInfo(F)) { - if (FI->getModRefInfo() == MRI_NoModRef) + if (!modOrRefSet(FI->getModRefInfo())) Min = FMRB_DoesNotAccessMemory; - else if ((FI->getModRefInfo() & MRI_Mod) == 0) + else if (!modSet(FI->getModRefInfo())) Min = FMRB_OnlyReadsMemory; } @@ -584,9 +585,9 @@ } } - if ((FI.getModRefInfo() & MRI_Mod) == 0) + if (!modSet(FI.getModRefInfo())) ++NumReadMemFunctions; - if (FI.getModRefInfo() == MRI_NoModRef) + if (!modOrRefSet(FI.getModRefInfo())) ++NumNoMemFunctions; // Finally, now that we know the full effect on this SCC, clone the @@ -894,7 +895,7 @@ ModRefInfo GlobalsAAResult::getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { - unsigned Known = MRI_ModRef; + ModRefInfo Known = MRI_ModRef; // If we are asking for mod/ref info of a direct call with a pointer to a // global we are tracking, return information if we have it. @@ -904,12 +905,12 @@ if (const Function *F = CS.getCalledFunction()) if (NonAddressTakenGlobals.count(GV)) if (const FunctionInfo *FI = getFunctionInfo(F)) - Known = FI->getModRefInfoForGlobal(*GV) | - getModRefInfoForArgument(CS, GV); + Known = modRefUnion(FI->getModRefInfoForGlobal(*GV), + getModRefInfoForArgument(CS, GV)); - if (Known == MRI_NoModRef) + if (!modOrRefSet(Known)) return MRI_NoModRef; // No need to query other mod/ref analyses - return ModRefInfo(Known & AAResultBase::getModRefInfo(CS, Loc)); + return modRefIntersection(Known, AAResultBase::getModRefInfo(CS, Loc)); } GlobalsAAResult::GlobalsAAResult(const DataLayout &DL, Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -212,7 +212,7 @@ ModRefInfo MR = GetLocation(Inst, Loc, TLI); if (Loc.Ptr) { // A simple instruction. - if (AA.getModRefInfo(CS, Loc) != MRI_NoModRef) + if (modOrRefSet(AA.getModRefInfo(CS, Loc))) return MemDepResult::getClobber(Inst); continue; } @@ -223,7 +223,7 @@ case MRI_NoModRef: // If the two calls are the same, return InstCS as a Def, so that // CS can be found redundant and eliminated. - if (isReadOnlyCall && !(MR & MRI_Mod) && + if (isReadOnlyCall && !modSet(MR) && CS.getInstruction()->isIdenticalToWhenDefined(Inst)) return MemDepResult::getDef(Inst); @@ -237,7 +237,7 @@ // If we could not obtain a pointer for the instruction and the instruction // touches memory then assume that this is a dependency. - if (MR != MRI_NoModRef) + if (modOrRefSet(MR)) return MemDepResult::getClobber(Inst); } @@ -642,7 +642,7 @@ // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where // the query pointer points to constant memory etc. - if (AA.getModRefInfo(SI, MemLoc) == MRI_NoModRef) + if (!modOrRefSet(AA.getModRefInfo(SI, MemLoc))) continue; // Ok, this store might clobber the query pointer. Check to see if it is @@ -688,7 +688,7 @@ // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer. ModRefInfo MR = AA.getModRefInfo(Inst, MemLoc); // If necessary, perform additional analysis. - if (MR == MRI_ModRef) + if (modAndRefSet(MR)) MR = AA.callCapturesBefore(Inst, MemLoc, &DT, &OBB); switch (MR) { case MRI_NoModRef: Index: lib/Analysis/MemorySSA.cpp =================================================================== --- lib/Analysis/MemorySSA.cpp +++ lib/Analysis/MemorySSA.cpp @@ -262,7 +262,7 @@ if (UseCS) { ModRefInfo I = AA.getModRefInfo(DefInst, UseCS); - return I != MRI_NoModRef; + return modOrRefSet(I); } if (auto *DefLoad = dyn_cast(DefInst)) { @@ -278,7 +278,7 @@ } } - return AA.getModRefInfo(DefInst, UseLoc) & MRI_Mod; + return modSet(AA.getModRefInfo(DefInst, UseLoc)); } static bool instructionClobbersQuery(MemoryDef *MD, const MemoryUseOrDef *MU, @@ -1526,8 +1526,8 @@ // Separate memory aliasing and ordering into two different chains so that we // can precisely represent both "what memory will this read/write/is clobbered // by" and "what instructions can I move this past". - bool Def = bool(ModRef & MRI_Mod) || isOrdered(I); - bool Use = bool(ModRef & MRI_Ref); + bool Def = modSet(ModRef) || isOrdered(I); + bool Use = refSet(ModRef); // It's possible for an instruction to not modify memory at all. During // construction, we ignore them. Index: lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- lib/Transforms/Scalar/DeadStoreElimination.cpp +++ lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -594,11 +594,9 @@ } for (; BI != EI; ++BI) { Instruction *I = &*BI; - if (I->mayWriteToMemory() && I != SecondI) { - auto Res = AA->getModRefInfo(I, MemLoc); - if (Res & MRI_Mod) + if (I->mayWriteToMemory() && I != SecondI) + if (modSet(AA->getModRefInfo(I, MemLoc))) return false; - } } if (B != FirstBB) { assert(B != &FirstBB->getParent()->getEntryBlock() && @@ -824,7 +822,7 @@ // See if the call site touches the value. ModRefInfo A = AA->getModRefInfo(CS, I, getPointerSize(I, DL, *TLI)); - return A == MRI_ModRef || A == MRI_Ref; + return refSet(A); }); // If all of the allocas were clobbered by the call then we're not going @@ -1255,7 +1253,7 @@ if (DepWrite == &BB.front()) break; // Can't look past this instruction if it might read 'Loc'. - if (AA->getModRefInfo(DepWrite, Loc) & MRI_Ref) + if (refSet(AA->getModRefInfo(DepWrite, Loc))) break; InstDep = MD->getPointerDependencyFrom(Loc, /*isLoad=*/ false, Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -518,7 +518,7 @@ const LoadInst *LI) { // If the store alias this position, early bail out. MemoryLocation StoreLoc = MemoryLocation::get(SI); - if (AA.getModRefInfo(P, StoreLoc) != MRI_NoModRef) + if (modOrRefSet(AA.getModRefInfo(P, StoreLoc))) return false; // Keep track of the arguments of all instruction we plan to lift @@ -542,20 +542,20 @@ for (auto I = --SI->getIterator(), E = P->getIterator(); I != E; --I) { auto *C = &*I; - bool MayAlias = AA.getModRefInfo(C, None) != MRI_NoModRef; + bool MayAlias = modOrRefSet(AA.getModRefInfo(C, None)); bool NeedLift = false; if (Args.erase(C)) NeedLift = true; else if (MayAlias) { NeedLift = llvm::any_of(MemLocs, [C, &AA](const MemoryLocation &ML) { - return AA.getModRefInfo(C, ML); + return modOrRefSet(AA.getModRefInfo(C, ML)); }); if (!NeedLift) NeedLift = llvm::any_of(CallSites, [C, &AA](const ImmutableCallSite &CS) { - return AA.getModRefInfo(C, CS); + return modOrRefSet(AA.getModRefInfo(C, CS)); }); } @@ -565,18 +565,18 @@ if (MayAlias) { // Since LI is implicitly moved downwards past the lifted instructions, // none of them may modify its source. - if (AA.getModRefInfo(C, LoadLoc) & MRI_Mod) + if (modSet(AA.getModRefInfo(C, LoadLoc))) return false; else if (auto CS = ImmutableCallSite(C)) { // If we can't lift this before P, it's game over. - if (AA.getModRefInfo(P, CS) != MRI_NoModRef) + if (modOrRefSet(AA.getModRefInfo(P, CS))) return false; CallSites.push_back(CS); } else if (isa(C) || isa(C) || isa(C)) { // If we can't lift this before P, it's game over. auto ML = MemoryLocation::get(C); - if (AA.getModRefInfo(P, ML) != MRI_NoModRef) + if (modOrRefSet(AA.getModRefInfo(P, ML))) return false; MemLocs.push_back(ML); @@ -631,7 +631,7 @@ // of at the store position. Instruction *P = SI; for (auto &I : make_range(++LI->getIterator(), SI->getIterator())) { - if (AA.getModRefInfo(&I, LoadLoc) & MRI_Mod) { + if (modSet(AA.getModRefInfo(&I, LoadLoc))) { P = &I; break; } @@ -702,7 +702,7 @@ MemoryLocation StoreLoc = MemoryLocation::get(SI); for (BasicBlock::iterator I = --SI->getIterator(), E = C->getIterator(); I != E; --I) { - if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) { + if (modOrRefSet(AA.getModRefInfo(&*I, StoreLoc))) { C = nullptr; break; } @@ -934,9 +934,9 @@ AliasAnalysis &AA = LookupAliasAnalysis(); ModRefInfo MR = AA.getModRefInfo(C, cpyDest, srcSize); // If necessary, perform additional analysis. - if (MR != MRI_NoModRef) + if (modOrRefSet(MR)) MR = AA.callCapturesBefore(C, cpyDest, srcSize, &DT); - if (MR != MRI_NoModRef) + if (modOrRefSet(MR)) return false; // We can't create address space casts here because we don't know if they're