3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-12 00:53:26 +00:00

Merge pull request #5101 from georgerennie/george/opt_expr_shift_ovfl

opt_expr: fix shift optimization with overflowing shift amount
This commit is contained in:
George Rennie 2025-05-22 15:16:19 +01:00 committed by GitHub
commit 6331f92d00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 168 additions and 2 deletions

View file

@ -1307,7 +1307,12 @@ skip_fine_alu:
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && (keepdc ? assign_map(cell->getPort(ID::B)).is_fully_def() : assign_map(cell->getPort(ID::B)).is_fully_const()))
{
bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID::A_SIGNED).as_bool();
int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID::B_SIGNED).as_bool());
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
const bool b_sign_ext = cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID::B_SIGNED).as_bool();
// We saturate the value to prevent overflow, but note that this could
// cause incorrect opimization in the impractical case that A is 2^32 bits
// wide
int shift_bits = sig_b.as_int_saturating(b_sign_ext);
if (cell->type.in(ID($shl), ID($sshl)))
shift_bits *= -1;