@@ -370,15 +370,30 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
370370 { // Scope for SwitchInstProfUpdateWrapper. It must not live during
371371 // ConstantFoldTerminator() as the underlying SwitchInst can be changed.
372372 SwitchInstProfUpdateWrapper SI (*I);
373+ ConstantRange CR =
374+ LVI->getConstantRangeAtUse (I->getOperandUse (0 ), /* UndefAllowed=*/ false );
373375 unsigned ReachableCaseCount = 0 ;
374376
375377 for (auto CI = SI->case_begin (), CE = SI->case_end (); CI != CE;) {
376378 ConstantInt *Case = CI->getCaseValue ();
377- auto *Res = dyn_cast_or_null<ConstantInt>(
378- LVI->getPredicateAt (CmpInst::ICMP_EQ, Cond, Case, I,
379- /* UseBlockValue */ true ));
379+ std::optional<bool > Predicate = std::nullopt ;
380+ if (!CR.contains (Case->getValue ()))
381+ Predicate = false ;
382+ else if (CR.isSingleElement () &&
383+ *CR.getSingleElement () == Case->getValue ())
384+ Predicate = true ;
385+ if (!Predicate) {
386+ // Handle missing cases, e.g., the range has a hole.
387+ auto *Res = dyn_cast_or_null<ConstantInt>(
388+ LVI->getPredicateAt (CmpInst::ICMP_EQ, Cond, Case, I,
389+ /* UseBlockValue=*/ true ));
390+ if (Res && Res->isZero ())
391+ Predicate = false ;
392+ else if (Res && Res->isOne ())
393+ Predicate = true ;
394+ }
380395
381- if (Res && Res-> isZero () ) {
396+ if (Predicate && !*Predicate ) {
382397 // This case never fires - remove it.
383398 BasicBlock *Succ = CI->getCaseSuccessor ();
384399 Succ->removePredecessor (BB);
@@ -395,7 +410,7 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
395410 DTU.applyUpdatesPermissive ({{DominatorTree::Delete, BB, Succ}});
396411 continue ;
397412 }
398- if (Res && Res-> isOne () ) {
413+ if (Predicate && *Predicate ) {
399414 // This case always fires. Arrange for the switch to be turned into an
400415 // unconditional branch by replacing the switch condition with the case
401416 // value.
@@ -410,28 +425,24 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
410425 ++ReachableCaseCount;
411426 }
412427
413- BasicBlock *DefaultDest = SI->getDefaultDest ();
414- if (ReachableCaseCount > 1 &&
415- !isa<UnreachableInst>(DefaultDest->getFirstNonPHIOrDbg ())) {
416- ConstantRange CR = LVI->getConstantRangeAtUse (I->getOperandUse (0 ),
417- /* UndefAllowed*/ false );
418- // The default dest is unreachable if all cases are covered.
419- if (!CR.isSizeLargerThan (ReachableCaseCount)) {
420- BasicBlock *NewUnreachableBB =
421- BasicBlock::Create (BB->getContext (), " default.unreachable" ,
422- BB->getParent (), DefaultDest);
423- new UnreachableInst (BB->getContext (), NewUnreachableBB);
428+ // The default dest is unreachable if all cases are covered.
429+ if (!SI->defaultDestUndefined () &&
430+ !CR.isSizeLargerThan (ReachableCaseCount)) {
431+ BasicBlock *DefaultDest = SI->getDefaultDest ();
432+ BasicBlock *NewUnreachableBB =
433+ BasicBlock::Create (BB->getContext (), " default.unreachable" ,
434+ BB->getParent (), DefaultDest);
435+ new UnreachableInst (BB->getContext (), NewUnreachableBB);
424436
425- DefaultDest->removePredecessor (BB);
426- SI->setDefaultDest (NewUnreachableBB);
437+ DefaultDest->removePredecessor (BB);
438+ SI->setDefaultDest (NewUnreachableBB);
427439
428- if (SuccessorsCount[DefaultDest] == 1 )
429- DTU.applyUpdates ({{DominatorTree::Delete, BB, DefaultDest}});
430- DTU.applyUpdates ({{DominatorTree::Insert, BB, NewUnreachableBB}});
440+ if (SuccessorsCount[DefaultDest] == 1 )
441+ DTU.applyUpdates ({{DominatorTree::Delete, BB, DefaultDest}});
442+ DTU.applyUpdates ({{DominatorTree::Insert, BB, NewUnreachableBB}});
431443
432- ++NumDeadCases;
433- Changed = true ;
434- }
444+ ++NumDeadCases;
445+ Changed = true ;
435446 }
436447 }
437448
0 commit comments