From e5f49baaac5817bff56f65cc59c261b71fffc351 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 25 Aug 2014 20:27:22 +0100 Subject: [PATCH] Fix for GitHub issue #37 - bug in expression width pruning. If an expression contains a division, remainder, or right shift operation, set the expression min_width to UINT_MAX to flag that the expression width cannot be pruned. Using UINT_MAX ensures that the min_width won't change as we continue to elaborate the expression. --- elab_expr.cc | 4 ++-- netmisc.cc | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 11e7695ba..eeab59de9 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -310,7 +310,7 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode) case '%': case '/': - min_width_ = max(min_width_, expr_width_); + min_width_ = UINT_MAX; // disable width pruning break; case 'l': // << Should be handled by PEBShift @@ -816,7 +816,7 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode) if (op_ == 'l') min_width_ = left_->min_width(); else - min_width_ = expr_width_; + min_width_ = UINT_MAX; // disable width pruning return fix_width_(mode); } diff --git a/netmisc.cc b/netmisc.cc index ee69e8e6e..585388f06 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -20,6 +20,7 @@ # include "config.h" # include +# include # include "netlist.h" # include "netvector.h" # include "netmisc.h" @@ -764,12 +765,13 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, // If we can get the same result using a smaller expression // width, do so. - if ((context_width > 0) && (pe->expr_type() != IVL_VT_REAL) - && (expr_width > pos_context_width)) { - expr_width = max(pe->min_width(), pos_context_width); + unsigned min_width = pe->min_width(); + if ((min_width != UINT_MAX) && (pe->expr_type() != IVL_VT_REAL) + && (pos_context_width > 0) && (expr_width > pos_context_width)) { + expr_width = max(min_width, pos_context_width); if (debug_elaborate) { - cerr << pe->get_fileline() << ": " + cerr << pe->get_fileline() << ": : " << "pruned to width=" << expr_width << endl; } }