[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