From 31b00b4c72f89cf7e9e61733141838cf7819f2db Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:03:33 +1300 Subject: [PATCH 1/2] celledges: Use b_width_capped for left shifts `b_width_capped` already exists for preventing arithmetic overflow, limiting the value of `b_width` to 30. This just changes the left shifts to also use it. The caveat of incorrect results for extremely large values of `a_width` still applies, as does the improbability of that actually happening. This fixes #4844 (or at least, the floating point exception; the circuit still isn't valid but I think that's fine). --- kernel/celledges.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/celledges.cc b/kernel/celledges.cc index bad7124d9b1..68e55db02c7 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -253,13 +253,13 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) if (a_width == 1 && is_signed) { int skip = 1 << (k + 1); int base = skip -1; - if (i % skip != base && i - a_width + 2 < 1 << b_width) + if (i % skip != base && i - a_width + 2 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } else if (is_signed) { - if (i - a_width + 2 < 1 << b_width) + if (i - a_width + 2 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } else { - if (i - a_width + 1 < 1 << b_width) + if (i - a_width + 1 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } // right shifts From cf52cf300916d82eaee0194b29d9ae342c0a6d68 Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 31 Jan 2025 12:15:53 +1300 Subject: [PATCH 2/2] nowrshmsk: Check for stride==0 log2(0) returns -inf, which gives undefined behaviour when casting to an int. So catch the case when it's 0 just set the width to 0. --- frontends/ast/simplify.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b00cde28e2c..d35756d4ed3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2936,7 +2936,10 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin lsb_expr->children[stride_ix]->detectSignWidth(stride_width, stride_sign); max_width = std::max(i_width, stride_width); // Stride width calculated from actual stride value. - stride_width = std::ceil(std::log2(std::abs(stride))); + if (stride == 0) + stride_width = 0; + else + stride_width = std::ceil(std::log2(std::abs(stride))); if (i_width + stride_width > max_width) { // For (truncated) i*stride to be within the range of dst, the following must hold: