[llvm] [LoopIdiomRecognizer] Implement CRC recognition (PR #79295)

Mark Zhuang via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 23 23:17:20 PDT 2024


================
@@ -2868,3 +2893,928 @@ bool LoopIdiomRecognize::recognizeShiftUntilZero() {
   ++NumShiftUntilZero;
   return MadeChange;
 }
+
+static uint64_t reverseBits(uint64_t Num, unsigned NumBits) {
+  uint64_t Reversed = 0;
+  for (unsigned i = 1; i <= NumBits; i++) {
+    Reversed |= (Num & 1) << (NumBits - i);
+    Num >>= 1;
+  }
+  return Reversed;
+}
+
+class ValueBits {
+  // This is a representation of a value's bits in terms of references to
+  // other values' bits, or 1/0 if the bit is known. This allows symbolic
+  // execution of bitwise instructions without knowing the exact values.
+  //
+  // Example:
+  //
+  // LLVM IR Value i8 %x:
+  // [%x[7], %x[6], %x[5], %x[4], %x[3], %x[2], %x[1], %x[0]]
+  //
+  // %shr = lshr i8 %x, 2
+  // [ 0, 0, %x[7], %x[6], %x[5], %x[4], %x[3], %x[2]]
+  //
+  // %shl = shl i8 %shr, 1
+  // [ 0, %x[7], %x[6], %x[5], %x[4], %x[3], %x[2], 0]
+  //
+  // %xor = xor i8 %shl, 0xb
+  // [ 0, %x[7], %x[6], %x[5], %x[4]^1, %x[3], %x[2]^1, 1]
+public:
+  class ValueBit {
+  public:
+    enum BitType { ONE, ZERO, REF, XOR };
+
+  private:
+    BitType _Type;
+    std::pair<Value *, uint64_t> _BitRef;
+    // Pointers to LHS and RHS of an XOR operation. These pointers are owned by
+    // the ValueBit object.
+    ValueBit *_LHS = nullptr;
+    ValueBit *_RHS = nullptr;
+
+  public:
+    ValueBit(BitType Type) : _Type(Type) {}
+    ValueBit(BitType Type, std::pair<Value *, uint64_t> BitRef)
+        : _Type(Type), _BitRef(BitRef) {}
+    ValueBit(BitType Type, ValueBit &LHS, ValueBit &RHS)
+        : _Type(Type), _LHS(new ValueBit(LHS)), _RHS(new ValueBit(RHS)) {
+      assert(_Type == BitType::XOR);
+    }
+    ValueBit() = delete;
+    // Define Copy and Assignment constructor to create copies of the LHS and
+    // RHS if the bit type is XOR. This is done to ensure the pointers will be
+    // owned by the ValueBit object and avoid double free in the destructor.
+    ValueBit(const ValueBit &VB) {
+      _Type = VB._Type;
+      if (_Type == BitType::REF)
+        _BitRef = VB._BitRef;
+      else if (_Type == BitType::XOR) {
+        _LHS = new ValueBit(*VB._LHS);
+        _RHS = new ValueBit(*VB._RHS);
+      }
+    }
+    ValueBit& operator=(const ValueBit &VB) {
+      _Type = VB._Type;
+      if (_Type == BitType::REF)
+        _BitRef = VB._BitRef;
+      else if (_Type == BitType::XOR) {
+        _LHS = new ValueBit(*VB._LHS);
+        _RHS = new ValueBit(*VB._RHS);
+      }
+      return *this;
+    }
+    ~ValueBit() {
+      if (_LHS)
+        delete _LHS;
+      if (_RHS)
+        delete _RHS;
+    }
+
+  public:
+    static ValueBit CreateOneBit() { return ValueBit(BitType::ONE); }
+    static ValueBit CreateZeroBit() { return ValueBit(BitType::ZERO); }
+    static ValueBit CreateRefBit(Value *Ref, uint64_t Offset) {
+      return ValueBit(BitType::REF, std::make_pair(Ref, Offset));
+    }
+    static ValueBit CreateXORBit(ValueBit &LHS, ValueBit &RHS) {
+      return ValueBit(BitType::XOR, LHS, RHS);
+    }
+    inline BitType getType() { return _Type; }
+    bool equals(ValueBit RHS) {
+      if (_Type != RHS.getType())
+        return false;
+      switch (_Type) {
+      case BitType::ONE:
+      case BitType::ZERO:
+        return true;
+      case BitType::REF:
+        return _BitRef == RHS._BitRef;
+      case BitType::XOR:
+        return (_LHS->equals(*RHS._LHS) && _RHS->equals(*RHS._RHS)) ||
+               (_LHS->equals(*RHS._RHS) && _RHS->equals(*RHS._LHS));
+      }
+      return false;
+    }
+
+    void print(raw_ostream &OS) {
+      switch (_Type) {
+      case BitType::ONE:
+        OS << "1";
+        break;
+      case BitType::ZERO:
+        OS << "0";
+        break;
+      case BitType::REF:
+        OS << _BitRef.first->getNameOrAsOperand() << "[" << _BitRef.second
----------------
zqb-all wrote:

`getNameOrAsOperand` causes a build error when building a release version

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


More information about the llvm-commits mailing list