mirror of https://github.com/YosysHQ/yosys.git
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.
This commit is contained in:
parent
55e8f5061a
commit
12b3a9765d
|
@ -1648,7 +1648,7 @@ skip_identity:
|
||||||
goto next_cell;
|
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 (b_val == (1 << i))
|
||||||
{
|
{
|
||||||
if (cell->type.in(ID($div), ID($divfloor)))
|
if (cell->type.in(ID($div), ID($divfloor)))
|
||||||
|
@ -1672,7 +1672,7 @@ skip_identity:
|
||||||
|
|
||||||
// Truncating division is the same as flooring division, except when
|
// Truncating division is the same as flooring division, except when
|
||||||
// the result is negative and there is a remainder - then trunc = floor + 1
|
// 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());
|
Wire *flooring = module->addWire(NEW_ID, sig_y.size());
|
||||||
cell->setPort(ID::Y, flooring);
|
cell->setPort(ID::Y, flooring);
|
||||||
|
|
||||||
|
@ -1698,7 +1698,7 @@ skip_identity:
|
||||||
|
|
||||||
std::vector<RTLIL::SigBit> new_b = RTLIL::SigSpec(State::S1, i);
|
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);
|
new_b.push_back(State::S0);
|
||||||
|
|
||||||
cell->type = ID($and);
|
cell->type = ID($and);
|
||||||
|
@ -1707,7 +1707,7 @@ skip_identity:
|
||||||
|
|
||||||
// truncating modulo has the same masked bits as flooring modulo, but
|
// truncating modulo has the same masked bits as flooring modulo, but
|
||||||
// the sign bits are those of A (except when R=0)
|
// 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());
|
Wire *flooring = module->addWire(NEW_ID, sig_y.size());
|
||||||
cell->setPort(ID::Y, flooring);
|
cell->setPort(ID::Y, flooring);
|
||||||
SigSpec truncating = SigSpec(flooring).extract(0, i);
|
SigSpec truncating = SigSpec(flooring).extract(0, i);
|
||||||
|
|
Loading…
Reference in New Issue