@@ -90,6 +90,7 @@ class ValueEvolution {
9090 const bool ByteOrderSwapped;
9191 APInt GenPoly;
9292 StringRef ErrStr;
93+ unsigned AtIter;
9394
9495 // Compute the KnownBits of a BinaryOperator.
9596 KnownBits computeBinOp (const BinaryOperator *I);
@@ -190,43 +191,54 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
190191 return KnownPhis.lookup_or (P, BitWidth);
191192
192193 // Compute the KnownBits for a Select(Cmp()), forcing it to take the branch
193- // that is predicated on the (least|most)-significant-bit check .
194+ // that is (least|most)-significant-bit-clear .
194195 CmpPredicate Pred;
195196 Value *L, *R;
196197 Instruction *TV, *FV;
197198 if (match (I, m_Select (m_ICmp (Pred, m_Value (L), m_Value (R)), m_Instruction (TV),
198199 m_Instruction (FV)))) {
199200 Visited.insert (cast<Instruction>(I->getOperand (0 )));
200201
201- // We need to check LCR against [0, 2) in the little-endian case, because
202- // the RCR check is insufficient: it is simply [0, 1).
203- if (!ByteOrderSwapped) {
204- KnownBits KnownL = compute (L);
205- unsigned ICmpBW = KnownL.getBitWidth ();
206- auto LCR = ConstantRange::fromKnownBits (KnownL, false );
207- auto CheckLCR = ConstantRange (APInt::getZero (ICmpBW), APInt (ICmpBW, 2 ));
208- if (LCR != CheckLCR) {
209- ErrStr = " Bad LHS of significant-bit-check" ;
210- return {BitWidth};
211- }
202+ // Check that the predication is on (most|least) significant bit. We check
203+ // that the compare is `>= 0` in the big-endian case, and `== 0` in the
204+ // little-endian case (or the inverse, in which case the branches of the
205+ // compare are swapped). We check LCR against CheckLCR, which is full-set,
206+ // [0, -1), [0, -3), [0, -7), etc. depending on AtIter in the big-endian
207+ // case, and [0, 2) in the little-endian case: CheckLCR checks that we are
208+ // shifting in zero bits in every loop iteration in the big-endian case, and
209+ // the compare 0 or 1 in the little-endian case (as a value and'ed with 1 is
210+ // passed as the operand). We then check AllowedByR against CheckAllowedByR,
211+ // which is [0, smin) in the big-endian case, and [0, 1) in the
212+ // little-endian case: CheckAllowedByR checks for significant-bit-clear,
213+ // which means that we visit the bit-shift branch instead of the
214+ // bit-shift-and-xor-poly branch.
215+ KnownBits KnownL = compute (L);
216+ unsigned ICmpBW = KnownL.getBitWidth ();
217+ auto LCR = ConstantRange::fromKnownBits (KnownL, false );
218+ auto CheckLCR = ConstantRange::getNonEmpty (
219+ APInt::getZero (ICmpBW), ByteOrderSwapped
220+ ? -APInt::getLowBitsSet (ICmpBW, AtIter)
221+ : APInt (ICmpBW, 2 ));
222+ if (LCR != CheckLCR) {
223+ ErrStr = " Bad LHS of significant-bit-check" ;
224+ return {BitWidth};
212225 }
213226
214- // Check that the predication is on (most|least) significant bit.
215227 KnownBits KnownR = compute (R);
216- unsigned ICmpBW = KnownR.getBitWidth ();
217228 auto RCR = ConstantRange::fromKnownBits (KnownR, false );
218- auto AllowedR = ConstantRange::makeAllowedICmpRegion (Pred, RCR);
219- ConstantRange CheckRCR (APInt::getZero (ICmpBW),
220- ByteOrderSwapped ? APInt::getSignedMinValue (ICmpBW)
221- : APInt (ICmpBW, 1 ));
222-
223- // We only compute KnownBits of either TV or FV, as the other value would
224- // just be a bit-shift as checked by isBigEndianBitShift.
225- if (AllowedR == CheckRCR) {
229+ auto AllowedByR = ConstantRange::makeAllowedICmpRegion (Pred, RCR);
230+ ConstantRange CheckAllowedByR (
231+ APInt::getZero (ICmpBW),
232+ ByteOrderSwapped ? APInt::getSignedMinValue (ICmpBW) : APInt (ICmpBW, 1 ));
233+
234+ // We only compute KnownBits of either TV or FV, as the other branch would
235+ // be the bit-shift-and-xor-poly branch, as determined by the conditional
236+ // recurrence.
237+ if (AllowedByR == CheckAllowedByR) {
226238 Visited.insert (FV);
227239 return compute (TV);
228240 }
229- if (AllowedR .inverse () == CheckRCR ) {
241+ if (AllowedByR .inverse () == CheckAllowedByR ) {
230242 Visited.insert (TV);
231243 return compute (FV);
232244 }
@@ -264,9 +276,11 @@ KnownBits ValueEvolution::compute(const Value *V) {
264276}
265277
266278bool ValueEvolution::computeEvolutions (ArrayRef<PhiStepPair> PhiEvolutions) {
267- for (unsigned I = 0 ; I < TripCount; ++I)
279+ for (unsigned I = 0 ; I < TripCount; ++I) {
280+ AtIter = I;
268281 for (auto [Phi, Step] : PhiEvolutions)
269282 KnownPhis.emplace_or_assign (Phi, computeInstr (Step));
283+ }
270284
271285 return ErrStr.empty ();
272286}
0 commit comments