@@ -370,15 +370,30 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
370
370
{ // Scope for SwitchInstProfUpdateWrapper. It must not live during
371
371
// ConstantFoldTerminator() as the underlying SwitchInst can be changed.
372
372
SwitchInstProfUpdateWrapper SI (*I);
373
+ ConstantRange CR =
374
+ LVI->getConstantRangeAtUse (I->getOperandUse (0 ), /* UndefAllowed=*/ false );
373
375
unsigned ReachableCaseCount = 0 ;
374
376
375
377
for (auto CI = SI->case_begin (), CE = SI->case_end (); CI != CE;) {
376
378
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
+ }
380
395
381
- if (Res && Res-> isZero () ) {
396
+ if (Predicate && !*Predicate ) {
382
397
// This case never fires - remove it.
383
398
BasicBlock *Succ = CI->getCaseSuccessor ();
384
399
Succ->removePredecessor (BB);
@@ -395,7 +410,7 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
395
410
DTU.applyUpdatesPermissive ({{DominatorTree::Delete, BB, Succ}});
396
411
continue ;
397
412
}
398
- if (Res && Res-> isOne () ) {
413
+ if (Predicate && *Predicate ) {
399
414
// This case always fires. Arrange for the switch to be turned into an
400
415
// unconditional branch by replacing the switch condition with the case
401
416
// value.
@@ -410,27 +425,24 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
410
425
++ReachableCaseCount;
411
426
}
412
427
413
- if (ReachableCaseCount > 1 && !SI->defaultDestUnreachable ()) {
428
+ // The default dest is unreachable if all cases are covered.
429
+ if (!SI->defaultDestUnreachable () &&
430
+ !CR.isSizeLargerThan (ReachableCaseCount)) {
414
431
BasicBlock *DefaultDest = SI->getDefaultDest ();
415
- ConstantRange CR = LVI->getConstantRangeAtUse (I->getOperandUse (0 ),
416
- /* UndefAllowed*/ false );
417
- // The default dest is unreachable if all cases are covered.
418
- if (!CR.isSizeLargerThan (ReachableCaseCount)) {
419
- BasicBlock *NewUnreachableBB =
420
- BasicBlock::Create (BB->getContext (), " default.unreachable" ,
421
- BB->getParent (), DefaultDest);
422
- new UnreachableInst (BB->getContext (), NewUnreachableBB);
432
+ BasicBlock *NewUnreachableBB =
433
+ BasicBlock::Create (BB->getContext (), " default.unreachable" ,
434
+ BB->getParent (), DefaultDest);
435
+ new UnreachableInst (BB->getContext (), NewUnreachableBB);
423
436
424
- DefaultDest->removePredecessor (BB);
425
- SI->setDefaultDest (NewUnreachableBB);
437
+ DefaultDest->removePredecessor (BB);
438
+ SI->setDefaultDest (NewUnreachableBB);
426
439
427
- if (SuccessorsCount[DefaultDest] == 1 )
428
- DTU.applyUpdates ({{DominatorTree::Delete, BB, DefaultDest}});
429
- 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}});
430
443
431
- ++NumDeadCases;
432
- Changed = true ;
433
- }
444
+ ++NumDeadCases;
445
+ Changed = true ;
434
446
}
435
447
}
436
448
0 commit comments