@@ -370,7 +370,9 @@ void ProcessSwitchInst(SwitchInst *SI,
370
370
const unsigned NumSimpleCases = Clusterify (Cases, SI);
371
371
IntegerType *IT = cast<IntegerType>(SI->getCondition ()->getType ());
372
372
const unsigned BitWidth = IT->getBitWidth ();
373
- APInt SignedZero (BitWidth, 0 );
373
+ // Explictly use higher precision to prevent unsigned overflow where
374
+ // `UnsignedMax - 0 + 1 == 0`
375
+ APInt UnsignedZero (BitWidth + 1 , 0 );
374
376
APInt UnsignedMax = APInt::getMaxValue (BitWidth);
375
377
LLVM_DEBUG (dbgs () << " Clusterify finished. Total clusters: " << Cases.size ()
376
378
<< " . Total non-default cases: " << NumSimpleCases
@@ -431,7 +433,7 @@ void ProcessSwitchInst(SwitchInst *SI,
431
433
432
434
if (DefaultIsUnreachableFromSwitch) {
433
435
DenseMap<BasicBlock *, APInt> Popularity;
434
- APInt MaxPop (SignedZero );
436
+ APInt MaxPop (UnsignedZero );
435
437
BasicBlock *PopSucc = nullptr ;
436
438
437
439
APInt SignedMax = APInt::getSignedMaxValue (BitWidth);
@@ -457,11 +459,11 @@ void ProcessSwitchInst(SwitchInst *SI,
457
459
}
458
460
459
461
// Count popularity.
460
- APInt N = High - Low + 1 ;
461
- assert (N. sge (SignedZero) && " Popularity shouldn't be negative. " ) ;
462
+ assert ( High. sge (Low) && " Popularity shouldn't be negative. " ) ;
463
+ APInt N = High. sext (BitWidth + 1 ) - Low. sext (BitWidth + 1 ) + 1 ;
462
464
// Explict insert to make sure the bitwidth of APInts match
463
- APInt &Pop = Popularity.insert ({I.BB , APInt (SignedZero )}).first ->second ;
464
- if ((Pop += N).sgt (MaxPop)) {
465
+ APInt &Pop = Popularity.insert ({I.BB , APInt (UnsignedZero )}).first ->second ;
466
+ if ((Pop += N).ugt (MaxPop)) {
465
467
MaxPop = Pop;
466
468
PopSucc = I.BB ;
467
469
}
@@ -486,8 +488,6 @@ void ProcessSwitchInst(SwitchInst *SI,
486
488
487
489
// Use the most popular block as the new default, reducing the number of
488
490
// cases.
489
- assert (MaxPop.sgt (SignedZero) && PopSucc &&
490
- " Max populartion shouldn't be negative." );
491
491
Default = PopSucc;
492
492
llvm::erase_if (Cases,
493
493
[PopSucc](const CaseRange &R) { return R.BB == PopSucc; });
@@ -498,8 +498,9 @@ void ProcessSwitchInst(SwitchInst *SI,
498
498
SI->eraseFromParent ();
499
499
// As all the cases have been replaced with a single branch, only keep
500
500
// one entry in the PHI nodes.
501
- for (APInt I (SignedZero); I.slt (MaxPop - 1 ); ++I)
502
- PopSucc->removePredecessor (OrigBlock);
501
+ if (!MaxPop.isZero ())
502
+ for (APInt I (UnsignedZero); I.ult (MaxPop - 1 ); ++I)
503
+ PopSucc->removePredecessor (OrigBlock);
503
504
return ;
504
505
}
505
506
0 commit comments