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);
return &BI;
}
+ if (isa<UndefValue>(Cond) && handlePotentiallyDeadSuccessors(
+ BI.getParent(), /*LiveSucc*/ nullptr, *this))
+ return &BI;
+ if (auto *CI = dyn_cast<ConstantInt>(Cond))
+ if (handlePotentiallyDeadSuccessors(
+ BI.getParent(), BI.getSuccessor(!CI->getZExtValue()), *this))
+ return &BI;
+
return nullptr;
}
return replaceOperand(SI, 0, Op0);
}
+ if (isa<UndefValue>(Cond) && handlePotentiallyDeadSuccessors(
+ SI.getParent(), /*LiveSucc*/ nullptr, *this))
+ return &SI;
+ if (auto *CI = dyn_cast<ConstantInt>(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();