Skip to content

Commit 21d9756

Browse files
committed
[HashRecognize] Check TC against bitwidth of LHSAux
The trip-count of a CRC algorithm can legitimiately be greater than the bitwidth of the result: what it cannot exceed is the bitwidth of the data, or LHSAux. crc8.le.tc16 is now successfully recognized as a CRC algorithm.
1 parent 201d906 commit 21d9756

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

llvm/lib/Analysis/HashRecognize.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,10 @@ KnownBits ValueEvolution::compute(const Value *V) {
247247
}
248248

249249
bool ValueEvolution::computeEvolutions(ArrayRef<PhiStepPair> PhiEvolutions) {
250-
for (unsigned I = 0; I < TripCount; ++I) {
251-
for (auto [Phi, Step] : PhiEvolutions) {
252-
KnownBits KnownAtIter = computeInstr(Step);
253-
if (KnownAtIter.getBitWidth() < I + 1) {
254-
ErrStr = "Loop iterations exceed bitwidth of result";
255-
return false;
256-
}
257-
KnownPhis.emplace_or_assign(Phi, KnownAtIter);
258-
}
259-
}
250+
for (unsigned I = 0; I < TripCount; ++I)
251+
for (auto [Phi, Step] : PhiEvolutions)
252+
KnownPhis.emplace_or_assign(Phi, computeInstr(Step));
253+
260254
return ErrStr.empty();
261255
}
262256

@@ -583,6 +577,13 @@ HashRecognize::recognizeCRC() const {
583577
return "Recurrences not intertwined with XOR";
584578
}
585579

580+
// Make sure that the TC doesn't exceed the bitwidth of LHSAux, or LHS.
581+
Value *LHS = ConditionalRecurrence.Start;
582+
Value *LHSAux = SimpleRecurrence ? SimpleRecurrence.Start : nullptr;
583+
if (TC > (LHSAux ? LHSAux->getType()->getIntegerBitWidth()
584+
: LHS->getType()->getIntegerBitWidth()))
585+
return "Loop iterations exceed bitwidth of data";
586+
586587
// Make sure that the computed value is used in the exit block: this should be
587588
// true even if it is only really used in an outer loop's exit block, since
588589
// the loop is in LCSSA form.
@@ -612,12 +613,12 @@ HashRecognize::recognizeCRC() const {
612613
KnownBits ResultBits = VE.KnownPhis.at(ConditionalRecurrence.Phi);
613614

614615
auto IsZero = [](const KnownBits &K) { return K.isZero(); };
615-
if (!checkExtractBits(ResultBits, TC, IsZero, *ByteOrderSwapped))
616+
if (!checkExtractBits(ResultBits, std::min(TC, ResultBits.getBitWidth()),
617+
IsZero, *ByteOrderSwapped))
616618
return ErrBits(ResultBits, TC, *ByteOrderSwapped);
617619

618-
Value *LHSAux = SimpleRecurrence ? SimpleRecurrence.Start : nullptr;
619-
return PolynomialInfo(TC, ConditionalRecurrence.Start, GenPoly, ComputedValue,
620-
*ByteOrderSwapped, LHSAux);
620+
return PolynomialInfo(TC, LHS, GenPoly, ComputedValue, *ByteOrderSwapped,
621+
LHSAux);
621622
}
622623

623624
void CRCTable::print(raw_ostream &OS) const {

llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,28 @@ exit: ; preds = %loop
146146

147147
define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
148148
; CHECK-LABEL: 'crc8.le.tc16'
149-
; CHECK-NEXT: Did not find a hash algorithm
150-
; CHECK-NEXT: Reason: Loop iterations exceed bitwidth of result
149+
; CHECK-NEXT: Found little-endian CRC-8 loop with trip count 16
150+
; CHECK-NEXT: Initial CRC: i8 %checksum
151+
; CHECK-NEXT: Generating polynomial: 29
152+
; CHECK-NEXT: Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
153+
; CHECK-NEXT: Auxiliary data: i16 %msg
154+
; CHECK-NEXT: Computed CRC lookup table:
155+
; CHECK-NEXT: 0 9 18 27 31 22 13 4 5 12 23 30 26 19 8 1
156+
; CHECK-NEXT: 10 3 24 17 21 28 7 14 15 6 29 20 16 25 2 11
157+
; CHECK-NEXT: 20 29 6 15 11 2 25 16 17 24 3 10 14 7 28 21
158+
; CHECK-NEXT: 30 23 12 5 1 8 19 26 27 18 9 0 4 13 22 31
159+
; CHECK-NEXT: 19 26 1 8 12 5 30 23 22 31 4 13 9 0 27 18
160+
; CHECK-NEXT: 25 16 11 2 6 15 20 29 28 21 14 7 3 10 17 24
161+
; CHECK-NEXT: 7 14 21 28 24 17 10 3 2 11 16 25 29 20 15 6
162+
; CHECK-NEXT: 13 4 31 22 18 27 0 9 8 1 26 19 23 30 5 12
163+
; CHECK-NEXT: 29 20 15 6 2 11 16 25 24 17 10 3 7 14 21 28
164+
; CHECK-NEXT: 23 30 5 12 8 1 26 19 18 27 0 9 13 4 31 22
165+
; CHECK-NEXT: 9 0 27 18 22 31 4 13 12 5 30 23 19 26 1 8
166+
; CHECK-NEXT: 3 10 17 24 28 21 14 7 6 15 20 29 25 16 11 2
167+
; CHECK-NEXT: 14 7 28 21 17 24 3 10 11 2 25 16 20 29 6 15
168+
; CHECK-NEXT: 4 13 22 31 27 18 9 0 1 8 19 26 30 23 12 5
169+
; CHECK-NEXT: 26 19 8 1 5 12 23 30 31 22 13 4 0 9 18 27
170+
; CHECK-NEXT: 16 25 2 11 15 6 29 20 21 28 7 14 10 3 24 17
151171
;
152172
entry:
153173
br label %loop
@@ -679,7 +699,7 @@ exit: ; preds = %loop
679699
define i16 @not.crc.excess.tc(i16 %msg, i16 %checksum) {
680700
; CHECK-LABEL: 'not.crc.excess.tc'
681701
; CHECK-NEXT: Did not find a hash algorithm
682-
; CHECK-NEXT: Reason: Loop iterations exceed bitwidth of result
702+
; CHECK-NEXT: Reason: Loop iterations exceed bitwidth of data
683703
;
684704
entry:
685705
br label %loop

0 commit comments

Comments
 (0)