aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-06-09 16:14:16 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-06-09 17:42:30 +0200
commit12b3a9765dafeb8766265c82dee9e06435343e66 (patch)
treee5c0ea0f96e28a9e3537f21f395323491dc56f6e /passes/opt
parent55e8f5061af57bf25bd9e30528de8196c6eabe9e (diff)
downloadyosys-12b3a9765dafeb8766265c82dee9e06435343e66.tar.gz
yosys-12b3a9765dafeb8766265c82dee9e06435343e66.tar.bz2
yosys-12b3a9765dafeb8766265c82dee9e06435343e66.zip
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.
Diffstat (limited to 'passes/opt')
-rw-r--r--passes/opt/opt_expr.cc8
1 files 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<RTLIL::SigBit> 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);