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 { void visit(DfgArraySel* vtxp) override {
if (DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>()) { if (DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>()) {
if (DfgVarArray* const varp = vtxp->fromp()->cast<DfgVarArray>()) { 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)) { if (DfgVertex* const driverp = varp->driverAt(idx)) {
APPLYING(INLINE_ARRAYSEL) { APPLYING(INLINE_ARRAYSEL) {
vtxp->replaceWith(driverp); vtxp->replaceWith(driverp);
@ -1368,7 +1368,7 @@ class V3DfgPeephole final : public DfgVisitor {
return; return;
} }
} }
if (vtxp->dtypep() == m_bitDType && rConstp->toU32() == 1) { if (vtxp->dtypep() == m_bitDType && rConstp->hasValue(1)) {
APPLYING(REPLACE_SUB_WITH_NOT) { APPLYING(REPLACE_SUB_WITH_NOT) {
DfgNot* const replacementp = new DfgNot{m_dfg, vtxp->fileline(), m_bitDType}; DfgNot* const replacementp = new DfgNot{m_dfg, vtxp->fileline(), m_bitDType};
replacementp->srcp(lhsp); replacementp->srcp(lhsp);
@ -1454,7 +1454,7 @@ class V3DfgPeephole final : public DfgVisitor {
// 'cond ? a + 1 : a' -> 'a + cond' // 'cond ? a + 1 : a' -> 'a + cond'
if (DfgAdd* const thenAddp = thenp->cast<DfgAdd>()) { if (DfgAdd* const thenAddp = thenp->cast<DfgAdd>()) {
if (DfgConst* const constp = thenAddp->lhsp()->cast<DfgConst>()) { if (DfgConst* const constp = thenAddp->lhsp()->cast<DfgConst>()) {
if (constp->toI32() == 1) { if (constp->hasValue(1)) {
if (thenAddp->rhsp() == elsep) { if (thenAddp->rhsp() == elsep) {
APPLYING(REPLACE_COND_INC) { APPLYING(REPLACE_COND_INC) {
DfgConcat* const extp = new DfgConcat{m_dfg, flp, vtxp->dtypep()}; 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' // 'cond ? a - 1 : a' -> 'a - cond'
if (DfgSub* const thenSubp = thenp->cast<DfgSub>()) { if (DfgSub* const thenSubp = thenp->cast<DfgSub>()) {
if (DfgConst* const constp = thenSubp->rhsp()->cast<DfgConst>()) { if (DfgConst* const constp = thenSubp->rhsp()->cast<DfgConst>()) {
if (constp->toI32() == 1) { if (constp->hasValue(1)) {
if (thenSubp->lhsp() == elsep) { if (thenSubp->lhsp() == elsep) {
APPLYING(REPLACE_COND_DEC) { APPLYING(REPLACE_COND_DEC) {
DfgConcat* const extp = new DfgConcat{m_dfg, flp, vtxp->dtypep()}; DfgConcat* const extp = new DfgConcat{m_dfg, flp, vtxp->dtypep()};

View File

@ -108,12 +108,21 @@ public:
V3Number& num() { return m_num; } V3Number& num() { return m_num; }
const V3Number& num() const { return m_num; } const V3Number& num() const { return m_num; }
uint32_t toU32() const { return num().toUInt(); } size_t toSizeT() const {
int32_t toI32() const { return num().toSInt(); } 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 isZero() const { return num().isEqZero(); }
bool isOnes() const { return num().isEqAllOnes(width()); } 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<DfgEdge*, size_t> sourceEdges() override { return {nullptr, 0}; }
std::pair<const DfgEdge*, size_t> sourceEdges() const 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 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(REMOVE_XOR_WITH_ONES, -64'd1 ^ rand_a);
`signal(REPLACE_COND_DEC, randbit_a ? rand_b - 64'b1 : rand_b); `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(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_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b));
`signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b}); `signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b});