@@ -182,33 +182,31 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I,
182
182
Value *L, *R, *TV, *FV;
183
183
if (match (I, m_Select (m_ICmp (Pred, m_Value (L), m_Value (R)), m_Value (TV),
184
184
m_Value (FV)))) {
185
- KnownBits KnownL = compute (L, KnownPhis).zextOrTrunc (BitWidth);
186
- KnownBits KnownR = compute (R, KnownPhis).zextOrTrunc (BitWidth);
187
- KnownBits KnownTV = compute (TV, KnownPhis);
188
- KnownBits KnownFV = compute (FV, KnownPhis);
189
- auto LCR = ConstantRange::fromKnownBits (KnownL, false );
190
- auto RCR = ConstantRange::fromKnownBits (KnownR, false );
191
-
192
185
// We need to check LCR against [0, 2) in the little-endian case, because
193
186
// the RCR check is insufficient: it is simply [0, 1).
194
- auto CheckLCR = ConstantRange (APInt::getZero (BitWidth), APInt (BitWidth, 2 ));
195
- if (!ByteOrderSwapped && LCR != CheckLCR) {
196
- ErrStr = " Bad LHS of significant-bit-check" ;
197
- return {BitWidth};
187
+ if (!ByteOrderSwapped) {
188
+ KnownBits KnownL = compute (L, KnownPhis).zextOrTrunc (BitWidth);
189
+ auto LCR = ConstantRange::fromKnownBits (KnownL, false );
190
+ auto CheckLCR =
191
+ ConstantRange (APInt::getZero (BitWidth), APInt (BitWidth, 2 ));
192
+ if (LCR != CheckLCR) {
193
+ ErrStr = " Bad LHS of significant-bit-check" ;
194
+ return {BitWidth};
195
+ }
198
196
}
199
197
200
198
// Check that the predication is on (most|least) significant bit.
199
+ KnownBits KnownR = compute (R, KnownPhis).zextOrTrunc (BitWidth);
200
+ auto RCR = ConstantRange::fromKnownBits (KnownR, false );
201
201
auto AllowedR = ConstantRange::makeAllowedICmpRegion (Pred, RCR);
202
- auto InverseR = ConstantRange::makeAllowedICmpRegion (
203
- CmpInst::getInversePredicate (Pred), RCR);
204
202
ConstantRange LSBRange (APInt::getZero (BitWidth), APInt (BitWidth, 1 ));
205
203
ConstantRange MSBRange (APInt::getZero (BitWidth),
206
204
APInt::getSignedMinValue (BitWidth));
207
205
const ConstantRange &CheckRCR = ByteOrderSwapped ? MSBRange : LSBRange;
208
206
if (AllowedR == CheckRCR)
209
- return KnownTV ;
207
+ return compute (TV, KnownPhis) ;
210
208
if (AllowedR.inverse () == CheckRCR)
211
- return KnownFV ;
209
+ return compute (FV, KnownPhis) ;
212
210
213
211
ErrStr = " Bad RHS of significant-bit-check" ;
214
212
return {BitWidth};
@@ -233,9 +231,8 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I,
233
231
// / Compute the KnownBits of Value \p V.
234
232
KnownBits ValueEvolution::compute (const Value *V,
235
233
const KnownPhiMap &KnownPhis) {
236
- const APInt *C;
237
- if (match (V, m_APInt (C)))
238
- return KnownBits::makeConstant (*C);
234
+ if (auto *CI = dyn_cast<ConstantInt>(V))
235
+ return KnownBits::makeConstant (CI->getValue ());
239
236
240
237
if (auto *I = dyn_cast<Instruction>(V))
241
238
return computeInstr (I, KnownPhis);
@@ -260,7 +257,7 @@ ValueEvolution::computeEvolutions(ArrayRef<PhiStepPair> PhiEvolutions) {
260
257
KnownPhis.emplace_or_assign (Phi, KnownAtIter);
261
258
}
262
259
}
263
- return KnownPhis;
260
+ return hasError () ? std::nullopt : std::make_optional ( KnownPhis) ;
264
261
}
265
262
266
263
// / A structure that can hold either a Simple Recurrence or a Conditional
@@ -375,11 +372,11 @@ RecurrenceInfo::digRecurrence(Instruction *V,
375
372
// / where %tv and %fv ultimately end up using %rec via the same %BO instruction,
376
373
// / after digging through the use-def chain.
377
374
// /
378
- // / \p ExtraConst is relevant if \p BOWithConstOpToMatch is supplied: when
379
- // / digging the use-def chain, a BinOp with opcode \p BOWithConstOpToMatch is
380
- // / matched, and \p ExtraConst is a constant operand of that BinOp. This
381
- // / peculiarity exists, because in a CRC algorithm, the \p BOWithConstOpToMatch
382
- // / is an XOR, and the \p ExtraConst ends up being the generating polynomial.
375
+ // / ExtraConst is relevant if \p BOWithConstOpToMatch is supplied: when digging
376
+ // / the use-def chain, a BinOp with opcode \p BOWithConstOpToMatch is matched,
377
+ // / and ExtraConst is a constant operand of that BinOp. This peculiarity exists,
378
+ // / because in a CRC algorithm, the \p BOWithConstOpToMatch is an XOR, and the
379
+ // / ExtraConst ends up being the generating polynomial.
383
380
bool RecurrenceInfo::matchConditionalRecurrence (
384
381
const PHINode *P, Instruction::BinaryOps BOWithConstOpToMatch) {
385
382
Phi = P;
@@ -447,9 +444,11 @@ PolynomialInfo::PolynomialInfo(unsigned TripCount, const Value *LHS,
447
444
: TripCount(TripCount), LHS(LHS), RHS(RHS), ComputedValue(ComputedValue),
448
445
ByteOrderSwapped(ByteOrderSwapped), LHSAux(LHSAux) {}
449
446
450
- // / In big-endian case, checks that the bottom N bits against CheckFn, and that
451
- // / the rest are unknown. In little-endian case, checks that the top N bits
452
- // / against CheckFn, and that the rest are unknown.
447
+ // / In the big-endian case, checks the bottom N bits against CheckFn, and that
448
+ // / the rest are unknown. In the little-endian case, checks the top N bits
449
+ // / against CheckFn, and that the rest are unknown. Callers usually call this
450
+ // / function with N = TripCount, and CheckFn checking that the remainder bits of
451
+ // / the CRC polynomial division are zero.
453
452
static bool checkExtractBits (const KnownBits &Known, unsigned N,
454
453
function_ref<bool (const KnownBits &)> CheckFn,
455
454
bool ByteOrderSwapped) {
@@ -555,7 +554,7 @@ HashRecognize::recognizeCRC() const {
555
554
if (!L.isInnermost ())
556
555
return " Loop is not innermost" ;
557
556
unsigned TC = SE.getSmallConstantMaxTripCount (&L);
558
- if (!TC)
557
+ if (!TC || TC > 256 )
559
558
return " Unable to find a small constant trip count" ;
560
559
BasicBlock *Latch = L.getLoopLatch ();
561
560
BasicBlock *Exit = L.getExitBlock ();
@@ -600,7 +599,9 @@ HashRecognize::recognizeCRC() const {
600
599
const APInt &GenPoly = *ConditionalRecurrence.ExtraConst ;
601
600
602
601
// PhiEvolutions are pairs of PHINodes along with their incoming value from
603
- // within the loop, which we term as their step.
602
+ // within the loop, which we term as their step. Note that in the case of a
603
+ // Simple Recurrence, Step is an operand of the BO, while in a Conditional
604
+ // Recurrence, it is a SelectInst.
604
605
SmallVector<PhiStepPair, 2 > PhiEvolutions;
605
606
PhiEvolutions.emplace_back (ConditionalRecurrence.Phi , ComputedValue);
606
607
if (SimpleRecurrence)
0 commit comments