[llvm] [HashRecognize] Tighten pre-conditions for analysis (PR #144757)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 18 10:41:55 PDT 2025
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/144757
>From 86904ee25b85e01e8f3711f032ff4e7c2e81f2a5 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 18 Jun 2025 18:07:01 +0100
Subject: [PATCH 1/3] [HashRecognize] Tighten pre-conditions for analysis
Exit early if the TC is not a byte-multiple, as optimization works by
dividing TC by 8. Also delay the SCEV TC query.
---
llvm/lib/Analysis/HashRecognize.cpp | 8 ++++----
.../Analysis/HashRecognize/cyclic-redundancy-check.ll | 6 +++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 1edb8b3bdc9a8..60d2480a07096 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -561,14 +561,14 @@ std::variant<PolynomialInfo, ErrBits, StringRef>
HashRecognize::recognizeCRC() const {
if (!L.isInnermost())
return "Loop is not innermost";
- unsigned TC = SE.getSmallConstantMaxTripCount(&L);
- if (!TC || TC > 256)
- return "Unable to find a small constant trip count";
BasicBlock *Latch = L.getLoopLatch();
BasicBlock *Exit = L.getExitBlock();
const PHINode *IndVar = L.getCanonicalInductionVariable();
- if (!Latch || !Exit || !IndVar)
+ if (!Latch || !Exit || !IndVar || L.getNumBlocks() != 1)
return "Loop not in canonical form";
+ unsigned TC = SE.getSmallConstantTripCount(&L);
+ if (!TC || TC > 256 || TC % 8)
+ return "Unable to find a small constant byte-multiple trip count";
auto R = getRecurrences(Latch, IndVar, L);
if (!R)
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 7a3082056ad29..2c2e45aa09589 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -384,7 +384,7 @@ exit: ; preds = %loop
define i16 @not.crc.non.const.tc(i16 %crc.init, i32 %loop.limit) {
; CHECK-LABEL: 'not.crc.non.const.tc'
; CHECK-NEXT: Did not find a hash algorithm
-; CHECK-NEXT: Reason: Unable to find a small constant trip count
+; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
;
entry:
br label %loop
@@ -430,7 +430,7 @@ exit: ; preds = %loop
define i16 @not.crc.tc.limit(i16 %crc.init) {
; CHECK-LABEL: 'not.crc.tc.limit'
; CHECK-NEXT: Did not find a hash algorithm
-; CHECK-NEXT: Reason: Unable to find a small constant trip count
+; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
;
entry:
br label %loop
@@ -617,7 +617,7 @@ loop: ; preds = %loop, %entry
%crc.xor = xor i16 %crc.lshr, -24575
%crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %crc.xor
%iv.next = add nuw nsw i8 %iv, 1
- %exit.cond = icmp samesign ult i8 %iv, 20
+ %exit.cond = icmp samesign ult i8 %iv, 31
br i1 %exit.cond, label %loop, label %exit
exit: ; preds = %loop
>From 61296b6fda61b799729b840935c600ad8ce0baa4 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 18 Jun 2025 18:37:13 +0100
Subject: [PATCH 2/3] [HashRecognize] Add test with multiple blocks
---
.../HashRecognize/cyclic-redundancy-check.ll | 33 +++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 2c2e45aa09589..6c66d7e26b9f6 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -404,8 +404,8 @@ exit: ; preds = %loop
ret i16 %crc.next
}
-define i16 @not.crc.non.canonical.loop(i16 %crc.init) {
-; CHECK-LABEL: 'not.crc.non.canonical.loop'
+define i16 @not.crc.non.canonical.loop.countdown(i16 %crc.init) {
+; CHECK-LABEL: 'not.crc.non.canonical.loop.countdown'
; CHECK-NEXT: Did not find a hash algorithm
; CHECK-NEXT: Reason: Loop not in canonical form
;
@@ -427,6 +427,35 @@ exit: ; preds = %loop
ret i16 %crc.next
}
+define i16 @not.crc.non.canonical.loop.multiple.blocks(i16 %crc.init) {
+; CHECK-LABEL: 'not.crc.non.canonical.loop.multiple.blocks'
+; CHECK-NEXT: Did not find a hash algorithm
+; CHECK-NEXT: Reason: Loop not in canonical form
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %continue ]
+ %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %continue ]
+ %check.sb = icmp slt i16 %crc, 0
+ %crc.shl = shl i16 %crc, 1
+ br i1 %check.sb, label %xor, label %continue
+
+xor:
+ %crc.xor = xor i16 %crc.shl, 4129
+ br label %continue
+
+continue:
+ %crc.next = phi i16 [ %crc.xor, %xor ], [ %crc.shl, %loop ]
+ %iv.next = add nuw nsw i32 %iv, 1
+ %exit.cond = icmp samesign eq i32 %iv, 7
+ br i1 %exit.cond, label %exit, label %loop
+
+exit: ; preds = %loop
+ ret i16 %crc.next
+}
+
define i16 @not.crc.tc.limit(i16 %crc.init) {
; CHECK-LABEL: 'not.crc.tc.limit'
; CHECK-NEXT: Did not find a hash algorithm
>From 982f8d8a1e4c50917358501d2bbc12ab670c321f Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 18 Jun 2025 18:41:14 +0100
Subject: [PATCH 3/3] [HashRecognize] Add test for TC % 8 != 0
---
.../HashRecognize/cyclic-redundancy-check.ll | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 6c66d7e26b9f6..6006ebd529583 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -404,6 +404,29 @@ exit: ; preds = %loop
ret i16 %crc.next
}
+define i16 @not.crc.non.canonical.not.multiple.8(i16 %crc.init) {
+; CHECK-LABEL: 'not.crc.non.canonical.not.multiple.8'
+; CHECK-NEXT: Did not find a hash algorithm
+; CHECK-NEXT: Reason: Unable to find a small constant byte-multiple trip count
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+ %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+ %crc.shl = shl i16 %crc, 1
+ %crc.xor = xor i16 %crc.shl, 4129
+ %check.sb = icmp slt i16 %crc, 0
+ %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+ %iv.next = add nuw nsw i32 %iv, 1
+ %exit.cond = icmp samesign eq i32 %iv, 3
+ br i1 %exit.cond, label %exit, label %loop
+
+exit: ; preds = %loop
+ ret i16 %crc.next
+}
+
define i16 @not.crc.non.canonical.loop.countdown(i16 %crc.init) {
; CHECK-LABEL: 'not.crc.non.canonical.loop.countdown'
; CHECK-NEXT: Did not find a hash algorithm
More information about the llvm-commits
mailing list