summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis')
-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 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);
}
OpenPOWER on IntegriCloud