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