From 3bfeaee8ca216f17c11a6ab13ddaa877e2eb7ad0 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 2 Feb 2026 19:09:30 +0100 Subject: [PATCH] opt_expr: fix const lhs of $pow to $shl --- passes/opt/opt_expr.cc | 7 ++++-- tests/opt/opt_expr.ys | 56 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index ffe678d2f..7131053c9 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1667,7 +1667,11 @@ skip_identity: int bit_idx; const auto onehot = sig_a.is_onehot(&bit_idx); - if (onehot) { + // Power of two + // A is unsigned or positive + if (onehot && (!cell->parameters[ID::A_SIGNED].as_bool() || bit_idx < sig_a.size() - 1)) { + cell->parameters[ID::A_SIGNED] = 0; + // 2^B = 1<name.c_str(), module->name.c_str()); @@ -1679,7 +1683,6 @@ skip_identity: log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n", cell->name.c_str(), module->name.c_str()); cell->type = ID($mul); - cell->parameters[ID::A_SIGNED] = 0; cell->setPort(ID::A, Const(bit_idx, cell->parameters[ID::A_WIDTH].as_int())); SigSpec y_wire = module->addWire(NEW_ID, y_size); diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index 7c446afd1..61b54a92f 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -319,3 +319,59 @@ check equiv_opt -assert opt_expr -keepdc design -load postopt select -assert-count 1 t:$mul r:A_WIDTH=4 %i r:B_WIDTH=4 %i r:Y_WIDTH=8 %i + +########### + +design -reset +read_rtlil <