[llvm] [HashRecognize] Strip ValueEvolution (PR #148620)
    Piotr Fusik via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Tue Sep  2 06:20:04 PDT 2025
    
    
  
================
@@ -73,202 +73,31 @@ using namespace SCEVPatternMatch;
 
 #define DEBUG_TYPE "hash-recognize"
 
-// KnownBits for a PHI node. There are at most two PHI nodes, corresponding to
-// the Simple Recurrence and Conditional Recurrence. The IndVar PHI is not
-// relevant.
-using KnownPhiMap = SmallDenseMap<const PHINode *, KnownBits, 2>;
-
-// A pair of a PHI node along with its incoming value from within a loop.
-using PhiStepPair = std::pair<const PHINode *, const Instruction *>;
-
-/// A much simpler version of ValueTracking, in that it computes KnownBits of
-/// values, except that it computes the evolution of KnownBits in a loop with a
-/// given trip count, and predication is specialized for a significant-bit
-/// check.
-class ValueEvolution {
-  const unsigned TripCount;
-  const bool ByteOrderSwapped;
-  APInt GenPoly;
-  StringRef ErrStr;
-
-  // Compute the KnownBits of a BinaryOperator.
-  KnownBits computeBinOp(const BinaryOperator *I);
-
-  // Compute the KnownBits of an Instruction.
-  KnownBits computeInstr(const Instruction *I);
-
-  // Compute the KnownBits of a Value.
-  KnownBits compute(const Value *V);
-
-public:
-  // ValueEvolution is meant to be constructed with the TripCount of the loop,
-  // and a boolean indicating whether the polynomial algorithm is big-endian
-  // (for the significant-bit check).
-  ValueEvolution(unsigned TripCount, bool ByteOrderSwapped);
-
-  // Given a list of PHI nodes along with their incoming value from within the
-  // loop, computeEvolutions computes the KnownBits of each of the PHI nodes on
-  // the final iteration. Returns true on success and false on error.
-  bool computeEvolutions(ArrayRef<PhiStepPair> PhiEvolutions);
-
-  // In case ValueEvolution encounters an error, this is meant to be used for a
-  // precise error message.
-  StringRef getError() const { return ErrStr; }
-
-  // A set of Instructions visited by ValueEvolution. The only unvisited
-  // instructions will be ones not on the use-def chain of the PHIs' evolutions.
+/// Checks if Loop \p L contains instructions unreachable \p Roots on the
+/// use-def chain.
+static bool containsUnreachable(const Loop &L,
+                                ArrayRef<const Instruction *> Roots) {
   SmallPtrSet<const Instruction *, 16> Visited;
+  BasicBlock *Latch = L.getLoopLatch();
 
-  // The computed KnownBits for each PHI node, which is populated after
-  // computeEvolutions is called.
-  KnownPhiMap KnownPhis;
-};
-
-ValueEvolution::ValueEvolution(unsigned TripCount, bool ByteOrderSwapped)
-    : TripCount(TripCount), ByteOrderSwapped(ByteOrderSwapped) {}
-
-KnownBits ValueEvolution::computeBinOp(const BinaryOperator *I) {
-  KnownBits KnownL(compute(I->getOperand(0)));
-  KnownBits KnownR(compute(I->getOperand(1)));
-
-  switch (I->getOpcode()) {
-  case Instruction::BinaryOps::And:
-    return KnownL & KnownR;
-  case Instruction::BinaryOps::Or:
-    return KnownL | KnownR;
-  case Instruction::BinaryOps::Xor:
-    return KnownL ^ KnownR;
-  case Instruction::BinaryOps::Shl: {
-    auto *OBO = cast<OverflowingBinaryOperator>(I);
-    return KnownBits::shl(KnownL, KnownR, OBO->hasNoUnsignedWrap(),
-                          OBO->hasNoSignedWrap());
-  }
-  case Instruction::BinaryOps::LShr:
-    return KnownBits::lshr(KnownL, KnownR);
-  case Instruction::BinaryOps::AShr:
-    return KnownBits::ashr(KnownL, KnownR);
-  case Instruction::BinaryOps::Add: {
-    auto *OBO = cast<OverflowingBinaryOperator>(I);
-    return KnownBits::add(KnownL, KnownR, OBO->hasNoUnsignedWrap(),
-                          OBO->hasNoSignedWrap());
-  }
-  case Instruction::BinaryOps::Sub: {
-    auto *OBO = cast<OverflowingBinaryOperator>(I);
-    return KnownBits::sub(KnownL, KnownR, OBO->hasNoUnsignedWrap(),
-                          OBO->hasNoSignedWrap());
-  }
-  case Instruction::BinaryOps::Mul: {
-    Value *Op0 = I->getOperand(0);
-    Value *Op1 = I->getOperand(1);
-    bool SelfMultiply = Op0 == Op1 && isGuaranteedNotToBeUndef(Op0);
-    return KnownBits::mul(KnownL, KnownR, SelfMultiply);
-  }
-  case Instruction::BinaryOps::UDiv:
-    return KnownBits::udiv(KnownL, KnownR);
-  case Instruction::BinaryOps::SDiv:
-    return KnownBits::sdiv(KnownL, KnownR);
-  case Instruction::BinaryOps::URem:
-    return KnownBits::urem(KnownL, KnownR);
-  case Instruction::BinaryOps::SRem:
-    return KnownBits::srem(KnownL, KnownR);
-  default:
-    ErrStr = "Unknown BinaryOperator";
-    unsigned BitWidth = I->getType()->getScalarSizeInBits();
-    return {BitWidth};
-  }
-}
-
-KnownBits ValueEvolution::computeInstr(const Instruction *I) {
-  unsigned BitWidth = I->getType()->getScalarSizeInBits();
-
-  // computeInstr is the only entry-point that needs to update the Visited set.
-  Visited.insert(I);
+  SmallVector<const Instruction *, 16> Worklist(Roots);
+  while (!Worklist.empty()) {
+    const Instruction *I = Worklist.pop_back_val();
+    Visited.insert(I);
 
-  // We look up in the map that contains the KnownBits of the PHI from the
-  // previous iteration.
-  if (const PHINode *P = dyn_cast<PHINode>(I))
-    return KnownPhis.lookup_or(P, BitWidth);
+    if (isa<PHINode>(I))
+      continue;
 
-  // 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;
-  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)));
-
-    // We need to check LCR against [0, 2) in the little-endian case, because
-    // the RCR check is insufficient: it is simply [0, 1).
-    if (!ByteOrderSwapped) {
-      KnownBits KnownL = compute(L);
-      unsigned ICmpBW = KnownL.getBitWidth();
-      auto LCR = ConstantRange::fromKnownBits(KnownL, false);
-      auto CheckLCR = ConstantRange(APInt::getZero(ICmpBW), APInt(ICmpBW, 2));
-      if (LCR != CheckLCR) {
-        ErrStr = "Bad LHS of significant-bit-check";
-        return {BitWidth};
+    for (const Use &U : I->operands()) {
+      if (auto *UI = dyn_cast<Instruction>(U)) {
+        if (!L.contains(UI))
+          return true;
+        Worklist.push_back(UI);
+        continue;
----------------
pfusik wrote:
Redundant `continue`.
https://github.com/llvm/llvm-project/pull/148620
    
    
More information about the llvm-commits
mailing list