Index: include/llvm/Transforms/Utils/LoopUtils.h =================================================================== --- include/llvm/Transforms/Utils/LoopUtils.h +++ include/llvm/Transforms/Utils/LoopUtils.h @@ -474,15 +474,13 @@ void getLoopAnalysisUsage(AnalysisUsage &AU); /// Returns true if the hoister and sinker can handle this instruction. -/// If SafetyInfo is null, we are checking for sinking instructions from -/// preheader to loop body (no speculation). -/// If SafetyInfo is not null, we are checking for hoisting/sinking -/// instructions from loop body to preheader/exit. Check if the instruction -/// can execute specultatively. +/// NOTE: this function only checks whether its legal to sink or hoist, +/// it does not check whether its safe, e.g. a load can be legal to hoist +/// or sink out of a loop as there is no write in the loop, but may not be safe +/// as it might be loading a no-dereferenceable pointer. /// bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, - Loop *CurLoop, AliasSetTracker *CurAST, - LoopSafetyInfo *SafetyInfo); + Loop *CurLoop, AliasSetTracker *CurAST); } #endif Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -363,7 +363,7 @@ // operands of the instruction are loop invariant. // if (isNotUsedInLoop(I, CurLoop, SafetyInfo) && - canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo)) { + canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST)) { ++II; Changed |= sink(I, LI, DT, CurLoop, CurAST, SafetyInfo); } @@ -413,10 +413,10 @@ // Try hoisting the instruction out to the preheader. We can only do this // if all of the operands of the instruction are loop invariant and if it - // is safe to hoist the instruction. + // is legal and safe to hoist the instruction. // if (CurLoop->hasLoopInvariantOperands(&I) && - canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo) && + canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST) && isSafeToExecuteUnconditionally( I, DT, CurLoop, SafetyInfo, CurLoop->getLoopPreheader()->getTerminator())) @@ -463,12 +463,21 @@ } bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, - Loop *CurLoop, AliasSetTracker *CurAST, - LoopSafetyInfo *SafetyInfo) { - // Loads have extra constraints we have to verify before we can hoist them. + Loop *CurLoop, AliasSetTracker *CurAST) { + + // These instructions work on SSA values and are therefore hoistable/sinkable. + if (isa(I) || isa(I) || isa(I) || + isa(I) || isa(I) || + isa(I) || isa(I) || + isa(I) || isa(I) || + isa(I)) + return true; + + // Loads have extra constraints we have to verify before we can hoist or sink + // them. if (LoadInst *LI = dyn_cast(&I)) { if (!LI->isUnordered()) - return false; // Don't hoist volatile/atomic loads! + return false; // Don't hoist or sink volatile/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. @@ -477,7 +486,7 @@ if (LI->getMetadata(LLVMContext::MD_invariant_load)) return true; - // Don't hoist loads which have may-aliased stores in loop. + // Don't hoist or sink loads which have may-aliased stores in loop. uint64_t Size = 0; if (LI->getType()->isSized()) Size = I.getModule()->getDataLayout().getTypeStoreSize(LI->getType()); @@ -491,7 +500,7 @@ if (isa(I)) return false; - // Don't sink calls which can throw. + // Don't hoist or sink calls which can throw. if (CI->mayThrow()) return false; @@ -530,23 +539,8 @@ return false; } - // Only these instructions are hoistable/sinkable. - if (!isa(I) && !isa(I) && !isa(I) && - !isa(I) && !isa(I) && - !isa(I) && !isa(I) && - !isa(I) && !isa(I) && - !isa(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) - return true; - - // TODO: Plumb the context instruction through to make hoisting and sinking - // more powerful. Hoisting of loads already works due to the special casing - // above. - return isSafeToExecuteUnconditionally(I, DT, CurLoop, SafetyInfo, nullptr); + // We do not know much about this instruction, return conservatively. + return false; } /// Returns true if a PHINode is a trivially replaceable with an Index: lib/Transforms/Scalar/LoopSink.cpp =================================================================== --- lib/Transforms/Scalar/LoopSink.cpp +++ lib/Transforms/Scalar/LoopSink.cpp @@ -284,7 +284,7 @@ for (auto II = Preheader->rbegin(), E = Preheader->rend(); II != E;) { Instruction *I = &*II++; if (!L.hasLoopInvariantOperands(I) || - !canSinkOrHoistInst(*I, &AA, &DT, &L, &CurAST, nullptr)) + !canSinkOrHoistInst(*I, &AA, &DT, &L, &CurAST)) continue; if (sinkInstruction(L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI)) Changed = true;