@@ -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