[PrepareForEmission] Incorrect emission of blocking assignments with disallowLocalVariables
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
Currently PrepareForEmission hoist expressions if `disallowLocalVariables` exists but it has been broken.
```mlir
module attributes {circt.loweringOptions = "disallowLocalVariables"} {
hw.module @Foo(%fd: i32) -> () {
%r1 = sv.reg : !hw.inout
sv.initial {
%1 = sv.verbatim.expr "`RANDOM" : () -> i4
sv.bpassign %r1, %1 : i4
%read = sv.read_inout %r1: !hw.inout
%2 = comb.add %read, %read: i4
%3 = comb.extract %2 from 0 : (i4) -> i2
sv.fwrite %fd, "%d"(%3) : i2
}
}
}
```
Current output is broken. `r1 + r1` must be spilled to a register.
```verilog
module Foo( // foo.mlir:3:3
input [31:0] fd);
reg [3:0] r1; // foo.mlir:4:12
wire [3:0] _GEN = r1 + r1; // foo.mlir:8:16, :9:13
initial begin // foo.mlir:5:6
r1 = `RANDOM; // foo.mlir:6:13, :7:8
$fwrite(fd, "%d", _GEN[1:0]); // foo.mlir:9:13, :10:13, :11:8
end // initial
endmodule
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the issue with the provided MLIR example and inspect PrepareForEmission's handling of disallowLocalVariables and blocking assignments. Trace why the r1 + r1 expression is emitted as a wire, then verify that the expression is spilled to a register and that the generated Verilog matches the intended behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100