Skip to content

Commit 156a64c

Browse files
authored
[HashRecognize] Tighten pre-conditions for analysis (#144757)
Exit early if the TC is not a byte-multiple, as optimization works by dividing TC by 8. Also delay the SCEV TC query.
1 parent f13b9e3 commit 156a64c

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

llvm/lib/Analysis/HashRecognize.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -561,14 +561,14 @@ std::variant<PolynomialInfo, ErrBits, StringRef>
561561
HashRecognize::recognizeCRC() const {
562562
if (!L.isInnermost())
563563
return "Loop is not innermost";
564-
unsigned TC = SE.getSmallConstantMaxTripCount(&L);
565-
if (!TC || TC > 256)
566-
return "Unable to find a small constant trip count";
567564
BasicBlock *Latch = L.getLoopLatch();
568565
BasicBlock *Exit = L.getExitBlock();
569566
const PHINode *IndVar = L.getCanonicalInductionVariable();
570-
if (!Latch || !Exit || !IndVar)
567+
if (!Latch || !Exit || !IndVar || L.getNumBlocks() != 1)
571568
return "Loop not in canonical form";
569+
unsigned TC = SE.getSmallConstantTripCount(&L);
570+
if (!TC || TC > 256 || TC % 8)
571+
return "Unable to find a small constant byte-multiple trip count";
572572

573573
auto R = getRecurrences(Latch, IndVar, L);
574574
if (!R)

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

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ exit: ; preds = %loop
384384
define i16 @not.crc.non.const.tc(i16 %crc.init, i32 %loop.limit) {
385385
; CHECK-LABEL: 'not.crc.non.const.tc'
386386
; CHECK-NEXT: Did not find a hash algorithm
387-
; CHECK-NEXT: Reason: Unable to find a small constant trip count
387+
; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
388388
;
389389
entry:
390390
br label %loop
@@ -404,8 +404,31 @@ exit: ; preds = %loop
404404
ret i16 %crc.next
405405
}
406406

407-
define i16 @not.crc.non.canonical.loop(i16 %crc.init) {
408-
; CHECK-LABEL: 'not.crc.non.canonical.loop'
407+
define i16 @not.crc.non.canonical.not.multiple.8(i16 %crc.init) {
408+
; CHECK-LABEL: 'not.crc.non.canonical.not.multiple.8'
409+
; CHECK-NEXT: Did not find a hash algorithm
410+
; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
411+
;
412+
entry:
413+
br label %loop
414+
415+
loop: ; preds = %loop, %entry
416+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
417+
%crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
418+
%crc.shl = shl i16 %crc, 1
419+
%crc.xor = xor i16 %crc.shl, 4129
420+
%check.sb = icmp slt i16 %crc, 0
421+
%crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
422+
%iv.next = add nuw nsw i32 %iv, 1
423+
%exit.cond = icmp samesign eq i32 %iv, 3
424+
br i1 %exit.cond, label %exit, label %loop
425+
426+
exit: ; preds = %loop
427+
ret i16 %crc.next
428+
}
429+
430+
define i16 @not.crc.non.canonical.loop.countdown(i16 %crc.init) {
431+
; CHECK-LABEL: 'not.crc.non.canonical.loop.countdown'
409432
; CHECK-NEXT: Did not find a hash algorithm
410433
; CHECK-NEXT: Reason: Loop not in canonical form
411434
;
@@ -427,10 +450,39 @@ exit: ; preds = %loop
427450
ret i16 %crc.next
428451
}
429452

453+
define i16 @not.crc.non.canonical.loop.multiple.blocks(i16 %crc.init) {
454+
; CHECK-LABEL: 'not.crc.non.canonical.loop.multiple.blocks'
455+
; CHECK-NEXT: Did not find a hash algorithm
456+
; CHECK-NEXT: Reason: Loop not in canonical form
457+
;
458+
entry:
459+
br label %loop
460+
461+
loop: ; preds = %loop, %entry
462+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %continue ]
463+
%crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %continue ]
464+
%check.sb = icmp slt i16 %crc, 0
465+
%crc.shl = shl i16 %crc, 1
466+
br i1 %check.sb, label %xor, label %continue
467+
468+
xor:
469+
%crc.xor = xor i16 %crc.shl, 4129
470+
br label %continue
471+
472+
continue:
473+
%crc.next = phi i16 [ %crc.xor, %xor ], [ %crc.shl, %loop ]
474+
%iv.next = add nuw nsw i32 %iv, 1
475+
%exit.cond = icmp samesign eq i32 %iv, 7
476+
br i1 %exit.cond, label %exit, label %loop
477+
478+
exit: ; preds = %loop
479+
ret i16 %crc.next
480+
}
481+
430482
define i16 @not.crc.tc.limit(i16 %crc.init) {
431483
; CHECK-LABEL: 'not.crc.tc.limit'
432484
; CHECK-NEXT: Did not find a hash algorithm
433-
; CHECK-NEXT: Reason: Unable to find a small constant trip count
485+
; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
434486
;
435487
entry:
436488
br label %loop
@@ -617,7 +669,7 @@ loop: ; preds = %loop, %entry
617669
%crc.xor = xor i16 %crc.lshr, -24575
618670
%crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %crc.xor
619671
%iv.next = add nuw nsw i8 %iv, 1
620-
%exit.cond = icmp samesign ult i8 %iv, 20
672+
%exit.cond = icmp samesign ult i8 %iv, 31
621673
br i1 %exit.cond, label %loop, label %exit
622674

623675
exit: ; preds = %loop

0 commit comments

Comments
 (0)