Internals: Do not generate redundant masking on word selects

newAstWordSelClone returns a clean word and these And mask out exactly
the bits that are zero after the shift.
This commit is contained in:
Geza Lore 2026-06-19 14:16:58 +01:00
parent 9670dabcfe
commit 2f28beadf5
1 changed files with 10 additions and 22 deletions

View File

@ -206,31 +206,19 @@ class ExpandVisitor final : public VNVisitor {
static AstNodeExpr* newWordGrabShift(FileLine* fl, int word, AstNodeExpr* lhsp, int shift) { static AstNodeExpr* newWordGrabShift(FileLine* fl, int word, AstNodeExpr* lhsp, int shift) {
// Extract the expression to grab the value for the specified word, if it's the shift // Extract the expression to grab the value for the specified word, if it's the shift
// of shift bits from lhsp // of shift bits from lhsp
AstNodeExpr* newp;
// Negative word numbers requested for lhs when it's "before" what we want. // Negative word numbers requested for lhs when it's "before" what we want.
// We get a 0 then. // We get a 0 then.
const int othword = word - shift / VL_EDATASIZE; const int othword = word - shift / VL_EDATASIZE;
AstNodeExpr* const llowp = newAstWordSelClone(lhsp, othword); AstNodeExpr* const lop = newAstWordSelClone(lhsp, othword);
if (const int loffset = VL_BITBIT_E(shift)) { const uint32_t loShift = VL_BITBIT_E(shift);
AstNodeExpr* const lhip = newAstWordSelClone(lhsp, othword - 1); if (!loShift) return lop;
const int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword AstNodeExpr* const hip = newAstWordSelClone(lhsp, othword - 1);
newp = new AstOr{ const uint32_t hiShift = VL_EDATASIZE - loShift; // Complement offset
fl, AstNodeExpr* const newp
new AstAnd{fl, new AstConst{fl, AstConst::SizedEData{}, VL_MASK_E(loffset)}, = new AstOr{fl, //
new AstShiftR{fl, lhip, new AstShiftR{fl, hip, new AstConst{fl, hiShift}, VL_EDATASIZE},
new AstConst{fl, static_cast<uint32_t>(nbitsonright)}, new AstShiftL{fl, lop, new AstConst{fl, loShift}, VL_EDATASIZE}};
VL_EDATASIZE}}, return V3Const::constifyEditCpp(newp);
new AstAnd{fl,
new AstConst{fl, AstConst::SizedEData{},
static_cast<uint32_t>(~VL_MASK_E(loffset))},
new AstShiftL{fl, llowp,
new AstConst{fl, static_cast<uint32_t>(loffset)},
VL_EDATASIZE}}};
newp = V3Const::constifyEditCpp(newp);
} else {
newp = llowp;
}
return newp;
} }
// Return expression indexing the word that contains 'lsbp' + the given word offset // Return expression indexing the word that contains 'lsbp' + the given word offset