@@ -955,9 +955,11 @@ static Value *foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd,
955955}
956956
957957// / Reduce a pair of compares that check if a value has exactly 1 bit set.
958- // / Also used for logical and/or, must be poison safe.
958+ // / Also used for logical and/or, must be poison safe if range attributes are
959+ // / dropped.
959960static Value *foldIsPowerOf2 (ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
960- InstCombiner::BuilderTy &Builder) {
961+ InstCombiner::BuilderTy &Builder,
962+ InstCombinerImpl &IC) {
961963 // Handle 'and' / 'or' commutation: make the equality check the first operand.
962964 if (JoinedByAnd && Cmp1->getPredicate () == ICmpInst::ICMP_NE)
963965 std::swap (Cmp0, Cmp1);
@@ -971,7 +973,10 @@ static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
971973 match (Cmp1, m_SpecificICmp (ICmpInst::ICMP_ULT,
972974 m_Intrinsic<Intrinsic::ctpop>(m_Specific (X)),
973975 m_SpecificInt (2 )))) {
974- Value *CtPop = Cmp1->getOperand (0 );
976+ auto *CtPop = cast<Instruction>(Cmp1->getOperand (0 ));
977+ // Drop range attributes and re-infer them in the next iteration.
978+ CtPop->dropPoisonGeneratingAnnotations ();
979+ IC.addToWorklist (CtPop);
975980 return Builder.CreateICmpEQ (CtPop, ConstantInt::get (CtPop->getType (), 1 ));
976981 }
977982 // (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1
@@ -980,7 +985,10 @@ static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
980985 match (Cmp1, m_SpecificICmp (ICmpInst::ICMP_UGT,
981986 m_Intrinsic<Intrinsic::ctpop>(m_Specific (X)),
982987 m_SpecificInt (1 )))) {
983- Value *CtPop = Cmp1->getOperand (0 );
988+ auto *CtPop = cast<Instruction>(Cmp1->getOperand (0 ));
989+ // Drop range attributes and re-infer them in the next iteration.
990+ CtPop->dropPoisonGeneratingAnnotations ();
991+ IC.addToWorklist (CtPop);
984992 return Builder.CreateICmpNE (CtPop, ConstantInt::get (CtPop->getType (), 1 ));
985993 }
986994 return nullptr ;
@@ -3375,7 +3383,7 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
33753383 if (Value *V = foldSignedTruncationCheck (LHS, RHS, I, Builder))
33763384 return V;
33773385
3378- if (Value *V = foldIsPowerOf2 (LHS, RHS, IsAnd, Builder))
3386+ if (Value *V = foldIsPowerOf2 (LHS, RHS, IsAnd, Builder, * this ))
33793387 return V;
33803388
33813389 if (Value *V = foldPowerOf2AndShiftedMask (LHS, RHS, IsAnd, Builder))
0 commit comments