diff options
| author | Max Kazantsev <max.kazantsev@azul.com> | 2017-11-28 07:07:55 +0000 |
|---|---|---|
| committer | Max Kazantsev <max.kazantsev@azul.com> | 2017-11-28 07:07:55 +0000 |
| commit | 115607226a12f6dbaa2b9e32a36089a9685daa7e (patch) | |
| tree | 3846ff78cbc20a0d337dd3d4bc00935865f69074 /llvm/lib/Transforms | |
| parent | bf74f64e6718b73f48da255c7331d6d5ab3c601e (diff) | |
| download | bcm5719-llvm-115607226a12f6dbaa2b9e32a36089a9685daa7e.tar.gz bcm5719-llvm-115607226a12f6dbaa2b9e32a36089a9685daa7e.zip | |
[GVN] Prevent ScalarPRE from hoisting across instructions that don't pass control flow to successors
This is to address a problem similar to those in D37460 for Scalar PRE. We should not
PRE across an instruction that may not pass execution to its successor unless it is safe
to speculatively execute it.
Differential Revision: https://reviews.llvm.org/D38619
llvm-svn: 319147
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index b031f905eba..76e295c1ad2 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2255,6 +2255,20 @@ bool GVN::performScalarPRE(Instruction *CurInst) { Instruction *PREInstr = nullptr; if (NumWithout != 0) { + if (!isSafeToSpeculativelyExecute(CurInst)) { + // It is only valid to insert a new instruction if the current instruction + // is always executed. An instruction with implicit control flow could + // prevent us from doing it. If we cannot speculate the execution, then + // PRE should be prohibited. + auto It = FirstImplicitControlFlowInsts.find(CurrentBlock); + if (It != FirstImplicitControlFlowInsts.end()) { + assert(It->second->getParent() == CurrentBlock && + "Implicit control flow map broken?"); + if (OI->dominates(It->second, CurInst)) + return false; + } + } + // Don't do PRE across indirect branch. if (isa<IndirectBrInst>(PREPred->getTerminator())) return false; |

