From 8c7f08dfc39e71b68a890f8593225c5e0675b9df Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Mon, 23 Feb 2026 17:35:15 +0000 Subject: [PATCH] Fix inlining of CFuncs with reloop locals (#7132) The recent V3InlineCFuncs only checks AstCFunc::varsp for locals, but V3Reloop used to insert them into AstCFunc::stmtsp resulting in multiple locals with the same name being inlined into the caller if the stars align. Fix Reloop. Such things will also go away with #6280. --- src/V3Reloop.cpp | 4 +-- test_regress/t/t_reloop_inlined.py | 21 +++++++++++++++ test_regress/t/t_reloop_inlined.v | 43 ++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_reloop_inlined.py create mode 100644 test_regress/t/t_reloop_inlined.v diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index caa9e5410..8870e2ab6 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -68,6 +68,7 @@ class ReloopVisitor final : public VNVisitor { const string newvarname{"__Vilp" + std::to_string(cfuncp->user1Inc() + 1)}; AstVar* const varp = new AstVar{fl, VVarType::STMTTEMP, newvarname, VFlagLogicPacked{}, 32}; + cfuncp->addVarsp(varp); return varp; } void mergeEnd() { @@ -105,8 +106,7 @@ class ReloopVisitor final : public VNVisitor { AstLoop* const loopp = new AstLoop{fl}; loopp->addStmtsp(new AstLoopTest{fl, loopp, condp}); initp->addNext(loopp); - itp->AstNode::addNext(initp); - bodyp->replaceWith(itp); + bodyp->replaceWith(initp); loopp->addStmtsp(bodyp); loopp->addStmtsp(incp); diff --git a/test_regress/t/t_reloop_inlined.py b/test_regress/t/t_reloop_inlined.py new file mode 100755 index 000000000..686612a8f --- /dev/null +++ b/test_regress/t/t_reloop_inlined.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=[ + "--binary", "--unroll-count", "1024", "--inline-cfuncs", "100000000", "--output-split-cfuncs", + "50", "--reloop-limit", "2" +]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_reloop_inlined.v b/test_regress/t/t_reloop_inlined.v new file mode 100644 index 000000000..2f838d88b --- /dev/null +++ b/test_regress/t/t_reloop_inlined.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +module t; + bit clk1 = 1'b0; + bit clk2 = 1'b0; + always #5 clk1 = ~clk1; + always #10 clk2 = ~clk2; + + int iarray [63:0]; + int oarray1 [63:0]; + int oarray2 [63:0]; + + initial begin + for (int i = 0; i < 64 ; i = i + 1) begin + iarray[i] = i; + end + + #100; + + for (int i = 0; i < 64; i = i + 1) begin + $display("%d %d %d", i, oarray1[i], oarray2[i]); + end + + $write("*-* All Finished *-*\n"); + $finish; + end + + always @(posedge clk1) begin + for (int i = 0; i < 64 ; i = i + 1) begin + oarray1[i] = iarray[i]; + end + end + always @(posedge clk2) begin + for (int i = 0; i < 64 ; i = i + 1) begin + oarray2[i] =iarray[i]; + end + end + +endmodule