From d8c9374797ccb9520b6ef7bdb29ed3a4bb5a1be2 Mon Sep 17 00:00:00 2001 From: Stanislav Mekhanoshin Date: Sat, 23 Jun 2018 04:01:28 +0000 Subject: Fix invariant fdiv hoisting in LICM FDiv is replaced with multiplication by reciprocal and invariant reciprocal is hoisted out of the loop, while multiplication remains even if invariant. Switch checks for all invariant operands and only invariant denominator to fix the issue. Differential Revision: https://reviews.llvm.org/D48447 llvm-svn: 335411 --- llvm/lib/Transforms/Scalar/LICM.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 412f2678184..10f386064f9 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -477,6 +477,20 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, continue; } + // 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. + // + if (CurLoop->hasLoopInvariantOperands(&I) && + canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) && + (IsMustExecute || + isSafeToExecuteUnconditionally( + I, DT, CurLoop, SafetyInfo, ORE, + CurLoop->getLoopPreheader()->getTerminator()))) { + Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE); + continue; + } + // Attempt to remove floating point division out of the loop by // converting it to a reciprocal multiplication. if (I.getOpcode() == Instruction::FDiv && @@ -500,20 +514,6 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, continue; } - // 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. - // - if (CurLoop->hasLoopInvariantOperands(&I) && - canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) && - (IsMustExecute || - isSafeToExecuteUnconditionally( - I, DT, CurLoop, SafetyInfo, ORE, - CurLoop->getLoopPreheader()->getTerminator()))) { - Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE); - continue; - } - if (IsMustExecute) IsMustExecute = isGuaranteedToTransferExecutionToSuccessor(&I); } -- cgit v1.2.3