diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index 79b743d67528c1..38e3c14f7ef9ca 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -156,6 +156,14 @@ void RecursivelyDeleteTriviallyDeadInstructions( SmallVectorImpl &DeadInsts, const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr); +/// Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow +/// instructions that are not trivially dead. These will be ignored. +/// Returns true if any changes were made, i.e. any instructions trivially dead +/// were found and deleted. +bool RecursivelyDeleteTriviallyDeadInstructionsPermissive( + SmallVectorImpl &DeadInsts, + const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr); + /// If the specified value is an effectively dead PHI node, due to being a /// def-use chain of single-use nodes that either forms a cycle or is terminated /// by a trivially dead instruction, delete it. If that makes any of its diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index e9f368628a087e..fef5508e3bda3f 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -962,33 +962,6 @@ static bool isHighCostExpansion(const SCEV *S, return true; } -/// If any of the instructions in the specified set are trivially dead, delete -/// them and see if this makes any of their operands subsequently dead. -static bool -DeleteTriviallyDeadInstructions(SmallVectorImpl &DeadInsts) { - bool Changed = false; - - while (!DeadInsts.empty()) { - Value *V = DeadInsts.pop_back_val(); - Instruction *I = dyn_cast_or_null(V); - - if (!I || !isInstructionTriviallyDead(I)) - continue; - - for (Use &O : I->operands()) - if (Instruction *U = dyn_cast(O)) { - O = nullptr; - if (U->use_empty()) - DeadInsts.emplace_back(U); - } - - I->eraseFromParent(); - Changed = true; - } - - return Changed; -} - namespace { class LSRUse; @@ -3212,7 +3185,8 @@ void LSRInstance::GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter, IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy, "lsr.chain"); } Inc.UserInst->replaceUsesOfWith(Inc.IVOperand, IVOper); - DeadInsts.emplace_back(Inc.IVOperand); + if (auto *OperandIsInstr = dyn_cast(Inc.IVOperand)) + DeadInsts.emplace_back(OperandIsInstr); } // If LSR created a new, wider phi, we may also replace its postinc. We only // do this if we also found a wide value for the head of the chain. @@ -5268,7 +5242,8 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF, // form, update the ICmp's other operand. if (LU.Kind == LSRUse::ICmpZero) { ICmpInst *CI = cast(LF.UserInst); - DeadInsts.emplace_back(CI->getOperand(1)); + if (auto *OperandIsInstr = dyn_cast(CI->getOperand(1))) + DeadInsts.emplace_back(OperandIsInstr); assert(!F.BaseGV && "ICmp does not support folding a global value and " "a scale at the same time!"); if (F.Scale == -1) { @@ -5449,7 +5424,8 @@ void LSRInstance::Rewrite(const LSRUse &LU, const LSRFixup &LF, LF.UserInst->replaceUsesOfWith(LF.OperandValToReplace, FullV); } - DeadInsts.emplace_back(LF.OperandValToReplace); + if (auto *OperandIsInstr = dyn_cast(LF.OperandValToReplace)) + DeadInsts.emplace_back(OperandIsInstr); } /// Rewrite all the fixup locations with new values, following the chosen @@ -5490,7 +5466,7 @@ void LSRInstance::ImplementSolution( // instructions. Rewriter.clear(); - Changed |= DeleteTriviallyDeadInstructions(DeadInsts); + Changed |= RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts); } LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE, @@ -5727,7 +5703,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE, unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &TTI); if (numFolded) { Changed = true; - DeleteTriviallyDeadInstructions(DeadInsts); + RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts); DeleteDeadPHIs(L->getHeader()); } } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 10afed347180b8..aad960230f5ceb 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -450,6 +450,23 @@ bool llvm::RecursivelyDeleteTriviallyDeadInstructions( return true; } +bool llvm::RecursivelyDeleteTriviallyDeadInstructionsPermissive( + SmallVectorImpl &DeadInsts, const TargetLibraryInfo *TLI, + MemorySSAUpdater *MSSAU) { + unsigned S = 0, E = DeadInsts.size(), Alive = 0; + for (; S != E; ++S) { + auto *I = cast(DeadInsts[S]); + if (!isInstructionTriviallyDead(I)) { + DeadInsts[S] = nullptr; + ++Alive; + } + } + if (Alive == E) + return false; + RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, TLI, MSSAU); + return true; +} + void llvm::RecursivelyDeleteTriviallyDeadInstructions( SmallVectorImpl &DeadInsts, const TargetLibraryInfo *TLI, MemorySSAUpdater *MSSAU) {