Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misoptimization of wide shifts #4164

Open
flaviens opened this issue Jan 26, 2024 · 3 comments
Open

Misoptimization of wide shifts #4164

flaviens opened this issue Jan 26, 2024 · 3 comments
Labels

Comments

@flaviens
Copy link

Version

Yosys 0.37+29 (git sha1 3c3788e, clang 10.0.0-4ubuntu1 -fPIC -Os)

On which OS did this happen?

Linux

Reproduction Steps

Hi there!

I stumbled into an issue where a wide shift gets some misoptimization.
I could reduce it to a very simple circuit, that is packaged into this repository for helping you reproduce the issue.
Interestingly, reducing the shift operand width by 1 more will clear the bug.

Please let me know if you require any more information or help, or please let me know if I did something wrong here.

Thank you!
Flavien

Expected Behavior

no optimization
Output: 00000000
with optimization
Output: 00000000

Actual Behavior

no optimization
Output: 00000000
with optimization
Output: ffffffff

@flaviens flaviens added the pending-verification This issue is pending verification and/or reproduction label Jan 26, 2024
@flaviens flaviens changed the title Missynthesis of wide shifts Misoptimization of wide shifts Jan 26, 2024
@povik
Copy link
Member

povik commented Jan 26, 2024

Reproduces with

read_verilog -sv <<EOF
module top(out_data);
  wire [90:0] fullone_0;
  wire [90:0] fullone_1;
  wire [289:0] shiftout;
  output [31:0] out_data;
  wire [31:0] out_data;
  assign shiftout = fullone_0 << fullone_1;
  assign fullone_0 = '1;
  assign fullone_1 = '1;
  assign out_data[31:0] = shiftout[31:0];
endmodule
EOF
eval w:out_data
debug opt_expr
eval w:out_data

with log output

1. Executing Verilog-2005 frontend: <<EOF
Parsing SystemVerilog input from `<<EOF' to AST representation.
Generating RTLIL representation for module `\top'.
Successfully finished Verilog frontend.

2. Executing EVAL pass (evaluate the circuit given an input).
Eval result: \out_data = 0.

3. Executing OPT_EXPR pass (perform const folding).
Optimizing module top.
Replacing $shl cell `$shl$<<EOF:7$1' (B=91'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111, SHR=1) in module `top' with fixed wiring: 290'00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

4. Executing EVAL pass (evaluate the circuit given an input).
Eval result: \out_data = 32'11111111111111111111111111111111.

@povik povik added bug and removed pending-verification This issue is pending verification and/or reproduction labels Jan 26, 2024
@povik
Copy link
Member

povik commented Jan 26, 2024

Looks like the blame is on SigSpec::as_int overflowing here

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());

@jix
Copy link
Member

jix commented Jan 26, 2024

This might be the same bug as #4010. I have some work in progress to detect and error out on as_int overflows in general together with some fixes for places where it could overflow (like this optimization) but I haven't found the time finish it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants