[llvm] 34a34f1 - [HashRecognize] Prevent values other than `ComputedValue` from exiting loop (#213080)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 31 09:19:55 PDT 2026


Author: Sean Clarke
Date: 2026-07-31T16:19:50Z
New Revision: 34a34f1dac1d40e2ba49f39e9ebce8eafdf44ecc

URL: https://github.com/llvm/llvm-project/commit/34a34f1dac1d40e2ba49f39e9ebce8eafdf44ecc
DIFF: https://github.com/llvm/llvm-project/commit/34a34f1dac1d40e2ba49f39e9ebce8eafdf44ecc.diff

LOG: [HashRecognize] Prevent values other than `ComputedValue` from exiting loop (#213080)

A check exists to prevent recurrences from having stray uses, but this
is only applied when a simple recurrence exists, and does not apply to
other values such as the induction variable. Since the loop is in LCSSA
form, check the incoming value from the loop on each of the exit block
PHIs and bail if any of them are not `ComputedValue`.

This replaces the existing check requiring `ComputedValue` to be used in
the exit block. Note that this no longer covers the case where the exit
block has no PHIs, and therefore does not use `ComputedValue`. In this
case, the loop is dead and will be cleaned up by DCE anyway.

Added: 
    

Modified: 
    llvm/lib/Analysis/HashRecognize.cpp
    llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index ade4be565ee11..c7699ccfbd9ce 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -578,15 +578,14 @@ std::variant<PolynomialInfo, StringRef> HashRecognize::recognizeCRC() const {
                    : LHS->getType()->getIntegerBitWidth()))
     return "Loop iterations exceed bitwidth of data";
 
-  // Make sure that the computed value is used in the exit block: this should be
-  // true even if it is only really used in an outer loop's exit block, since
-  // the loop is in LCSSA form.
+  // Ensure nothing other than the computed value makes its way out of the loop.
+  // Since the loop is in LCSSA form, this is as simple as checking the PHI
+  // nodes in the exit block.
   auto *ComputedValue = cast<SelectInst>(ConditionalRecurrence.Step);
-  if (none_of(ComputedValue->users(), [Exit](User *U) {
-        auto *UI = dyn_cast<Instruction>(U);
-        return UI && UI->getParent() == Exit;
+  if (any_of(Exit->phis(), [Latch, ComputedValue](PHINode &PN) {
+        return PN.getIncomingValueForBlock(Latch) != ComputedValue;
       }))
-    return "Unable to find use of computed value in loop exit block";
+    return "Found stray incoming values in loop exit block";
 
   assert(ConditionalRecurrence.ExtraConst &&
          "Expected ExtraConst in conditional recurrence");

diff  --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 1a17a82f1bff1..9c6b41ad2cf3a 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -1030,7 +1030,7 @@ exit:                                              ; preds = %loop
 define i16 @not.crc.result.unused(i16 %crc.init) {
 ; CHECK-LABEL: 'not.crc.result.unused'
 ; CHECK-NEXT:  Did not find a hash algorithm
-; CHECK-NEXT:  Reason: Unable to find use of computed value in loop exit block
+; CHECK-NEXT:  Reason: Found stray incoming values in loop exit block
 ;
 entry:
   br label %loop
@@ -1886,4 +1886,55 @@ exit:
   ret i16 %ret
 }
 
+define i16 @not.crc.crc.phi.outside.user.nodata(i16 %crc.init) {
+; CHECK-LABEL: 'not.crc.crc.phi.outside.user.nodata'
+; CHECK-NEXT:  Did not find a hash algorithm
+; CHECK-NEXT:  Reason: Found stray incoming values in loop exit block
+;
+entry:
+  br label %loop
+
+loop:
+  %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, 3
+  %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 ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:
+  %ret = xor i16 %crc, %crc.next
+  ret i16 %ret
+}
+
+define i16 @not.crc.iv.phi.outside.user(i16 %crc.init, i16 %data.init) {
+; CHECK-LABEL: 'not.crc.iv.phi.outside.user'
+; CHECK-NEXT:  Did not find a hash algorithm
+; CHECK-NEXT:  Reason: Found stray incoming values in loop exit block
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %data.init, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %data, %crc
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 3
+  %check.sb = icmp slt i16 %xor.crc.data, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %data.next = shl i16 %data, 1
+  %iv.next = add nuw nsw i16 %iv, 1
+  %exit.cond = icmp samesign ult i16 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:
+  %ret = xor i16 %iv, %crc.next
+  ret i16 %ret
+}
+
 declare i16 @side.effect()


        


More information about the llvm-commits mailing list