summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-06-13 18:30:14 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-06-13 18:30:14 +0000
commit0ffb2271a1e60de368fc6b0b1df4595220981a8d (patch)
tree75728e9095837e73b3f11de93d6feac3ee575ef0 /llvm/tools/llvm-mca
parentd71614a438b4c9a6c595c695e86e8d24e6070fac (diff)
downloadbcm5719-llvm-0ffb2271a1e60de368fc6b0b1df4595220981a8d.tar.gz
bcm5719-llvm-0ffb2271a1e60de368fc6b0b1df4595220981a8d.zip
[llvm-mca] Fixed a bug in the logic that checks if a memory operation is ready to execute.
Fixes PR37790. In some (very rare) cases, the LSUnit (Load/Store unit) was wrongly marking a load (or store) as "ready to execute" effectively bypassing older memory barrier instructions. To reproduce this bug, the memory barrier must be the first instruction in the input assembly sequence, and it doesn't have to perform any register writes. llvm-svn: 334633
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r--llvm/tools/llvm-mca/LSUnit.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/llvm/tools/llvm-mca/LSUnit.cpp b/llvm/tools/llvm-mca/LSUnit.cpp
index dfd3e53fb49..c2f3b9dd5a0 100644
--- a/llvm/tools/llvm-mca/LSUnit.cpp
+++ b/llvm/tools/llvm-mca/LSUnit.cpp
@@ -78,18 +78,16 @@ bool LSUnit::isReady(const InstRef &IR) const {
bool IsAStore = StoreQueue.count(Index) != 0;
assert((IsALoad || IsAStore) && "Instruction is not in queue!");
- unsigned LoadBarrierIndex = LoadBarriers.empty() ? 0 : *LoadBarriers.begin();
- unsigned StoreBarrierIndex =
- StoreBarriers.empty() ? 0 : *StoreBarriers.begin();
-
- if (IsALoad && LoadBarrierIndex) {
+ if (IsALoad && !LoadBarriers.empty()) {
+ unsigned LoadBarrierIndex = *LoadBarriers.begin();
if (Index > LoadBarrierIndex)
return false;
if (Index == LoadBarrierIndex && Index != *LoadQueue.begin())
return false;
}
- if (IsAStore && StoreBarrierIndex) {
+ if (IsAStore && !StoreBarriers.empty()) {
+ unsigned StoreBarrierIndex = *StoreBarriers.begin();
if (Index > StoreBarrierIndex)
return false;
if (Index == StoreBarrierIndex && Index != *StoreQueue.begin())
@@ -135,9 +133,15 @@ void LSUnit::onInstructionExecuted(const InstRef &IR) {
StoreQueue.erase(it);
}
- if (!StoreBarriers.empty() && Index == *StoreBarriers.begin())
+ if (!StoreBarriers.empty() && Index == *StoreBarriers.begin()) {
+ LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
+ << " has been removed from the set of store barriers.\n");
StoreBarriers.erase(StoreBarriers.begin());
- if (!LoadBarriers.empty() && Index == *LoadBarriers.begin())
+ }
+ if (!LoadBarriers.empty() && Index == *LoadBarriers.begin()) {
+ LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
+ << " has been removed from the set of load barriers.\n");
LoadBarriers.erase(LoadBarriers.begin());
+ }
}
} // namespace mca
OpenPOWER on IntegriCloud