From 12b3a9765dafeb8766265c82dee9e06435343e66 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 9 Jun 2021 16:14:16 +0200 Subject: [PATCH] opt_expr: Optimize div/mod by const 1. Turns out the code for div by a power of 2 is already almost capable of optimizing this to a shift-by-0 or and-with-0, which will be further folded into nothingness; let's beef it up to handle div by 1 as well. Fixes #2820. --- passes/opt/opt_expr.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 84f07c8a9..0230a5c40 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1648,7 +1648,7 @@ skip_identity: goto next_cell; } - for (int i = 1; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) + for (int i = 0; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) if (b_val == (1 << i)) { if (cell->type.in(ID($div), ID($divfloor))) @@ -1672,7 +1672,7 @@ skip_identity: // Truncating division is the same as flooring division, except when // the result is negative and there is a remainder - then trunc = floor + 1 - if (is_truncating && a_signed) { + if (is_truncating && a_signed && i != 0) { Wire *flooring = module->addWire(NEW_ID, sig_y.size()); cell->setPort(ID::Y, flooring); @@ -1698,7 +1698,7 @@ skip_identity: std::vector new_b = RTLIL::SigSpec(State::S1, i); - if (b_signed) + if (b_signed || i == 0) new_b.push_back(State::S0); cell->type = ID($and); @@ -1707,7 +1707,7 @@ skip_identity: // truncating modulo has the same masked bits as flooring modulo, but // the sign bits are those of A (except when R=0) - if (is_truncating && a_signed) { + if (is_truncating && a_signed && i != 0) { Wire *flooring = module->addWire(NEW_ID, sig_y.size()); cell->setPort(ID::Y, flooring); SigSpec truncating = SigSpec(flooring).extract(0, i); -- 2.30.2