[llvm] [LoopIdiomRecognizer] Implement CRC recognition (PR #79295)
Joe Faulls via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 24 09:06:30 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
----------------
joe-img wrote:
I've rebased & pushed, but don't see this issue. Can you recreate it now?
https://github.com/llvm/llvm-project/pull/79295
More information about the llvm-commits
mailing list