@@ -119,13 +119,25 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
119
119
m_constp = constp;
120
120
m_msb = constp->widthMin () - 1 ;
121
121
}
122
+ // updateBitRange(), limitBitRangeToLsb(), and polarity() must be called during ascending
123
+ // back to the root.
124
+ void updateBitRange (int newLsb, int newMsb) {
125
+ if ((m_lsb <= m_msb && newLsb > newMsb) || (m_lsb > m_msb && m_lsb < newLsb)) {
126
+ // When the new bit range is out of m_refp, clear polarity because nodes below is
127
+ // shifted out to zero.
128
+ // This kind of clear may happen several times. e.g. (!(1'b1 >> 1)) >> 1
129
+ polarity (true );
130
+ }
131
+ m_lsb = newLsb;
132
+ m_msb = newMsb;
133
+ }
122
134
void updateBitRange (const AstCCast* castp) {
123
- m_msb = std::min (m_msb, m_lsb + castp->width () - 1 );
135
+ updateBitRange (m_lsb, std::min (m_msb, m_lsb + castp->width () - 1 ) );
124
136
}
125
137
void updateBitRange (const AstShiftR* shiftp) {
126
- m_lsb += VN_AS (shiftp->rhsp (), Const)->toUInt ();
138
+ updateBitRange ( m_lsb + VN_AS (shiftp->rhsp (), Const)->toUInt (), m_msb );
127
139
}
128
- void limitBitRangeToLsb () { m_msb = std::min (m_msb, m_lsb); }
140
+ void limitBitRangeToLsb () { updateBitRange (m_lsb, std::min (m_msb, m_lsb) ); }
129
141
int wordIdx () const { return m_wordIdx; }
130
142
void wordIdx (int i) { m_wordIdx = i; }
131
143
bool polarity () const { return m_polarity; }
@@ -467,6 +479,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
467
479
// Don't restore m_polarity for Xor as it counts parity of the entire tree
468
480
if (!isXorTree ()) m_polarity = !m_polarity;
469
481
if (m_leafp && castp) m_leafp->updateBitRange (castp);
482
+ if (m_leafp) m_leafp->polarity (!m_leafp->polarity ());
470
483
}
471
484
void visit (AstWordSel* nodep) override {
472
485
CONST_BITOP_RETURN_IF (!m_leafp, nodep);
@@ -479,7 +492,6 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
479
492
void visit (AstVarRef* nodep) override {
480
493
CONST_BITOP_RETURN_IF (!m_leafp, nodep);
481
494
m_leafp->setLeaf (nodep);
482
- m_leafp->polarity (m_polarity);
483
495
}
484
496
void visit (AstConst* nodep) override {
485
497
CONST_BITOP_RETURN_IF (!m_leafp, nodep);
0 commit comments