@@ -102,8 +102,8 @@ class ValueEvolution {
102
102
103
103
public:
104
104
// 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) .
107
107
ValueEvolution (unsigned TripCount, bool ByteOrderSwapped);
108
108
109
109
// Given a list of PHI nodes along with their incoming value from within the
@@ -115,6 +115,10 @@ class ValueEvolution {
115
115
// precise error message.
116
116
StringRef getError () const { return ErrStr; }
117
117
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
+
118
122
// The computed KnownBits for each PHI node, which is populated after
119
123
// computeEvolutions is called.
120
124
KnownPhiMap KnownPhis;
@@ -177,6 +181,9 @@ KnownBits ValueEvolution::computeBinOp(const BinaryOperator *I) {
177
181
KnownBits ValueEvolution::computeInstr (const Instruction *I) {
178
182
unsigned BitWidth = I->getType ()->getScalarSizeInBits ();
179
183
184
+ // computeInstr is the only entry-point that needs to update the Visited set.
185
+ Visited.insert (I);
186
+
180
187
// We look up in the map that contains the KnownBits of the PHI from the
181
188
// previous iteration.
182
189
if (const PHINode *P = dyn_cast<PHINode>(I))
@@ -185,9 +192,12 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
185
192
// Compute the KnownBits for a Select(Cmp()), forcing it to take the branch
186
193
// that is predicated on the (least|most)-significant-bit check.
187
194
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
+
191
201
// We need to check LCR against [0, 2) in the little-endian case, because
192
202
// the RCR check is insufficient: it is simply [0, 1).
193
203
if (!ByteOrderSwapped) {
@@ -209,10 +219,17 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
209
219
ConstantRange CheckRCR (APInt::getZero (ICmpBW),
210
220
ByteOrderSwapped ? APInt::getSignedMinValue (ICmpBW)
211
221
: 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);
213
227
return compute (TV);
214
- if (AllowedR.inverse () == CheckRCR)
228
+ }
229
+ if (AllowedR.inverse () == CheckRCR) {
230
+ Visited.insert (TV);
215
231
return compute (FV);
232
+ }
216
233
217
234
ErrStr = " Bad RHS of significant-bit-check" ;
218
235
return {BitWidth};
@@ -634,6 +651,17 @@ HashRecognize::recognizeCRC() const {
634
651
return VE.getError ();
635
652
KnownBits ResultBits = VE.KnownPhis .at (ConditionalRecurrence.Phi );
636
653
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
+
637
665
unsigned N = std::min (TC, ResultBits.getBitWidth ());
638
666
auto IsZero = [](const KnownBits &K) { return K.isZero (); };
639
667
if (!checkExtractBits (ResultBits, N, IsZero, *ByteOrderSwapped))
0 commit comments