Index: llvm/trunk/lib/Analysis/AliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp @@ -126,7 +126,7 @@ // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) - return Result; + return ModRefInfo::NoModRef; } return Result; @@ -162,7 +162,7 @@ // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) - return Result; + return ModRefInfo::NoModRef; } // Try to refine the mod-ref info further using other API entry points to the @@ -224,7 +224,7 @@ // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) - return Result; + return ModRefInfo::NoModRef; } // Try to refine the mod-ref info further using other API entry points to the @@ -254,85 +254,91 @@ // information from CS1's references to the memory referenced by // CS2's arguments. if (onlyAccessesArgPointees(CS2B)) { + if (!doesAccessArgPointees(CS2B)) + return ModRefInfo::NoModRef; ModRefInfo R = ModRefInfo::NoModRef; - if (doesAccessArgPointees(CS2B)) { - bool IsMustAlias = true; - for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) - continue; - unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); - auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); - - // 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 = ModRefInfo::NoModRef; - if (isModSet(ArgModRefCS2)) - ArgMask = ModRefInfo::ModRef; - else if (isRefSet(ArgModRefCS2)) - ArgMask = ModRefInfo::Mod; - - // ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use - // above ArgMask to update dependence info. - ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc); - ArgMask = intersectModRef(ArgMask, ModRefCS1); - - // Conservatively clear IsMustAlias unless only MustAlias is found. - IsMustAlias &= isMustSet(ModRefCS1); - - R = intersectModRef(unionModRef(R, ArgMask), Result); - if (R == Result) { - // On early exit, not all args were checked, cannot set Must. - if (I + 1 != E) - IsMustAlias = false; - break; - } + bool IsMustAlias = true; + for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); + auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); + + // 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 = ModRefInfo::NoModRef; + if (isModSet(ArgModRefCS2)) + ArgMask = ModRefInfo::ModRef; + else if (isRefSet(ArgModRefCS2)) + ArgMask = ModRefInfo::Mod; + + // ModRefCS1 indicates what CS1 might do to CS2ArgLoc, and we use + // above ArgMask to update dependence info. + ModRefInfo ModRefCS1 = getModRefInfo(CS1, CS2ArgLoc); + ArgMask = intersectModRef(ArgMask, ModRefCS1); + + // Conservatively clear IsMustAlias unless only MustAlias is found. + IsMustAlias &= isMustSet(ModRefCS1); + + R = intersectModRef(unionModRef(R, ArgMask), Result); + if (R == Result) { + // On early exit, not all args were checked, cannot set Must. + if (I + 1 != E) + IsMustAlias = false; + break; } - // If Alias found and only MustAlias found above, set Must bit. - R = IsMustAlias ? setMust(R) : clearMust(R); } - return R; + + if (isNoModRef(R)) + return ModRefInfo::NoModRef; + + // If MustAlias found above, set Must bit. + return IsMustAlias ? setMust(R) : clearMust(R); } // If CS1 only accesses memory through arguments, check if CS2 references // any of the memory referenced by CS1's arguments. If not, return NoModRef. if (onlyAccessesArgPointees(CS1B)) { + if (!doesAccessArgPointees(CS1B)) + return ModRefInfo::NoModRef; ModRefInfo R = ModRefInfo::NoModRef; - if (doesAccessArgPointees(CS1B)) { - bool IsMustAlias = true; - for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) - continue; - unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); - auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); - - // 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 ((isModSet(ArgModRefCS1) && isModOrRefSet(ModRefCS2)) || - (isRefSet(ArgModRefCS1) && isModSet(ModRefCS2))) - R = intersectModRef(unionModRef(R, ArgModRefCS1), Result); - - // Conservatively clear IsMustAlias unless only MustAlias is found. - IsMustAlias &= isMustSet(ModRefCS2); - - if (R == Result) { - // On early exit, not all args were checked, cannot set Must. - if (I + 1 != E) - IsMustAlias = false; - break; - } + bool IsMustAlias = true; + for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); + auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); + + // 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 ((isModSet(ArgModRefCS1) && isModOrRefSet(ModRefCS2)) || + (isRefSet(ArgModRefCS1) && isModSet(ModRefCS2))) + R = intersectModRef(unionModRef(R, ArgModRefCS1), Result); + + // Conservatively clear IsMustAlias unless only MustAlias is found. + IsMustAlias &= isMustSet(ModRefCS2); + + if (R == Result) { + // On early exit, not all args were checked, cannot set Must. + if (I + 1 != E) + IsMustAlias = false; + break; } - // If Alias found and only MustAlias found above, set Must bit. - R = IsMustAlias ? setMust(R) : clearMust(R); } - return R; + + if (isNoModRef(R)) + return ModRefInfo::NoModRef; + + // If MustAlias found above, set Must bit. + return IsMustAlias ? setMust(R) : clearMust(R); } return Result; Index: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp @@ -852,8 +852,11 @@ IsMustAlias = false; // Early return if we improved mod ref information - if (!isModAndRefSet(Result)) + if (!isModAndRefSet(Result)) { + if (isNoModRef(Result)) + return ModRefInfo::NoModRef; return IsMustAlias ? setMust(Result) : clearMust(Result); + } } // If the CallSite is to malloc or calloc, we can assume that it doesn't