diff options
author | Robin Morisset <morisset@google.com> | 2014-09-02 20:17:52 +0000 |
---|---|---|
committer | Robin Morisset <morisset@google.com> | 2014-09-02 20:17:52 +0000 |
commit | 4f6b93b1a88cb89af8b4bd922ee0ec5c14240a3c (patch) | |
tree | 479cd038e00f42e8b6a6eb48245c1c180dc4b5f4 /llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | |
parent | b2325b9ab36584c43b762295aa36db0a62413c93 (diff) | |
download | bcm5719-llvm-4f6b93b1a88cb89af8b4bd922ee0ec5c14240a3c.tar.gz bcm5719-llvm-4f6b93b1a88cb89af8b4bd922ee0ec5c14240a3c.zip |
Fix MemoryDependenceAnalysis in cases where QueryInstr is a CmpXchg or a AtomicRMW
Summary:
MemoryDependenceAnalysis is currently cautious when the QueryInstr is an atomic
load or store, but I forgot to check for atomic cmpxchg/atomicrmw. This patch
is a way of fixing that, and making it less brittle (i.e. no risk that I forget
another possible kind of atomic, even if the IR ends up changing in the future),
by adding a fallback checking mayReadOrWriteFromMemory.
Thanks to Philip Reames for finding this bug and suggesting this solution in
http://reviews.llvm.org/D4845
Sadly, I don't see how to add a test for this, since the passes depending on
MemoryDependenceAnalysis won't trigger for an atomic rmw anyway. Does anyone
see a way for testing it?
Test Plan: none possible at first sight
Reviewers: jfb, reames
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D5019
llvm-svn: 216940
Diffstat (limited to 'llvm/lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index aef241840ac..f7180aae69e 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -449,12 +449,16 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, if (!LI->isUnordered()) { if (!QueryInst) return MemDepResult::getClobber(LI); - if (auto *QueryLI = dyn_cast<LoadInst>(QueryInst)) + if (auto *QueryLI = dyn_cast<LoadInst>(QueryInst)) { if (!QueryLI->isSimple()) return MemDepResult::getClobber(LI); - if (auto *QuerySI = dyn_cast<StoreInst>(QueryInst)) + } else if (auto *QuerySI = dyn_cast<StoreInst>(QueryInst)) { if (!QuerySI->isSimple()) return MemDepResult::getClobber(LI); + } else if (QueryInst->mayReadOrWriteMemory()) { + return MemDepResult::getClobber(LI); + } + if (isAtLeastAcquire(LI->getOrdering())) HasSeenAcquire = true; } @@ -529,12 +533,16 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, if (!SI->isUnordered()) { if (!QueryInst) return MemDepResult::getClobber(SI); - if (auto *QueryLI = dyn_cast<LoadInst>(QueryInst)) + if (auto *QueryLI = dyn_cast<LoadInst>(QueryInst)) { if (!QueryLI->isSimple()) return MemDepResult::getClobber(SI); - if (auto *QuerySI = dyn_cast<StoreInst>(QueryInst)) + } else if (auto *QuerySI = dyn_cast<StoreInst>(QueryInst)) { if (!QuerySI->isSimple()) return MemDepResult::getClobber(SI); + } else if (QueryInst->mayReadOrWriteMemory()) { + return MemDepResult::getClobber(SI); + } + if (HasSeenAcquire && isAtLeastRelease(SI->getOrdering())) return MemDepResult::getClobber(SI); } |