@@ -102,8 +102,8 @@ class ValueEvolution {
102102
103103public:
104104 // ValueEvolution is meant to be constructed with the TripCount of the loop,
105- // and whether the polynomial algorithm is big-endian, for the significant-bit
106- // check.
105+ // and a boolean indicating whether the polynomial algorithm is big-endian
106+ // (for the significant-bit check) .
107107 ValueEvolution (unsigned TripCount, bool ByteOrderSwapped);
108108
109109 // Given a list of PHI nodes along with their incoming value from within the
@@ -115,6 +115,10 @@ class ValueEvolution {
115115 // precise error message.
116116 StringRef getError () const { return ErrStr; }
117117
118+ // A set of Instructions visited by ValueEvolution. The only unvisited
119+ // instructions will be ones not on the use-def chain of the PHIs' evolutions.
120+ SmallPtrSet<const Instruction *, 16 > Visited;
121+
118122 // The computed KnownBits for each PHI node, which is populated after
119123 // computeEvolutions is called.
120124 KnownPhiMap KnownPhis;
@@ -177,6 +181,9 @@ KnownBits ValueEvolution::computeBinOp(const BinaryOperator *I) {
177181KnownBits ValueEvolution::computeInstr (const Instruction *I) {
178182 unsigned BitWidth = I->getType ()->getScalarSizeInBits ();
179183
184+ // computeInstr is the only entry-point that needs to update the Visited set.
185+ Visited.insert (I);
186+
180187 // We look up in the map that contains the KnownBits of the PHI from the
181188 // previous iteration.
182189 if (const PHINode *P = dyn_cast<PHINode>(I))
@@ -185,9 +192,12 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
185192 // Compute the KnownBits for a Select(Cmp()), forcing it to take the branch
186193 // that is predicated on the (least|most)-significant-bit check.
187194 CmpPredicate Pred;
188- Value *L, *R, *TV, *FV;
189- if (match (I, m_Select (m_ICmp (Pred, m_Value (L), m_Value (R)), m_Value (TV),
190- m_Value (FV)))) {
195+ Value *L, *R;
196+ Instruction *TV, *FV;
197+ if (match (I, m_Select (m_ICmp (Pred, m_Value (L), m_Value (R)), m_Instruction (TV),
198+ m_Instruction (FV)))) {
199+ Visited.insert (cast<Instruction>(I->getOperand (0 )));
200+
191201 // We need to check LCR against [0, 2) in the little-endian case, because
192202 // the RCR check is insufficient: it is simply [0, 1).
193203 if (!ByteOrderSwapped) {
@@ -209,10 +219,17 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
209219 ConstantRange CheckRCR (APInt::getZero (ICmpBW),
210220 ByteOrderSwapped ? APInt::getSignedMinValue (ICmpBW)
211221 : APInt (ICmpBW, 1 ));
212- if (AllowedR == CheckRCR)
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) {
226+ Visited.insert (FV);
213227 return compute (TV);
214- if (AllowedR.inverse () == CheckRCR)
228+ }
229+ if (AllowedR.inverse () == CheckRCR) {
230+ Visited.insert (TV);
215231 return compute (FV);
232+ }
216233
217234 ErrStr = " Bad RHS of significant-bit-check" ;
218235 return {BitWidth};
@@ -634,6 +651,17 @@ HashRecognize::recognizeCRC() const {
634651 return VE.getError ();
635652 KnownBits ResultBits = VE.KnownPhis .at (ConditionalRecurrence.Phi );
636653
654+ // There must be exactly four unvisited instructions, corresponding to the
655+ // IndVar PHI. Any other unvisited instructions from the KnownBits propagation
656+ // can complicate the optimization, which replaces the entire loop with the
657+ // table-lookup version of the hash algorithm.
658+ std::initializer_list<const Instruction *> AugmentVisited = {
659+ IndVar, Latch->getTerminator (), L.getLatchCmpInst (),
660+ cast<Instruction>(IndVar->getIncomingValueForBlock (Latch))};
661+ VE.Visited .insert_range (AugmentVisited);
662+ if (std::distance (Latch->begin (), Latch->end ()) != VE.Visited .size ())
663+ return " Found stray unvisited instructions" ;
664+
637665 unsigned N = std::min (TC, ResultBits.getBitWidth ());
638666 auto IsZero = [](const KnownBits &K) { return K.isZero (); };
639667 if (!checkExtractBits (ResultBits, N, IsZero, *ByteOrderSwapped))
0 commit comments