From 1cfc7de87d87edb4b0ffd97212d552127acd085c Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Thu, 15 Jan 2026 11:30:18 +0100 Subject: [PATCH] Create lhsp of assignment by copying whole expression Signed-off-by: Ryszard Rozak --- src/V3Force.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/V3Force.cpp b/src/V3Force.cpp index c827ed4fa..e82444dcc 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -490,6 +490,9 @@ public: }; class ForceReplaceVisitor final : public VNVisitor { + // NODE STATE + // AstNodeExpr::user1 -> bool. Don't visit + // STATE const ForceState& m_state; AstNodeStmt* m_stmtp = nullptr; @@ -532,6 +535,7 @@ class ForceReplaceVisitor final : public VNVisitor { } void visit(AstSenItem* nodep) override { iterateLogic(nodep); } void visit(AstArraySel* nodep) override { + if (nodep->user1()) return; m_selIndices.push_back(nodep->bitp()); iterateChildren(nodep); UASSERT_OBJ(m_selIndices.size(), nodep, "Underflow"); @@ -561,11 +565,22 @@ class ForceReplaceVisitor final : public VNVisitor { if (nodep->dtypep()->skipRefp()->isIntegralOrPacked()) { rhsp = fcp->forcedUpdate(nodep->varScopep(), {}); } else { + AstNodeExpr* wholeExprp = nodep; + while (VN_IS(wholeExprp->backp(), NodeExpr)) { + wholeExprp = VN_AS(wholeExprp->backp(), NodeExpr); + } + if (nodep != wholeExprp) { + // nodep is a part of a bigger expression + AstNodeExpr* const copiedWholeExprp = wholeExprp->cloneTreePure(false); + copiedWholeExprp->user1(true); + wholeExprp->replaceWith(copiedWholeExprp); + nodep->replaceWith(lhsp); + pushDeletep(nodep); + lhsp = wholeExprp; + } std::vector reversedIndices(m_selIndices.size()); std::reverse_copy(m_selIndices.begin(), m_selIndices.end(), reversedIndices.begin()); - lhsp = ForceState::ForceComponentsVarScope::applySelects( - lhsp, reversedIndices); rhsp = fcp->forcedUpdate(nodep->varScopep(), reversedIndices); } m_stmtp->addNextHere(new AstAssign{flp, lhsp, rhsp}); @@ -596,6 +611,10 @@ class ForceReplaceVisitor final : public VNVisitor { break; } } + void visit(AstNodeExpr* nodep) override { + if (nodep->user1()) return; + iterateChildren(nodep); + } void visit(AstNode* nodep) override { iterateChildren(nodep); } public: