Fix for pr3582052.

The code that calculated the canonical index for a multi-dimensional
array access did not correctly estimate the index expression width
in the case that the first index value was a constant zero. This
patch fixes the problem, and, in passing, also makes the expression
calculation more efficient if any of the indices are constant zeroes.
This commit is contained in:
Martin Whitaker 2012-11-01 19:34:38 +00:00 committed by Stephen Williams
parent bad8ed39c1
commit 78128dd95d
1 changed files with 10 additions and 1 deletions

View File

@ -572,7 +572,7 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
int64_t use_stride = stride[idx]; int64_t use_stride = stride[idx];
// Account for that we are doing arithmatic and should // Account for that we are doing arithmetic and should
// have a proper width to make sure there are no // have a proper width to make sure there are no
// losses. So calculate a min_wid width. // losses. So calculate a min_wid width.
unsigned tmp_wid; unsigned tmp_wid;
@ -595,6 +595,10 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
int64_t val = tmp_const->value().as_long(); int64_t val = tmp_const->value().as_long();
val -= use_base; val -= use_base;
val *= use_stride; val *= use_stride;
// Very special case: the index is zero, so we can
// skip this iteration
if (val == 0)
continue;
tmp_scaled = new NetEConst(verinum(val)); tmp_scaled = new NetEConst(verinum(val));
} else { } else {
@ -613,6 +617,11 @@ NetExpr* normalize_variable_unpacked(const NetNet*net, list<NetExpr*>&indices)
} }
} }
// If we don't have an expression at this point, all the indices were
// constant zero. But this variant of normalize_variable_unpacked()
// is only used when at least one index is not a constant.
ivl_assert(*net, canonical_expr);
return canonical_expr; return canonical_expr;
} }