Optimize combinational loops through sign extension (#6724)

This commit is contained in:
Geza Lore 2025-11-23 19:26:51 +00:00 committed by GitHub
parent 07056b11f5
commit 6ab8d56993
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 6 deletions

View File

@ -496,6 +496,41 @@ class TraceDriver final : public DfgVisitor {
}
}
void visit(DfgExtendS* vtxp) override {
DfgVertex* const srcp = vtxp->srcp();
const uint32_t sWidth = srcp->width();
// If the traced bits are wholly in the input
if (sWidth > m_msb) {
SET_RESULT(trace(srcp, m_msb, m_lsb));
return;
}
// If there is a single traced bit, wholly in the extension
if (m_lsb >= sWidth && m_msb == m_lsb) {
if (DfgVertex* const sp = trace(srcp, sWidth - 1, sWidth - 1)) SET_RESULT(sp);
return;
}
// The rest need a real ExtendS
if (!m_aggressive) return;
// If the traced bits are wholly in the extension
if (m_lsb >= sWidth) {
if (DfgVertex* const sp = trace(srcp, sWidth - 1, sWidth - 1)) {
DfgExtendS* const resp = make<DfgExtendS>(vtxp, m_msb - m_lsb + 1);
resp->srcp(sp);
SET_RESULT(resp);
}
return;
}
// The traced bits span both sides
if (DfgVertex* const sp = trace(srcp, sWidth - 1, m_lsb)) {
DfgExtendS* const resp = make<DfgExtendS>(vtxp, m_msb - m_lsb + 1);
resp->srcp(sp);
SET_RESULT(resp);
return;
}
}
void visit(DfgSel* vtxp) override {
const uint32_t lsb = vtxp->lsb();
SET_RESULT(trace(vtxp->srcp(), m_msb + lsb, m_lsb + lsb));
@ -834,6 +869,15 @@ class IndependentBits final : public DfgVisitor {
m.opSetRange(sWidth, vtxp->width() - sWidth, '0');
}
void visit(DfgExtendS* vtxp) override {
const DfgVertex* const srcp = vtxp->srcp();
const uint32_t sWidth = srcp->width();
V3Number& s = MASK(srcp);
V3Number& m = MASK(vtxp);
m.opSelInto(s, 0, sWidth);
m.opSetRange(sWidth, vtxp->width() - sWidth, s.bitIs0(sWidth - 1) ? '0' : '1');
}
void visit(DfgNot* vtxp) override { //
MASK(vtxp) = MASK(vtxp->srcp());
}

View File

@ -59,12 +59,24 @@ module t (
assign SEL[1] = SEL[0];
assign SEL[2] = SEL[1];
`signal(EXTEND, 8); // UNOPTFLAT
assign EXTEND[0] = rand_a[3];
assign EXTEND[3:1] = 3'(EXTEND[0]);
assign EXTEND[4] = EXTEND[1];
assign EXTEND[6:5] = EXTEND[2:1];
assign EXTEND[7] = EXTEND[3];
`signal(ZX, 8); // UNOPTFLAT
assign ZX[0] = rand_a[3];
assign ZX[3:1] = 3'(ZX[0]);
assign ZX[4] = ZX[1];
assign ZX[6:5] = ZX[2:1];
assign ZX[7] = ZX[3];
`signal(SX_0, 5); // UNOPTFLAT
assign SX_0[0] = rand_a[3];
assign SX_0[3:1] = 3'(signed'(SX_0[0]));
`signal(SX_1, 5); // UNOPTFLAT
assign SX_1 = 5'(signed'({rand_a[0], SX_1[1]}));
`signal(SX_2, 5); // UNOPTFLAT
assign SX_2 = 5'(signed'({rand_a[0], SX_2[2]}));
`signal(SX_3, 5); // UNOPTFLAT
assign SX_3 = 5'(signed'({rand_a[0], SX_3[3:2]}));
`signal(SX_4, 5); // UNOPTFLAT
assign SX_4 = 5'(signed'({rand_a[0], SX_4[4:3]}));
`signal(NOT, 3); // UNOPTFLAT
assign NOT = ~(rand_a[2:0] ^ 3'(NOT[2:1]));