Fix integer overflow in V3Unroll (#3451)

This commit is contained in:
Geza Lore 2022-08-03 09:41:30 +01:00
parent bd211c87aa
commit f9f66d787e

View File

@ -50,6 +50,7 @@ private:
bool m_varModeReplace; // Replacing varrefs bool m_varModeReplace; // Replacing varrefs
bool m_varAssignHit; // Assign var hit bool m_varAssignHit; // Assign var hit
bool m_generate; // Expand single generate For loop bool m_generate; // Expand single generate For loop
int m_unrollLimit; // Unrolling limit
string m_beginName; // What name to give begin iterations string m_beginName; // What name to give begin iterations
VDouble0 m_statLoops; // Statistic tracking VDouble0 m_statLoops; // Statistic tracking
VDouble0 m_statIters; // Statistic tracking VDouble0 m_statIters; // Statistic tracking
@ -67,10 +68,6 @@ private:
return false; return false;
} }
int unrollCount() const {
return m_generate ? v3Global.opt.unrollCount() * 16 : v3Global.opt.unrollCount();
}
bool bodySizeOverRecurse(AstNode* nodep, int& bodySize, int bodyLimit) { bool bodySizeOverRecurse(AstNode* nodep, int& bodySize, int bodyLimit) {
if (!nodep) return false; if (!nodep) return false;
bodySize++; bodySize++;
@ -163,7 +160,7 @@ private:
// Check whether to we actually want to try and unroll. // Check whether to we actually want to try and unroll.
int loops; int loops;
if (!countLoops(initAssp, condp, incp, unrollCount(), loops)) { if (!countLoops(initAssp, condp, incp, m_unrollLimit, loops)) {
return cantUnroll(nodep, "Unable to simulate loop"); return cantUnroll(nodep, "Unable to simulate loop");
} }
@ -336,11 +333,11 @@ private:
} }
++m_statIters; ++m_statIters;
if (++times > unrollCount() * 3) { if (++times / 3 > m_unrollLimit) {
nodep->v3error( nodep->v3error(
"Loop unrolling took too long;" "Loop unrolling took too long;"
" probably this is an infinite loop, or set --unroll-count above " " probably this is an infinite loop, or set --unroll-count above "
<< unrollCount()); << m_unrollLimit);
break; break;
} }
@ -485,6 +482,12 @@ public:
m_varModeReplace = false; m_varModeReplace = false;
m_varAssignHit = false; m_varAssignHit = false;
m_generate = generate; m_generate = generate;
m_unrollLimit = v3Global.opt.unrollCount();
if (generate) {
m_unrollLimit = std::numeric_limits<int>::max() / 16 > m_unrollLimit
? m_unrollLimit * 16
: std::numeric_limits<int>::max();
}
m_beginName = beginName; m_beginName = beginName;
} }
void process(AstNode* nodep, bool generate, const string& beginName) { void process(AstNode* nodep, bool generate, const string& beginName) {