@@ -935,21 +935,31 @@ static Value *foldSignedTruncationCheck(ICmpInst *ICmp0, ICmpInst *ICmp1,
935935
936936// / Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and
937937// / fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1).
938- // / Also used for logical and/or, must be poison safe.
938+ // / Also used for logical and/or, must be poison safe if range attributes are
939+ // / dropped.
939940static Value *foldIsPowerOf2OrZero (ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd,
940- InstCombiner::BuilderTy &Builder) {
941+ InstCombiner::BuilderTy &Builder,
942+ InstCombinerImpl &IC) {
941943 CmpInst::Predicate Pred0, Pred1;
942944 Value *X;
943945 if (!match (Cmp0, m_ICmp (Pred0, m_Intrinsic<Intrinsic::ctpop>(m_Value (X)),
944946 m_SpecificInt (1 ))) ||
945947 !match (Cmp1, m_ICmp (Pred1, m_Specific (X), m_ZeroInt ())))
946948 return nullptr ;
947949
948- Value *CtPop = Cmp0->getOperand (0 );
949- if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_NE)
950+ auto *CtPop = cast<Instruction>(Cmp0->getOperand (0 ));
951+ if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_NE) {
952+ // Drop range attributes and re-infer them in the next iteration.
953+ CtPop->dropPoisonGeneratingAnnotations ();
954+ IC.addToWorklist (CtPop);
950955 return Builder.CreateICmpUGT (CtPop, ConstantInt::get (CtPop->getType (), 1 ));
951- if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_EQ)
956+ }
957+ if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_EQ) {
958+ // Drop range attributes and re-infer them in the next iteration.
959+ CtPop->dropPoisonGeneratingAnnotations ();
960+ IC.addToWorklist (CtPop);
952961 return Builder.CreateICmpULT (CtPop, ConstantInt::get (CtPop->getType (), 2 ));
962+ }
953963
954964 return nullptr ;
955965}
@@ -3362,9 +3372,9 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
33623372 /* IsLogical*/ false , Builder, Q))
33633373 return V;
33643374
3365- if (Value *V = foldIsPowerOf2OrZero (LHS, RHS, IsAnd, Builder))
3375+ if (Value *V = foldIsPowerOf2OrZero (LHS, RHS, IsAnd, Builder, * this ))
33663376 return V;
3367- if (Value *V = foldIsPowerOf2OrZero (RHS, LHS, IsAnd, Builder))
3377+ if (Value *V = foldIsPowerOf2OrZero (RHS, LHS, IsAnd, Builder, * this ))
33683378 return V;
33693379
33703380 // TODO: One of these directions is fine with logical and/or, the other could
0 commit comments