Fix hang in assertion optimization (#7707 repair)

This commit is contained in:
Geza Lore 2026-06-14 13:13:47 +01:00
parent c6a5255ea0
commit b973b1df5a
3 changed files with 38 additions and 16 deletions

View File

@ -659,6 +659,34 @@ class AssertVisitor final : public VNVisitor {
iterateChildren(nodep);
}
if (nodep->user2()) {
// Combine consecutive assertOn checks if possible
if (AstIf* const backp = VN_CAST(nodep->backp(), If)) {
if (backp->nextp() == nodep //
&& backp->user2() //
&& backp->condp()->sameTree(nodep->condp())) {
++m_statAssertOnCombined;
backp->addThensp(nodep->thensp()->unlinkFrBackWithNext());
nodep->unlinkFrBack();
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return;
}
}
// Combine nested assertOn checks if possible
if (nodep->thensp() && !nodep->thensp()->nextp() && isEmptyStmt(nodep->elsesp())) {
AstIf* const checkp = VN_CAST(nodep->thensp(), If);
if (checkp //
&& checkp->user2() //
&& checkp->condp()->sameTree(nodep->condp())) {
++m_statAssertOnCombined;
nodep->addThensp(checkp->thensp()->unlinkFrBackWithNext());
VL_DO_DANGLING(checkp->unlinkFrBack(), checkp);
return;
}
}
return;
}
// Swap assertOn check with single statement 'if' statement to bubble up for combining
// Note we can't just swap the conditions as they two Ifs have different flags,
// so swapping the Ifs themeselves then swapping back the bodies.
@ -684,20 +712,6 @@ class AssertVisitor final : public VNVisitor {
}
}
}
// Combine consecutive assertOn checks if possible
if (nodep->user2()) {
if (AstIf* const backp = VN_CAST(nodep->backp(), If)) {
if (backp->nextp() == nodep //
&& backp->user2() //
&& backp->condp()->sameTree(nodep->condp())) {
++m_statAssertOnCombined;
backp->addThensp(nodep->thensp()->unlinkFrBackWithNext());
nodep->unlinkFrBack();
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
}
}
}
//========== Case assertions

View File

@ -15,7 +15,7 @@ test.compile(verilator_flags2=['--binary', '--stats'])
test.execute(check_finished=True)
test.file_grep(test.stats, r'Assertions, assertOn checks combined\s+(\d+)', 2)
test.file_grep(test.stats, r'Assertions, assertOn checks hoisted\s+(\d+)', 11)
test.file_grep(test.stats, r'Assertions, assertOn checks combined\s+(\d+)', 3)
test.file_grep(test.stats, r'Assertions, assertOn checks hoisted\s+(\d+)', 15)
test.passes()

View File

@ -58,4 +58,12 @@ module t;
end
end
// Should combine the 2 nested assertOn checks after hoisting
always @(posedge clk) begin
if (assertEnable) begin
// This is an 'assert' with another 'assert' in the fail branch
assert(cntB - 100 == cntA); else assert(cntB == cntA + 100);
end
end
endmodule