From 5278f420255b34170113d8d7a100af3b068c86b7 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sat, 6 Dec 2025 15:31:27 +0000 Subject: [PATCH] Fix Dfg assertion on out of bounds selects --- src/V3DfgSynthesize.cpp | 12 +++++++++--- test_regress/t/t_dfg_oob_sel_rvalue.py | 20 ++++++++++++++++++++ test_regress/t/t_dfg_oob_sel_rvalue.v | 21 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_dfg_oob_sel_rvalue.py create mode 100644 test_regress/t/t_dfg_oob_sel_rvalue.v diff --git a/src/V3DfgSynthesize.cpp b/src/V3DfgSynthesize.cpp index b5009fd88..a96174eaf 100644 --- a/src/V3DfgSynthesize.cpp +++ b/src/V3DfgSynthesize.cpp @@ -414,11 +414,17 @@ class AstToDfgConverter final : public VNVisitor { if (const AstConst* const constp = VN_CAST(nodep->lsbp(), Const)) { const uint32_t lsb = constp->toUInt(); const uint32_t msb = lsb + nodep->widthConst() - 1; + DfgVertex* const fromp = nodep->fromp()->user2u().to(); + // Unfortunately we can still have out of bounds selects due to how + // indices are truncated for speed reasons in V3Width/V3Unknown. + if (msb >= fromp->size()) { + m_foundUnhandled = true; + ++m_ctx.m_conv.nonRepOOBSel; + return; + } DfgSel* const selp = make(flp, *dtypep); - selp->fromp(nodep->fromp()->user2u().to()); + selp->fromp(fromp); selp->lsb(lsb); - UASSERT_OBJ(msb < selp->fromp()->size(), nodep, - "OOB AstSel should have been fixed up by earlier passes"); vtxp = selp; } else { iterate(nodep->lsbp()); diff --git a/test_regress/t/t_dfg_oob_sel_rvalue.py b/test_regress/t/t_dfg_oob_sel_rvalue.py new file mode 100755 index 000000000..ed0e2a16e --- /dev/null +++ b/test_regress/t/t_dfg_oob_sel_rvalue.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=["--stats"]) + +test.file_grep( + test.stats, + r'Optimizations, DFG scoped Synthesis, conv / non-representable \(oobsel\)\s+(\d+)', 1) + +test.passes() diff --git a/test_regress/t/t_dfg_oob_sel_rvalue.v b/test_regress/t/t_dfg_oob_sel_rvalue.v new file mode 100644 index 000000000..0413788b4 --- /dev/null +++ b/test_regress/t/t_dfg_oob_sel_rvalue.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + + +module t( + input logic [0:0][2:0] i, + output logic o +); + + always_comb begin + o = 1'b0; + // verilator unroll_full + for (int n = 0 ; n < 3; ++n) begin + o = o | i[n] == 3'd0; // Intentionally out of bounds + end + end + +endmodule