DFG: Fix attempted evaluation of constants wider than 32 bits

Fixes #3718
This commit is contained in:
Geza Lore 2022-10-28 17:00:32 +01:00
parent 99791ac8b3
commit 0675510eb9
3 changed files with 17 additions and 6 deletions

View File

@ -1072,7 +1072,7 @@ class V3DfgPeephole final : public DfgVisitor {
void visit(DfgArraySel* vtxp) override {
if (DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>()) {
if (DfgVarArray* const varp = vtxp->fromp()->cast<DfgVarArray>()) {
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<DfgAdd>()) {
if (DfgConst* const constp = thenAddp->lhsp()->cast<DfgConst>()) {
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<DfgSub>()) {
if (DfgConst* const constp = thenSubp->rhsp()->cast<DfgConst>()) {
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()};

View File

@ -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<size_t>(num().toUQuad());
}
return static_cast<size_t>(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<DfgEdge*, size_t> sourceEdges() override { return {nullptr, 0}; }
std::pair<const DfgEdge*, size_t> sourceEdges() const override { return {nullptr, 0}; }
const string srcName(size_t) const override { // LCOV_EXCL_START

View File

@ -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});