@@ -91,6 +91,10 @@ class ValueEvolution {
9191 APInt GenPoly;
9292 StringRef ErrStr;
9393
94+ // A set of instructions visited by ValueEvolution. Anything that's not in the
95+ // use-def chain of the PHIs' evolution will be reported as unvisited.
96+ SmallPtrSet<const Instruction *, 16 > Visited;
97+
9498 // Compute the KnownBits of a BinaryOperator.
9599 KnownBits computeBinOp (const BinaryOperator *I);
96100
@@ -102,15 +106,19 @@ class ValueEvolution {
102106
103107public:
104108 // 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.
107- ValueEvolution (unsigned TripCount, bool ByteOrderSwapped);
109+ // whether the polynomial algorithm is big-endian for the significant-bit
110+ // check, and an initial value for the Visited set.
111+ ValueEvolution (unsigned TripCount, bool ByteOrderSwapped,
112+ ArrayRef<const Instruction *> InitVisited);
108113
109114 // Given a list of PHI nodes along with their incoming value from within the
110115 // loop, computeEvolutions computes the KnownBits of each of the PHI nodes on
111116 // the final iteration. Returns true on success and false on error.
112117 bool computeEvolutions (ArrayRef<PhiStepPair> PhiEvolutions);
113118
119+ // Query the Visited set.
120+ bool isVisited (const Instruction *I) const { return Visited.contains (I); }
121+
114122 // In case ValueEvolution encounters an error, this is meant to be used for a
115123 // precise error message.
116124 StringRef getError () const { return ErrStr; }
@@ -120,8 +128,11 @@ class ValueEvolution {
120128 KnownPhiMap KnownPhis;
121129};
122130
123- ValueEvolution::ValueEvolution (unsigned TripCount, bool ByteOrderSwapped)
124- : TripCount(TripCount), ByteOrderSwapped(ByteOrderSwapped) {}
131+ ValueEvolution::ValueEvolution (unsigned TripCount, bool ByteOrderSwapped,
132+ ArrayRef<const Instruction *> InitVisited)
133+ : TripCount(TripCount), ByteOrderSwapped(ByteOrderSwapped) {
134+ Visited.insert_range (InitVisited);
135+ }
125136
126137KnownBits ValueEvolution::computeBinOp (const BinaryOperator *I) {
127138 KnownBits KnownL (compute (I->getOperand (0 )));
@@ -177,6 +188,9 @@ KnownBits ValueEvolution::computeBinOp(const BinaryOperator *I) {
177188KnownBits ValueEvolution::computeInstr (const Instruction *I) {
178189 unsigned BitWidth = I->getType ()->getScalarSizeInBits ();
179190
191+ // computeInstr is the only entry-point that needs to update the Visited set.
192+ Visited.insert (I);
193+
180194 // We look up in the map that contains the KnownBits of the PHI from the
181195 // previous iteration.
182196 if (const PHINode *P = dyn_cast<PHINode>(I))
@@ -185,9 +199,14 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
185199 // Compute the KnownBits for a Select(Cmp()), forcing it to take the branch
186200 // that is predicated on the (least|most)-significant-bit check.
187201 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)))) {
202+ Value *L, *R;
203+ Instruction *TV, *FV;
204+ if (match (I, m_Select (m_ICmp (Pred, m_Value (L), m_Value (R)), m_Instruction (TV),
205+ m_Instruction (FV)))) {
206+ Visited.insert (cast<Instruction>(I->getOperand (0 )));
207+ Visited.insert (TV);
208+ Visited.insert (FV);
209+
191210 // We need to check LCR against [0, 2) in the little-endian case, because
192211 // the RCR check is insufficient: it is simply [0, 1).
193212 if (!ByteOrderSwapped) {
@@ -209,6 +228,9 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
209228 ConstantRange CheckRCR (APInt::getZero (ICmpBW),
210229 ByteOrderSwapped ? APInt::getSignedMinValue (ICmpBW)
211230 : APInt (ICmpBW, 1 ));
231+
232+ // We only compute KnownBits of either TV or FV, as the other value would
233+ // just be a bit-shift as checked by isBigEndianBitShift.
212234 if (AllowedR == CheckRCR)
213235 return compute (TV);
214236 if (AllowedR.inverse () == CheckRCR)
@@ -629,11 +651,23 @@ HashRecognize::recognizeCRC() const {
629651 if (SimpleRecurrence)
630652 PhiEvolutions.emplace_back (SimpleRecurrence.Phi , SimpleRecurrence.BO );
631653
632- ValueEvolution VE (TC, *ByteOrderSwapped);
654+ // Initialize the Visited set in ValueEvolution with the IndVar-related
655+ // instructions.
656+ std::initializer_list<const Instruction *> InitVisited = {
657+ IndVar, Latch->getTerminator (), L.getLatchCmpInst (),
658+ cast<Instruction>(IndVar->getIncomingValueForBlock (Latch))};
659+
660+ ValueEvolution VE (TC, *ByteOrderSwapped, InitVisited);
633661 if (!VE.computeEvolutions (PhiEvolutions))
634662 return VE.getError ();
635663 KnownBits ResultBits = VE.KnownPhis .at (ConditionalRecurrence.Phi );
636664
665+ // Any unvisited instructions from the KnownBits propagation can complicate
666+ // the optimization, which would just replace the entire loop with the
667+ // table-lookup version of the hash algorithm.
668+ if (any_of (*Latch, [VE](const Instruction &I) { return !VE.isVisited (&I); }))
669+ return " Found stray unvisited instructions" ;
670+
637671 unsigned N = std::min (TC, ResultBits.getBitWidth ());
638672 auto IsZero = [](const KnownBits &K) { return K.isZero (); };
639673 if (!checkExtractBits (ResultBits, N, IsZero, *ByteOrderSwapped))
0 commit comments