summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2017-10-11 07:26:45 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2017-10-11 07:26:45 +0000
commit0c8dd052b828ca2f0bcbad5398cef010d60649d4 (patch)
tree3334cde8d547242769601770a1c54d504ff31e95 /llvm/lib/Transforms
parent25d8655dc22cae27c2c5190577370e558c5afff5 (diff)
downloadbcm5719-llvm-0c8dd052b828ca2f0bcbad5398cef010d60649d4.tar.gz
bcm5719-llvm-0c8dd052b828ca2f0bcbad5398cef010d60649d4.zip
[LICM] Disallow sinking of unordered atomic loads into loops
Sinking of unordered atomic load into loop must be disallowed because it turns a single load into multiple loads. The relevant section of the documentation is: http://llvm.org/docs/Atomics.html#unordered, specifically the Notes for Optimizers section. Here is the full text of this section: > Notes for optimizers > In terms of the optimizer, this **prohibits any transformation that > transforms a single load into multiple loads**, transforms a store into > multiple stores, narrows a store, or stores a value which would not be > stored otherwise. Some examples of unsafe optimizations are narrowing > an assignment into a bitfield, rematerializing a load, and turning loads > and stores into a memcpy call. Reordering unordered operations is safe, > though, and optimizers should take advantage of that because unordered > operations are common in languages that need them. Patch by Daniil Suchkov! Reviewed By: reames Differential Revision: https://reviews.llvm.org/D38392 llvm-svn: 315438
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/LICM.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 5e8ed5f3a75..0cc70d42447 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -577,10 +577,13 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
Loop *CurLoop, AliasSetTracker *CurAST,
LoopSafetyInfo *SafetyInfo,
OptimizationRemarkEmitter *ORE) {
+ // SafetyInfo is nullptr if we are checking for sinking from preheader to
+ // loop body.
+ const bool SinkingToLoopBody = !SafetyInfo;
// Loads have extra constraints we have to verify before we can hoist them.
if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
if (!LI->isUnordered())
- return false; // Don't hoist volatile/atomic loads!
+ return false; // Don't sink/hoist volatile or ordered atomic loads!
// Loads from constant memory are always safe to move, even if they end up
// in the same alias set as something that ends up being modified.
@@ -589,6 +592,9 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
if (LI->getMetadata(LLVMContext::MD_invariant_load))
return true;
+ if (LI->isAtomic() && SinkingToLoopBody)
+ return false; // Don't sink unordered atomic loads to loop body.
+
// This checks for an invariant.start dominating the load.
if (isLoadInvariantInLoop(LI, DT, CurLoop))
return true;
@@ -664,9 +670,9 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
!isa<InsertValueInst>(I))
return false;
- // SafetyInfo is nullptr if we are checking for sinking from preheader to
- // loop body. It will be always safe as there is no speculative execution.
- if (!SafetyInfo)
+ // If we are checking for sinking from preheader to loop body it will be
+ // always safe as there is no speculative execution.
+ if (SinkingToLoopBody)
return true;
// TODO: Plumb the context instruction through to make hoisting and sinking
OpenPOWER on IntegriCloud