[llvm] [HashRecognize] Strip ValueEvolution (PR #148620)

Piotr Fusik via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 4 06:14:17 PDT 2025


================
@@ -320,6 +149,60 @@ struct RecurrenceInfo {
       Instruction::BinaryOps BOWithConstOpToMatch = Instruction::BinaryOpsEnd);
 };
 
+/// Check the well-formedness of the (most|least) significant bit check given \p
+/// ConditionalRecurrence, \p SimpleRecurrence, depending on \p
+/// ByteOrderSwapped. We check that ConditionalRecurrence.Step is a
+/// Select(Cmp()) where the compare is `>= 0` in the big-endian case, and `== 0`
+/// in the little-endian case (or the inverse, in which case the branches of the
+/// compare are swapped). We check that the LHS is (ConditionalRecurrence.Phi
+/// [xor SimpleRecurrence.Phi]) in the big-endian case, and additionally check
+/// for an AND with one in the little-endian case. We then check AllowedByR
+/// against CheckAllowedByR, which is [0, smin) in the big-endian case, and
+/// against [0, 1) in the little-endian case: CheckAllowedByR checks for
+/// significant-bit-clear, and we match the corresponding arms of the select
+/// against bit-shift and bit-shift-and-xor-gen-poly.
+static bool
+isSignificantBitCheckWellFormed(const RecurrenceInfo &ConditionalRecurrence,
+                                const RecurrenceInfo &SimpleRecurrence,
+                                bool ByteOrderSwapped) {
+  auto *SI = cast<SelectInst>(ConditionalRecurrence.Step);
+  CmpPredicate Pred;
+  const Value *L;
+  const APInt *R;
+  Instruction *TV, *FV;
+  if (!match(SI, m_Select(m_ICmp(Pred, m_Value(L), m_APInt(R)),
+                          m_Instruction(TV), m_Instruction(FV))))
+    return false;
+
+  // Match predicate with or without a SimpleRecurrence (the corresponding data
+  // is LHSAux).
+  auto MatchPred = m_CombineOr(
+      m_Specific(ConditionalRecurrence.Phi),
+      m_c_Xor(m_ZExtOrTruncOrSelf(m_Specific(ConditionalRecurrence.Phi)),
+              m_ZExtOrTruncOrSelf(m_Specific(SimpleRecurrence.Phi))));
+  bool LWellFormed = ByteOrderSwapped ? match(L, MatchPred)
+                                      : match(L, m_c_And(MatchPred, m_One()));
+  if (!LWellFormed)
+    return false;
+
+  KnownBits KnownR = KnownBits::makeConstant(*R);
+  unsigned BW = KnownR.getBitWidth();
+  auto RCR = ConstantRange::fromKnownBits(KnownR, false);
+  auto AllowedByR = ConstantRange::makeAllowedICmpRegion(Pred, RCR);
+  ConstantRange CheckAllowedByR(APInt::getZero(BW),
+                                ByteOrderSwapped ? APInt::getSignedMinValue(BW)
+                                                 : APInt(BW, 1));
+
+  BinaryOperator *BitShift = ConditionalRecurrence.BO;
+  if (AllowedByR == CheckAllowedByR)
+    return TV == BitShift &&
+           match(FV, m_c_Xor(m_Specific(BitShift), m_Constant()));
+  if (AllowedByR.inverse() == CheckAllowedByR)
+    return FV == BitShift &&
+           match(TV, m_c_Xor(m_Specific(BitShift), m_Constant()));
----------------
pfusik wrote:

```suggestion
           match(TV, m_c_Xor(m_Specific(BitShift), m_APInt(ConditionalRecurrence.ExtraConst)));
```

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


More information about the llvm-commits mailing list