diff options
author | Owen Anderson <resistor@mac.com> | 2011-09-06 23:33:25 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-09-06 23:33:25 +0000 |
commit | 69acc93b3de6854732a6d91b581c3c29b59bb315 (patch) | |
tree | 77f25d822e627c9e81cd1ed78290b65219a20dc5 /lib/Analysis/BasicAliasAnalysis.cpp | |
parent | 218affc710a0165746ec21a3315c6cc68272cfd5 (diff) |
Teach BasicAA about the aliasing properties of memset_pattern16.
Fixes PR10872 and <rdar://problem/10065079>.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139204 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 01257a1f2a..4964c8c209 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -30,6 +30,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLibraryInfo.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" @@ -468,6 +469,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<AliasAnalysis>(); + AU.addRequired<TargetLibraryInfo>(); } virtual AliasResult alias(const Location &LocA, @@ -550,10 +552,15 @@ namespace { // Register this pass... char BasicAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS(BasicAliasAnalysis, AliasAnalysis, "basicaa", +INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa", + "Basic Alias Analysis (stateless AA impl)", + false, true, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) +INITIALIZE_AG_PASS_END(BasicAliasAnalysis, AliasAnalysis, "basicaa", "Basic Alias Analysis (stateless AA impl)", false, true, false) + ImmutablePass *llvm::createBasicAliasAnalysisPass() { return new BasicAliasAnalysis(); } @@ -717,6 +724,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, return NoModRef; } + const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>(); ModRefResult Min = ModRef; // Finally, handle specific knowledge of intrinsics. @@ -819,6 +827,37 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, } } + // We can bound the aliasing properties of memset_pattern16 just as we can + // for memcpy/memset. This is particularly important because the + // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 + // whenever possible. + else if (TLI.has(LibFunc::memset_pattern16) && + CS.getCalledFunction() && + CS.getCalledFunction()->getName() == "memset_pattern16") { + const Function *MS = CS.getCalledFunction(); + FunctionType *MemsetType = MS->getFunctionType(); + if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 && + isa<PointerType>(MemsetType->getParamType(0)) && + isa<PointerType>(MemsetType->getParamType(1)) && + isa<IntegerType>(MemsetType->getParamType(2))) { + uint64_t Len = UnknownSize; + if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2))) + Len = LenCI->getZExtValue(); + const Value *Dest = CS.getArgument(0); + const Value *Src = CS.getArgument(1); + // If it can't overlap the source dest, then it doesn't modref the loc. + if (isNoAlias(Location(Dest, Len), Loc)) { + if (isNoAlias(Location(Src, 2), Loc)) + return NoModRef; + // If it can't overlap the dest, then worst case it reads the loc. + Min = Ref; + } else if (isNoAlias(Location(Src, 2), Loc)) { + // If it can't overlap the source, then worst case it mutates the loc. + Min = Mod; + } + } + } + // The AliasAnalysis base class has some smarts, lets use them. return ModRefResult(AliasAnalysis::getModRefInfo(CS, Loc) & Min); } |