Skip to content

Commit ffc7b77

Browse files
committed
[SimplifyCFG] Simplify uncond br with icmp & select
1 parent 22a10c8 commit ffc7b77

File tree

1 file changed

+175
-2
lines changed

1 file changed

+175
-2
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ class SimplifyCFGOpt {
301301

302302
bool tryToSimplifyUncondBranchWithICmpInIt(ICmpInst *ICI,
303303
IRBuilder<> &Builder);
304-
304+
bool tryToSimplifyUncondBranchWithICmpSelectInIt(ICmpInst *ICI,
305+
SelectInst *Select,
306+
IRBuilder<> &Builder);
305307
bool hoistCommonCodeFromSuccessors(Instruction *TI, bool AllInstsEqOnly);
306308
bool hoistSuccIdenticalTerminatorToSwitchOrIf(
307309
Instruction *TI, Instruction *I1,
@@ -5116,6 +5118,172 @@ bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpInIt(
51165118
return true;
51175119
}
51185120

5121+
/// Similar to tryToSimplifyUncondBranchWithICmpInIt, but handle a more generic
5122+
/// case. This is called when we find an icmp instruction (a seteq/setne with a
5123+
/// constant) and its following select instruction as the only TWO instruction
5124+
/// in a block that ends with an uncond branch. We are looking for a very
5125+
/// specific pattern that occurs when "
5126+
/// if (A == 1) return C1;
5127+
/// if (A == 2) return C2;
5128+
/// if (A < 3) return C3;
5129+
/// return C4;
5130+
/// " gets simplified. In this case, we merge the first two "branches of icmp"
5131+
/// into a switch, but then the default value goes to an uncond block with a lt
5132+
/// icmp and select in it, as InstCombine can not simplify "A < 3" as "A == 2".
5133+
/// After SimplifyCFG and other subsequent optimizations (e.g., SCCP), we might
5134+
/// get something like:
5135+
///
5136+
/// case1:
5137+
/// switch i8 %A, label %DEFAULT [ i8 0, label %end i8 1, label %case2 ]
5138+
/// case2:
5139+
/// br label %end
5140+
/// DEFAULT:
5141+
/// %tmp = icmp eq i8 %A, 2
5142+
/// %val = select i1 %tmp, i8 C3, i8 C4
5143+
/// br label %end
5144+
/// end:
5145+
/// _ = phi i8 [ C1, %case1 ], [ C2, %case2 ], [ %val, %DEFAULT ]
5146+
///
5147+
/// We prefer to split the edge to 'end' so that there are TWO entries of V3/V4
5148+
/// to the PHI, merging the icmp & select into the switch, as follows:
5149+
///
5150+
/// case1:
5151+
/// switch i8 %A, label %DEFAULT [
5152+
/// i8 0, label %end
5153+
/// i8 1, label %case2
5154+
/// i8 2, label %case3
5155+
/// ]
5156+
/// case2:
5157+
/// br label %end
5158+
/// case3:
5159+
/// br label %end
5160+
/// DEFAULT:
5161+
/// br label %end
5162+
/// end:
5163+
/// _ = phi i8 [ C1, %case1 ], [ C2, %case2 ], [ C3, %case2 ], [ C4, %DEFAULT]
5164+
bool SimplifyCFGOpt::tryToSimplifyUncondBranchWithICmpSelectInIt(
5165+
ICmpInst *ICI, SelectInst *Select, IRBuilder<> &Builder) {
5166+
BasicBlock *BB = ICI->getParent();
5167+
5168+
// If the block has any PHIs in it or the icmp/select has multiple uses, it is too
5169+
// complex.
5170+
if (isa<PHINode>(BB->begin()) || !ICI->hasOneUse() || !Select->hasOneUse())
5171+
return false;
5172+
5173+
// The pattern we're looking for is where our only predecessor is a switch on
5174+
// 'V' and this block is the default case for the switch. In this case we can
5175+
// fold the compared value into the switch to simplify things.
5176+
BasicBlock *Pred = BB->getSinglePredecessor();
5177+
if (!Pred || !isa<SwitchInst>(Pred->getTerminator()))
5178+
return false;
5179+
5180+
Value *IcmpCond;
5181+
ConstantInt *NewCaseVal;
5182+
CmpPredicate Predicate;
5183+
5184+
// Match icmp X, C
5185+
if (!match(ICI, m_ICmp(Predicate, m_Value(IcmpCond), m_ConstantInt(NewCaseVal))))
5186+
return false;
5187+
5188+
Value *SelectCond, *SelectTrueVal, *SelectFalseVal;
5189+
// Match select Cond, TrueVal, FalseVal
5190+
if (!match(Select, m_Select(m_Value(SelectCond), m_Value(SelectTrueVal),
5191+
m_Value(SelectFalseVal))))
5192+
return false;
5193+
5194+
// Check if the select condition is the same as the icmp condition.
5195+
if (SelectCond != ICI)
5196+
return false;
5197+
5198+
SwitchInst *SI = cast<SwitchInst>(Pred->getTerminator());
5199+
if (SI->getCondition() != IcmpCond)
5200+
return false;
5201+
5202+
// If BB is reachable on a non-default case, then we simply know the value of
5203+
// V in this block. Substitute it and constant fold the icmp instruction
5204+
// away.
5205+
if (SI->getDefaultDest() != BB) {
5206+
ConstantInt *VVal = SI->findCaseDest(BB);
5207+
assert(VVal && "Should have a unique destination value");
5208+
ICI->setOperand(0, VVal);
5209+
5210+
if (Value *V = simplifyInstruction(ICI, {DL, ICI})) {
5211+
ICI->replaceAllUsesWith(V);
5212+
ICI->eraseFromParent();
5213+
}
5214+
// BB is now empty, so it is likely to simplify away.
5215+
return requestResimplify();
5216+
}
5217+
5218+
// Ok, the block is reachable from the default dest. If the constant we're
5219+
// comparing exists in one of the other edges, then we can constant fold ICI
5220+
// and zap it.
5221+
if (SI->findCaseValue(NewCaseVal) != SI->case_default()) {
5222+
Value *V;
5223+
if (Predicate == ICmpInst::ICMP_EQ)
5224+
V = ConstantInt::getFalse(BB->getContext());
5225+
else
5226+
V = ConstantInt::getTrue(BB->getContext());
5227+
5228+
ICI->replaceAllUsesWith(V);
5229+
ICI->eraseFromParent();
5230+
// BB is now empty, so it is likely to simplify away.
5231+
return requestResimplify();
5232+
}
5233+
5234+
// The use of the select has to be in the 'end' block, by the only PHI node in
5235+
// the block.
5236+
BasicBlock *SuccBlock = BB->getTerminator()->getSuccessor(0);
5237+
PHINode *PHIUse = dyn_cast<PHINode>(Select->user_back());
5238+
if (PHIUse == nullptr || PHIUse != &SuccBlock->front() ||
5239+
isa<PHINode>(++BasicBlock::iterator(PHIUse)))
5240+
return false;
5241+
5242+
// If the icmp is a SETEQ, then the default dest gets SelectFalseVal, the new edge gets
5243+
// SelectTrueVal in the PHI.
5244+
Value *DefaultCst = SelectFalseVal;
5245+
Value *NewCst = SelectTrueVal;
5246+
5247+
if (ICI->getPredicate() == ICmpInst::ICMP_NE)
5248+
std::swap(DefaultCst, NewCst);
5249+
5250+
// Replace Select (which is used by the PHI for the default value) with
5251+
// SelectFalseVal or SelectTrueVal depending on if ICI is EQ or NE.
5252+
Select->replaceAllUsesWith(DefaultCst);
5253+
Select->eraseFromParent();
5254+
ICI->eraseFromParent();
5255+
5256+
SmallVector<DominatorTree::UpdateType, 2> Updates;
5257+
5258+
// Okay, the switch goes to this block on a default value. Add an edge from
5259+
// the switch to the merge point on the compared value.
5260+
BasicBlock *NewBB =
5261+
BasicBlock::Create(BB->getContext(), "switch.edge", BB->getParent(), BB);
5262+
{
5263+
SwitchInstProfUpdateWrapper SIW(*SI);
5264+
auto W0 = SIW.getSuccessorWeight(0);
5265+
SwitchInstProfUpdateWrapper::CaseWeightOpt NewW;
5266+
if (W0) {
5267+
NewW = ((uint64_t(*W0) + 1) >> 1);
5268+
SIW.setSuccessorWeight(0, *NewW);
5269+
}
5270+
SIW.addCase(NewCaseVal, NewBB, NewW);
5271+
if (DTU)
5272+
Updates.push_back({DominatorTree::Insert, Pred, NewBB});
5273+
}
5274+
5275+
// NewBB branches to the phi block, add the uncond branch and the phi entry.
5276+
Builder.SetInsertPoint(NewBB);
5277+
Builder.SetCurrentDebugLocation(SI->getDebugLoc());
5278+
Builder.CreateBr(SuccBlock);
5279+
PHIUse->addIncoming(NewCst, NewBB);
5280+
if (DTU) {
5281+
Updates.push_back({DominatorTree::Insert, NewBB, SuccBlock});
5282+
DTU->applyUpdates(Updates);
5283+
}
5284+
return true;
5285+
}
5286+
51195287
/// The specified branch is a conditional branch.
51205288
/// Check to see if it is branching on an or/and chain of icmp instructions, and
51215289
/// fold it into a switch instruction if so.
@@ -8167,13 +8335,18 @@ bool SimplifyCFGOpt::simplifyUncondBranch(BranchInst *BI,
81678335

81688336
// If the only instruction in the block is a seteq/setne comparison against a
81698337
// constant, try to simplify the block.
8170-
if (ICmpInst *ICI = dyn_cast<ICmpInst>(I))
8338+
if (ICmpInst *ICI = dyn_cast<ICmpInst>(I)) {
81718339
if (ICI->isEquality() && isa<ConstantInt>(ICI->getOperand(1))) {
81728340
++I;
81738341
if (I->isTerminator() &&
81748342
tryToSimplifyUncondBranchWithICmpInIt(ICI, Builder))
81758343
return true;
8344+
if (isa<SelectInst>(I) && I->getNextNode()->isTerminator() &&
8345+
tryToSimplifyUncondBranchWithICmpSelectInIt(ICI, cast<SelectInst>(I),
8346+
Builder))
8347+
return true;
81768348
}
8349+
}
81778350

81788351
// See if we can merge an empty landing pad block with another which is
81798352
// equivalent.

0 commit comments

Comments
 (0)