aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2016-08-09 17:18:05 +0000
committerAnna Thomas <anna@azul.com>2016-08-09 17:18:05 +0000
commit037e540f0842c33e72cbcb1ba7bf1659b170e852 (patch)
tree9504498848defbf2e66316e9ad3469325e5844b9 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parent4ee824a88d2e106c91a2f9f609d052440eff5659 (diff)
downloadllvm-037e540f0842c33e72cbcb1ba7bf1659b170e852.zip
llvm-037e540f0842c33e72cbcb1ba7bf1659b170e852.tar.gz
llvm-037e540f0842c33e72cbcb1ba7bf1659b170e852.tar.bz2
[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/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 89ae3d0..84affa1 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);
}