@@ -3343,7 +3343,8 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
3343
3343
// pattern.
3344
3344
static bool isSafeToRemoveBitCeilSelect (ICmpInst::Predicate Pred, Value *Cond0,
3345
3345
const APInt *Cond1, Value *CtlzOp,
3346
- unsigned BitWidth) {
3346
+ unsigned BitWidth,
3347
+ bool &ShouldDropNUW) {
3347
3348
// The challenge in recognizing std::bit_ceil(X) is that the operand is used
3348
3349
// for the CTLZ proper and select condition, each possibly with some
3349
3350
// operation like add and sub.
@@ -3366,6 +3367,8 @@ static bool isSafeToRemoveBitCeilSelect(ICmpInst::Predicate Pred, Value *Cond0,
3366
3367
ConstantRange CR = ConstantRange::makeExactICmpRegion (
3367
3368
CmpInst::getInversePredicate (Pred), *Cond1);
3368
3369
3370
+ ShouldDropNUW = false ;
3371
+
3369
3372
// Match the operation that's used to compute CtlzOp from CommonAncestor. If
3370
3373
// CtlzOp == CommonAncestor, return true as no operation is needed. If a
3371
3374
// match is found, execute the operation on CR, update CR, and return true.
@@ -3379,6 +3382,7 @@ static bool isSafeToRemoveBitCeilSelect(ICmpInst::Predicate Pred, Value *Cond0,
3379
3382
return true ;
3380
3383
}
3381
3384
if (match (CtlzOp, m_Sub (m_APInt (C), m_Specific (CommonAncestor)))) {
3385
+ ShouldDropNUW = true ;
3382
3386
CR = ConstantRange (*C).sub (CR);
3383
3387
return true ;
3384
3388
}
@@ -3448,14 +3452,20 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
3448
3452
Pred = CmpInst::getInversePredicate (Pred);
3449
3453
}
3450
3454
3455
+ bool ShouldDropNUW;
3456
+
3451
3457
if (!match (FalseVal, m_One ()) ||
3452
3458
!match (TrueVal,
3453
3459
m_OneUse (m_Shl (m_One (), m_OneUse (m_Sub (m_SpecificInt (BitWidth),
3454
3460
m_Value (Ctlz)))))) ||
3455
3461
!match (Ctlz, m_Intrinsic<Intrinsic::ctlz>(m_Value (CtlzOp), m_Zero ())) ||
3456
- !isSafeToRemoveBitCeilSelect (Pred, Cond0, Cond1, CtlzOp, BitWidth))
3462
+ !isSafeToRemoveBitCeilSelect (Pred, Cond0, Cond1, CtlzOp, BitWidth,
3463
+ ShouldDropNUW))
3457
3464
return nullptr ;
3458
3465
3466
+ if (ShouldDropNUW)
3467
+ cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap (false );
3468
+
3459
3469
// Build 1 << (-CTLZ & (BitWidth-1)). The negation likely corresponds to a
3460
3470
// single hardware instruction as opposed to BitWidth - CTLZ, where BitWidth
3461
3471
// is an integer constant. Masking with BitWidth-1 comes free on some
0 commit comments