summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-06-10 20:03:20 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-06-10 20:03:20 +0000
commiteaea297df46887d801e05311be7ad195ff57d1ae (patch)
tree08e14682d026d90e763d9b3fcecfd7f09c0fa5f8 /llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
parent122f984a33e91425133fee186f87d24d03bbf089 (diff)
downloadbcm5719-llvm-eaea297df46887d801e05311be7ad195ff57d1ae.tar.gz
bcm5719-llvm-eaea297df46887d801e05311be7ad195ff57d1ae.zip
Disable MSan-hostile loop unswitching.
Loop unswitching may cause MSan false positive when the unswitch condition is not guaranteed to execute. This is very similar to ASan and TSan special case in llvm::isSafeToSpeculativelyExecute (they don't like speculative loads and stores), but for branch instructions. This is a workaround for PR28054. llvm-svn: 272421
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopUnswitch.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopUnswitch.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
index 0e861b638d6..30aae21c90c 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -188,6 +188,9 @@ namespace {
BasicBlock *loopHeader;
BasicBlock *loopPreheader;
+ bool SanitizeMemory;
+ LoopSafetyInfo SafetyInfo;
+
// LoopBlocks contains all of the basic blocks of the loop, including the
// preheader of the loop, the body of the loop, and the exit blocks of the
// loop, in that order.
@@ -431,6 +434,10 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
currentLoop = L;
Function *F = currentLoop->getHeader()->getParent();
+ SanitizeMemory = F->hasFnAttribute(Attribute::SanitizeMemory);
+ if (SanitizeMemory)
+ computeLoopSafetyInfo(&SafetyInfo, L);
+
EnabledPGO = F->getEntryCount().hasValue();
if (LoopUnswitchWithBlockFrequency && EnabledPGO) {
@@ -530,6 +537,17 @@ bool LoopUnswitch::processCurrentLoop() {
for (Loop::block_iterator I = currentLoop->block_begin(),
E = currentLoop->block_end(); I != E; ++I) {
TerminatorInst *TI = (*I)->getTerminator();
+
+ // Unswitching on a potentially uninitialized predicate is not
+ // MSan-friendly. Limit this to the cases when the original predicate is
+ // guaranteed to execute, to avoid creating a use-of-uninitialized-value
+ // in the code that did not have one.
+ // This is a workaround for the discrepancy between LLVM IR and MSan
+ // semantics. See PR28054 for more details.
+ if (SanitizeMemory &&
+ !isGuaranteedToExecute(*TI, DT, currentLoop, &SafetyInfo))
+ continue;
+
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
// If this isn't branching on an invariant condition, we can't unswitch
// it.
OpenPOWER on IntegriCloud