diff --git a/src/V3MergeCond.cpp b/src/V3MergeCond.cpp index 538bbbb28..376daa47b 100644 --- a/src/V3MergeCond.cpp +++ b/src/V3MergeCond.cpp @@ -245,8 +245,8 @@ class CodeMotionAnalysisVisitor final : public VNVisitorConst { } void analyzeNode(AstNode* nodep) { - // If an impure node under a statement, mark that statement as impure - if (m_propsp && !nodep->isPure()) m_propsp->m_isFence = true; + // If impure, or branch, mark statement as fence + if (m_propsp && (!nodep->isPure() || nodep->isBrancher())) m_propsp->m_isFence = true; // Analyze children iterateChildrenConst(nodep); } diff --git a/test_regress/t/t_merge_cond_motion_branch.py b/test_regress/t/t_merge_cond_motion_branch.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_merge_cond_motion_branch.py @@ -0,0 +1,18 @@ +#!/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('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_merge_cond_motion_branch.v b/test_regress/t/t_merge_cond_motion_branch.v new file mode 100644 index 000000000..73a538df0 --- /dev/null +++ b/test_regress/t/t_merge_cond_motion_branch.v @@ -0,0 +1,23 @@ +// 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 + +// Based on ivtest's pr540.v by Steve Williams. +module t; + bit fail = 0; + bit abort = 0; + + initial begin + abort = 1; // Set here so it's non-constant, otherwise ifs gets folded + begin: block + if (abort) disable block; + fail = 1; // Don't try to move this in order to merge the 2 ifs + if (abort) $display("unreachable"); + end + if (fail) $error("block disable FAILED"); + $write("*-* All Finished *-*\n"); + $finish(0); + end +endmodule