[llvm] [HashRecognize] Rewrite arePHIsIntertwined (PR #144878)

Piotr Fusik via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 1 04:47:38 PDT 2025


================
@@ -497,42 +497,46 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
   return Table;
 }
 
-/// Checks if \p Reference is reachable from \p Needle on the use-def chain, and
-/// that there are no stray PHI nodes while digging the use-def chain. \p
-/// BOToMatch is a CRC peculiarity: at least one of the Users of Needle needs to
-/// match this OpCode, which is XOR for CRC.
-static bool arePHIsIntertwined(
-    const PHINode *Needle, const PHINode *Reference, const Loop &L,
-    Instruction::BinaryOps BOToMatch = Instruction::BinaryOpsEnd) {
-  // Initialize the worklist with Users of the Needle.
-  SmallVector<const Instruction *> Worklist;
-  for (const User *U : Needle->users()) {
-    if (auto *UI = dyn_cast<Instruction>(U))
-      if (L.contains(UI))
-        Worklist.push_back(UI);
-  }
+/// Checks that \p L and \p R are used together in an XOR in the use-def chain
+/// of \p SI's condition, ignoring any casts. The purpose of this function is to
+/// ensure that LHSAux from the SimpleRecurrence is used correctly in the CRC
+/// computation. We cannot check the correctness of casts at this point, and
+/// rely on the KnownBits propagation to check correctness of the CRC
+/// computation.
+///
+/// In other words, it checks for the following pattern:
+///
+/// loop:
+///   %L = phi [_, %entry], [%L.next, %loop]
+///   %R = phi [_, %entry], [%R.next, %loop]
+///   ...
+///   %xor = xor (CastOrSelf %L), (CastOrSelf %R)
+///
+/// where %xor is in the use-def chain of \p SI's condition.
+static bool isConditionalOnXorOfPHIs(SelectInst *SI, const PHINode *P1,
+                                     const PHINode *P2, const Loop &L) {
+  SmallVector<Instruction *> Worklist;
 
-  // BOToMatch is usually XOR for CRC.
-  if (BOToMatch != Instruction::BinaryOpsEnd) {
-    if (count_if(Worklist, [BOToMatch](const Instruction *I) {
-          return I->getOpcode() == BOToMatch;
-        }) != 1)
-      return false;
-  }
+  // matchConditionalRecurrence has already ensured that the SelectInst's
+  // condition is an Instruction.
+  Worklist.push_back(cast<Instruction>(SI->getCondition()));
 
   while (!Worklist.empty()) {
-    const Instruction *I = Worklist.pop_back_val();
+    Instruction *I = Worklist.pop_back_val();
----------------
pfusik wrote:

Let's keep this `const`. And for `Worklist` elements.

https://github.com/llvm/llvm-project/pull/144878


More information about the llvm-commits mailing list