Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -143,9 +143,9 @@ static bool inSubLoop(BasicBlock *BB, Loop *CurLoop, LoopInfo *LI); static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop, + const Loop *OutermostLoop, const LoopSafetyInfo *SafetyInfo, - TargetTransformInfo *TTI, bool &FreeInLoop, - bool LoopNestMode); + TargetTransformInfo *TTI, bool &FreeInLoop); static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU, ScalarEvolution *SE, @@ -551,12 +551,11 @@ // operands of the instruction are loop invariant. // bool FreeInLoop = false; - bool LoopNestMode = OutermostLoop != nullptr; if (!I.mayHaveSideEffects() && - isNotUsedOrFreeInLoop(I, LoopNestMode ? OutermostLoop : CurLoop, - SafetyInfo, TTI, FreeInLoop, LoopNestMode) && - canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/nullptr, MSSAU, true, - &Flags, ORE)) { + isNotUsedOrFreeInLoop(I, CurLoop, OutermostLoop, SafetyInfo, TTI, + FreeInLoop) && + canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/ nullptr, MSSAU, + true, &Flags, ORE)) { if (sink(I, LI, DT, BFI, CurLoop, SafetyInfo, MSSAU, ORE)) { if (!FreeInLoop) { ++II; @@ -1410,11 +1409,12 @@ /// We also return true if the instruction could be folded away in lowering. /// (e.g., a GEP can be folded into a load as an addressing mode in the loop). static bool isNotUsedOrFreeInLoop(const Instruction &I, const Loop *CurLoop, + const Loop *OutermostLoop, const LoopSafetyInfo *SafetyInfo, - TargetTransformInfo *TTI, bool &FreeInLoop, - bool LoopNestMode) { + TargetTransformInfo *TTI, bool &FreeInLoop) { const auto &BlockColors = SafetyInfo->getBlockColors(); - bool IsFree = isFreeInLoop(I, CurLoop, TTI); + const bool LoopNestMode = OutermostLoop != nullptr; + bool IsFree = isFreeInLoop(I, LoopNestMode ? OutermostLoop : CurLoop, TTI); for (const User *U : I.users()) { const Instruction *UI = cast(U); if (const PHINode *PN = dyn_cast(UI)) { @@ -1433,14 +1433,16 @@ if (LoopNestMode) { while (isa(UI) && UI->hasOneUser() && UI->getNumOperands() == 1) { - if (!CurLoop->contains(UI)) + if (CurLoop == OutermostLoop && CurLoop->contains(UI)) + break; + if (!OutermostLoop->contains(UI)) break; UI = cast(UI->user_back()); } } } - if (CurLoop->contains(UI)) { + if ((LoopNestMode ? OutermostLoop : CurLoop)->contains(UI)) { if (IsFree) { FreeInLoop = true; continue; Index: llvm/test/Transforms/LICM/lnicm-crash.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LICM/lnicm-crash.ll @@ -0,0 +1,23 @@ +; RUN: opt -passes='loop-mssa(licm)' -S %s +; RUN: opt -passes='loop-mssa(lnicm)' -S %s + +define void @main() { +entry: + br label %for.body1143 + +land.rhs1135: ; preds = %for.body1143 + %v_299.017 = phi i40 [ %0, %for.body1143 ] + br i1 true, label %land.rhs1135.for.cond.cleanup1952_crit_edge, label %for.body1143 + +for.body1143: ; preds = %land.rhs1135, %entry + %0 = select i1 undef, i40 undef, i40 253841517325 + br i1 true, label %for.body1143.for.cond.cleanup1952_crit_edge, label %land.rhs1135 + +for.body1143.for.cond.cleanup1952_crit_edge: ; preds = %for.body1143 + %split = phi i40 [ %0, %for.body1143 ] + unreachable + +land.rhs1135.for.cond.cleanup1952_crit_edge: ; preds = %land.rhs1135 + %split1 = phi i40 [ %v_299.017, %land.rhs1135 ] + unreachable +}