llvm / llvm/circt

[ImportVerilog] Don't convert lvalues

Open
#11,026 0 comments 0 reactions 0 assignees View on GitHub
ImportVerilog
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

Removal of the `moore.conversion` op in #11024 has uncovered a few places where we try to cast an lvalue to a different type. This doesn't work, since lvalues are `ref` pointing to a variable or some other memory-like thing, and we can't simply cast that pointer to a `ref`. This has come up with `output`, `inout`, and `ref` subroutine arguments, and `inout` module port connections. Instead of trying to cast the lvalue, we need to pass in a temporary of the correct `ref` value, and then upon write-back cast the `U` to `V` and do the actual write to `ref`. Modules already do this to some degree when dealing with output ports.

```systemverilog
module implicitCastsFunctionArguments;
real r, q;

function void fn(output logic [3:0] o, input logic [3:0] val);
o = val;
endfunction

initial fn(q, r);
endmodule
```
```
error: unsupported conversion from '!moore.ref' to '!moore.ref'
```

The same shape shows up for module inout ports whose connecting net has a different width than the port (see the `virtual-interface-modport.sv` XFAIL test for a related but distinct case: modport port renaming, not a width/domain mismatch).

`Context::materializeConversion` is fundamentally an rvalue-conversion helper; given two ref types it has nothing better to do than reinterpret the pointee in place, which is wrong. A real fix needs to read through the actual's ref, convert the value, and write it back through a temporary (or similar) rather than converting the ref type itself — this is a different code path from ordinary value conversion. The two call sites are the output/inout/ref argument handling in `lib/Conversion/ImportVerilog/Expressions.cpp` and the module instance port connection handling in `lib/Conversion/ImportVerilog/Structure.cpp`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in lib/Conversion/ImportVerilog/Expressions.cpp and Structure.cpp at the two call sites named in the issue, then inspect Context::materializeConversion to understand why ref types are mishandled. Use the implicitCastsFunctionArguments example and the virtual-interface-modport.sv XFAIL test as references. Done means output/inout/ref arguments and module inout connections read through the actual ref, convert through a temporary, and write back correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.