@@ -3201,7 +3201,8 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
3201
3201
// pattern.
3202
3202
static bool isSafeToRemoveBitCeilSelect (ICmpInst::Predicate Pred, Value *Cond0,
3203
3203
const APInt *Cond1, Value *CtlzOp,
3204
- unsigned BitWidth) {
3204
+ unsigned BitWidth,
3205
+ bool &ShouldDropNUW) {
3205
3206
// The challenge in recognizing std::bit_ceil(X) is that the operand is used
3206
3207
// for the CTLZ proper and select condition, each possibly with some
3207
3208
// operation like add and sub.
@@ -3224,6 +3225,8 @@ static bool isSafeToRemoveBitCeilSelect(ICmpInst::Predicate Pred, Value *Cond0,
3224
3225
ConstantRange CR = ConstantRange::makeExactICmpRegion (
3225
3226
CmpInst::getInversePredicate (Pred), *Cond1);
3226
3227
3228
+ ShouldDropNUW = false ;
3229
+
3227
3230
// Match the operation that's used to compute CtlzOp from CommonAncestor. If
3228
3231
// CtlzOp == CommonAncestor, return true as no operation is needed. If a
3229
3232
// match is found, execute the operation on CR, update CR, and return true.
@@ -3237,6 +3240,7 @@ static bool isSafeToRemoveBitCeilSelect(ICmpInst::Predicate Pred, Value *Cond0,
3237
3240
return true ;
3238
3241
}
3239
3242
if (match (CtlzOp, m_Sub (m_APInt (C), m_Specific (CommonAncestor)))) {
3243
+ ShouldDropNUW = true ;
3240
3244
CR = ConstantRange (*C).sub (CR);
3241
3245
return true ;
3242
3246
}
@@ -3306,14 +3310,20 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
3306
3310
Pred = CmpInst::getInversePredicate (Pred);
3307
3311
}
3308
3312
3313
+ bool ShouldDropNUW;
3314
+
3309
3315
if (!match (FalseVal, m_One ()) ||
3310
3316
!match (TrueVal,
3311
3317
m_OneUse (m_Shl (m_One (), m_OneUse (m_Sub (m_SpecificInt (BitWidth),
3312
3318
m_Value (Ctlz)))))) ||
3313
3319
!match (Ctlz, m_Intrinsic<Intrinsic::ctlz>(m_Value (CtlzOp), m_Zero ())) ||
3314
- !isSafeToRemoveBitCeilSelect (Pred, Cond0, Cond1, CtlzOp, BitWidth))
3320
+ !isSafeToRemoveBitCeilSelect (Pred, Cond0, Cond1, CtlzOp, BitWidth,
3321
+ ShouldDropNUW))
3315
3322
return nullptr ;
3316
3323
3324
+ if (ShouldDropNUW)
3325
+ cast<Instruction>(CtlzOp)->setHasNoUnsignedWrap (false );
3326
+
3317
3327
// Build 1 << (-CTLZ & (BitWidth-1)). The negation likely corresponds to a
3318
3328
// single hardware instruction as opposed to BitWidth - CTLZ, where BitWidth
3319
3329
// is an integer constant. Masking with BitWidth-1 comes free on some
0 commit comments