From: Nikita Popov Date: Wed, 24 May 2023 14:47:15 +0000 (+0200) Subject: [InstCombine] Remove instructions in dead blocks during combining X-Git-Tag: upstream/17.0.6~7053 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca18e21951a89f3115694fc64cd64a4b06cd5873;p=platform%2Fupstream%2Fllvm.git [InstCombine] Remove instructions in dead blocks during combining We already do this during initial worklist population. Doing this as part of primary combining allows us to remove instructions in blocks that were rendered dead by condition folding within the same instcombine iteration. --- diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 0df85be..2af6ba5 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2550,6 +2550,41 @@ Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) { return nullptr; } +/// If a block is dead due to a known branch condition, remove instructions +/// in it. +static bool handlePotentiallyDeadBlock(BasicBlock *BB, InstCombiner &IC) { + // We only know one edge to this block is dead, but there may be others. + // TODO: We could track dead edges globally. + if (!BB->getSinglePredecessor()) + return false; + + bool Changed = false; + for (Instruction &Inst : make_early_inc_range(make_range( + std::next(BB->getTerminator()->getReverseIterator()), BB->rend()))) { + if (!Inst.use_empty() && !Inst.getType()->isTokenTy()) { + IC.replaceInstUsesWith(Inst, PoisonValue::get(Inst.getType())); + Changed = true; + } + if (Inst.isEHPad() || Inst.getType()->isTokenTy()) + continue; + IC.eraseInstFromFunction(Inst); + Changed = true; + } + + // TODO: Successor blocks may also be dead. + return Changed; +} + +static bool handlePotentiallyDeadSuccessors(BasicBlock *BB, + BasicBlock *LiveSucc, + InstCombiner &IC) { + bool Changed = false; + for (BasicBlock *Succ : successors(BB)) + if (Succ != LiveSucc) + Changed |= handlePotentiallyDeadBlock(Succ, IC); + return Changed; +} + Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) { if (BI.isUnconditional()) return visitUnconditionalBranchInst(BI); @@ -2593,6 +2628,14 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) { return &BI; } + if (isa(Cond) && handlePotentiallyDeadSuccessors( + BI.getParent(), /*LiveSucc*/ nullptr, *this)) + return &BI; + if (auto *CI = dyn_cast(Cond)) + if (handlePotentiallyDeadSuccessors( + BI.getParent(), BI.getSuccessor(!CI->getZExtValue()), *this)) + return &BI; + return nullptr; } @@ -2611,6 +2654,14 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) { return replaceOperand(SI, 0, Op0); } + if (isa(Cond) && handlePotentiallyDeadSuccessors( + SI.getParent(), /*LiveSucc*/ nullptr, *this)) + return &SI; + if (auto *CI = dyn_cast(Cond)) + if (handlePotentiallyDeadSuccessors( + SI.getParent(), SI.findCaseValue(CI)->getCaseSuccessor(), *this)) + return &SI; + KnownBits Known = computeKnownBits(Cond, 0, &SI); unsigned LeadingKnownZeros = Known.countMinLeadingZeros(); unsigned LeadingKnownOnes = Known.countMinLeadingOnes(); diff --git a/llvm/test/Transforms/InstCombine/unreachable-code.ll b/llvm/test/Transforms/InstCombine/unreachable-code.ll index 4a85d08..7f17dfa 100644 --- a/llvm/test/Transforms/InstCombine/unreachable-code.ll +++ b/llvm/test/Transforms/InstCombine/unreachable-code.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 -; RUN: opt -S -passes=instcombine < %s | FileCheck %s +; RUN: opt -S -passes=instcombine -instcombine-infinite-loop-threshold=2 < %s | FileCheck %s declare void @dummy()