diff options
| author | Anna Thomas <anna@azul.com> | 2016-08-09 17:18:05 +0000 | 
|---|---|---|
| committer | Anna Thomas <anna@azul.com> | 2016-08-09 17:18:05 +0000 | 
| commit | 037e540f0842c33e72cbcb1ba7bf1659b170e852 (patch) | |
| tree | 9504498848defbf2e66316e9ad3469325e5844b9 /llvm/lib/Analysis | |
| parent | 4ee824a88d2e106c91a2f9f609d052440eff5659 (diff) | |
| download | bcm5719-llvm-037e540f0842c33e72cbcb1ba7bf1659b170e852.tar.gz bcm5719-llvm-037e540f0842c33e72cbcb1ba7bf1659b170e852.zip | |
[AliasAnalysis] Treat invariant.start as read-memory
Summary:
We teach alias analysis that invariant.start is readonly.
This helps with GVN and memcopy optimizations that currently treat.
invariant.start as a clobber.
We need to treat this as readonly, so that DSE does not incorrectly
remove stores prior to the invariant.start
Reviewers: sanjoy, reames, majnemer, dberlin
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D23214
llvm-svn: 278138
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 26 | 
1 files changed, 26 insertions, 0 deletions
| diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 89ae3d0ecce..84affa1caca 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -781,6 +781,32 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,    if (isIntrinsicCall(CS, Intrinsic::experimental_guard))      return MRI_Ref; +  // Like assumes, invariant.start intrinsics were also marked as arbitrarily +  // writing so that proper control dependencies are maintained but they never +  // mod any particular memory location visible to the IR. +  // *Unlike* assumes (which are now modeled as NoModRef), invariant.start +  // intrinsic is now modeled as reading memory. This prevents hoisting the +  // invariant.start intrinsic over stores. Consider: +  // *ptr = 40; +  // *ptr = 50; +  // invariant_start(ptr) +  // int val = *ptr; +  // print(val); +  // +  // This cannot be transformed to: +  // +  // *ptr = 40; +  // invariant_start(ptr) +  // *ptr = 50; +  // int val = *ptr; +  // print(val); +  // +  // The transformation will cause the second store to be ignored (based on +  // rules of invariant.start)  and print 40, while the first program always +  // prints 50. +  if (isIntrinsicCall(CS, Intrinsic::invariant_start)) +    return MRI_Ref; +    // The AAResultBase base class has some smarts, lets use them.    return AAResultBase::getModRefInfo(CS, Loc);  } | 

