diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index af98ca8da..bb0fe31b8 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -1072,7 +1072,7 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgArraySel* vtxp) override { if (DfgConst* const idxp = vtxp->bitp()->cast()) { if (DfgVarArray* const varp = vtxp->fromp()->cast()) { - const uint32_t idx = idxp->toU32(); + const size_t idx = idxp->toSizeT(); if (DfgVertex* const driverp = varp->driverAt(idx)) { APPLYING(INLINE_ARRAYSEL) { vtxp->replaceWith(driverp); @@ -1368,7 +1368,7 @@ class V3DfgPeephole final : public DfgVisitor { return; } } - if (vtxp->dtypep() == m_bitDType && rConstp->toU32() == 1) { + if (vtxp->dtypep() == m_bitDType && rConstp->hasValue(1)) { APPLYING(REPLACE_SUB_WITH_NOT) { DfgNot* const replacementp = new DfgNot{m_dfg, vtxp->fileline(), m_bitDType}; replacementp->srcp(lhsp); @@ -1454,7 +1454,7 @@ class V3DfgPeephole final : public DfgVisitor { // 'cond ? a + 1 : a' -> 'a + cond' if (DfgAdd* const thenAddp = thenp->cast()) { if (DfgConst* const constp = thenAddp->lhsp()->cast()) { - if (constp->toI32() == 1) { + if (constp->hasValue(1)) { if (thenAddp->rhsp() == elsep) { APPLYING(REPLACE_COND_INC) { DfgConcat* const extp = new DfgConcat{m_dfg, flp, vtxp->dtypep()}; @@ -1474,7 +1474,7 @@ class V3DfgPeephole final : public DfgVisitor { // 'cond ? a - 1 : a' -> 'a - cond' if (DfgSub* const thenSubp = thenp->cast()) { if (DfgConst* const constp = thenSubp->rhsp()->cast()) { - if (constp->toI32() == 1) { + if (constp->hasValue(1)) { if (thenSubp->lhsp() == elsep) { APPLYING(REPLACE_COND_DEC) { DfgConcat* const extp = new DfgConcat{m_dfg, flp, vtxp->dtypep()}; diff --git a/src/V3DfgVertices.h b/src/V3DfgVertices.h index 8b003ace0..5c3700308 100644 --- a/src/V3DfgVertices.h +++ b/src/V3DfgVertices.h @@ -108,12 +108,21 @@ public: V3Number& num() { return m_num; } const V3Number& num() const { return m_num; } - uint32_t toU32() const { return num().toUInt(); } - int32_t toI32() const { return num().toSInt(); } + size_t toSizeT() const { + if VL_CONSTEXPR_CXX17 (sizeof(size_t) > sizeof(uint32_t)) { + return static_cast(num().toUQuad()); + } + return static_cast(num().toUInt()); + } bool isZero() const { return num().isEqZero(); } bool isOnes() const { return num().isEqAllOnes(width()); } + // Does this DfgConst have the given value? Note this is not easy to answer if wider than 32. + bool hasValue(uint32_t value) const { + return !num().isFourState() && num().edataWord(0) == value && num().mostSetBitP1() <= 32; + } + std::pair sourceEdges() override { return {nullptr, 0}; } std::pair sourceEdges() const override { return {nullptr, 0}; } const string srcName(size_t) const override { // LCOV_EXCL_START diff --git a/test_regress/t/t_dfg_peephole.v b/test_regress/t/t_dfg_peephole.v index 675fd9194..e3e3862bd 100644 --- a/test_regress/t/t_dfg_peephole.v +++ b/test_regress/t/t_dfg_peephole.v @@ -175,6 +175,8 @@ module t ( `signal(REMOVE_XOR_WITH_ONES, -64'd1 ^ rand_a); `signal(REPLACE_COND_DEC, randbit_a ? rand_b - 64'b1 : rand_b); `signal(REPLACE_COND_INC, randbit_a ? rand_b + 64'b1 : rand_b); + `signal(NO_REPLACE_COND_DEC, randbit_a ? rand_b - 64'hf000000000000000 : rand_b); + `signal(NO_REPLACE_COND_INC, randbit_a ? rand_b + 64'hf000000000000000 : rand_b); `signal(RIGHT_LEANING_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b)); `signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b});