[llvm] [HashRecognize] Track visited in ValueEvolution (PR #147812)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 14 06:22:49 PDT 2025


================
@@ -185,9 +199,14 @@ KnownBits ValueEvolution::computeInstr(const Instruction *I) {
   // Compute the KnownBits for a Select(Cmp()), forcing it to take the branch
   // that is predicated on the (least|most)-significant-bit check.
   CmpPredicate Pred;
-  Value *L, *R, *TV, *FV;
-  if (match(I, m_Select(m_ICmp(Pred, m_Value(L), m_Value(R)), m_Value(TV),
-                        m_Value(FV)))) {
+  Value *L, *R;
+  Instruction *TV, *FV;
+  if (match(I, m_Select(m_ICmp(Pred, m_Value(L), m_Value(R)), m_Instruction(TV),
+                        m_Instruction(FV)))) {
+    Visited.insert(cast<Instruction>(I->getOperand(0)));
+    Visited.insert(TV);
+    Visited.insert(FV);
----------------
artagnon wrote:

So this is the CRC algorithm:

```c
#define CRCLOOP_LE(ty, genpoly, crc, data)                                     \
  {                                                                            \
    for (size_t i = 0; i < BW(data); ++i) {                                    \
      ty xor_crc_data = crc ^ data;                                            \
      ty crc_lshr = crc >> 1;                                                  \
      crc = (xor_crc_data & 1) ? (crc_lshr ^ genpoly) : crc_lshr;              \
      data >>= 1;                                                              \
    }                                                                          \
  }
```

In the branching step, ` crc = (xor_crc_data & 1) ? (crc_lshr ^ genpoly) : crc_lshr`, we force the conditional to always compute `crc_lshr ^ genpoly`, as we would have a fork in the KnownBits at each iteration otherwise, leading to 2^TC KnownBits. We actually compute the KnownBits of:

```c
#define CRCLOOP_LE(ty, genpoly, crc, data)                                     \
  {                                                                            \
    for (size_t i = 0; i < BW(data); ++i) {                                    \
      ty xor_crc_data = crc ^ data;                                            \
      ty crc_lshr = crc >> 1;                                                  \
      crc = crc_lshr ^ genpoly;              \
      data >>= 1;                                                              \
    }                                                                          \
  }
```

which is guaranteed to be zero, if the algorithm is well-formed, and match various constructs including the xors and bit-shifts, to ensure that we're computing KnownBits of something that reasonably matches a CRC, and not of a constant zero, for example.

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


More information about the llvm-commits mailing list