diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 4acd229cd96..76e4f598e7b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -299,16 +299,15 @@ RTLIL::Const::~Const() { check(false); } -bool RTLIL::Const::operator <(const RTLIL::Const &other) const +bool RTLIL::Const::operator<(const RTLIL::Const &other) const { - if (is_str() != other.is_str()) - return decode_string() < other.decode_string(); - - if (get_if_str()) + if (is_str() && other.is_str()) return str_ < other.str_; - bitvectype& bv = get_bits(); - auto other_bv = other.get_bits(); + // If either operand isn't a string, we have to construct a copy + // to bitvectorize without unpacking either operand + bitvectype &bv = is_str() ? Const(*this).bits() : get_bits(); + bitvectype &other_bv = other.is_str() ? Const(other).bits() : other.get_bits(); if (bv.size() != other_bv.size()) return bv.size() < other_bv.size(); @@ -321,13 +320,13 @@ bool RTLIL::Const::operator <(const RTLIL::Const &other) const bool RTLIL::Const::operator ==(const RTLIL::Const &other) const { - if (is_str() != other.is_str()) - return decode_string() == other.decode_string(); - - if (get_if_str()) + if (is_str() && other.is_str()) return get_str() == other.get_str(); - return get_bits() == other.get_bits(); + bitvectype &bv = is_str() ? Const(*this).bits() : get_bits(); + bitvectype &other_bv = other.is_str() ? Const(other).bits() : other.get_bits(); + + return bv == other_bv; } bool RTLIL::Const::operator !=(const RTLIL::Const &other) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9308b423259..de5b1798e2e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -802,8 +802,10 @@ struct RTLIL::Const unsigned int h = mkhash_init; if(is_str()) { - for (auto c : get_str()) - h = mkhash(h, c); + // Copy to avoid unpacking `this` + Const c = Const(*this); + for (auto b : c.bits()) + h = mkhash(h, b); } else { for (auto b : get_bits()) h = mkhash(h, b);