[ARC] arcilator fails to legalize 'llhd.process' during class instantiation lowering
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
## Bug Report: arcilator fails to legalize 'llhd.process' during class instantiation lowering
**Tool**: CIRCT v1.144.0 (circt-verilog + arcilator)
**Severity**: Compilation Error
### Description
CIRCT fails to compile SystemVerilog code containing class instantiation in procedural context. The `circt-verilog` frontend successfully parses the class declaration and generates MLIR, but the `arcilator` backend crashes with a legalization failure: **"failed to legalize operation 'llhd.process' that was explicitly marked illegal"**. This is a circt compilation error where Verilator and Icarus Verilog successfully compile the same code without errors.
The root cause is that CIRCT incorrectly lowers SystemVerilog class instantiation to `llhd.process` operations, which Arcilator cannot convert to LLVM IR. The `llhd.process` dialect is designed for hardware simulation processes, not software object allocation.
### Minimal Reproducible Example
```systemverilog
module top;
class parent;
endclass
initial begin
parent p = new();
end
endmodule
```
### Reproduction Steps
```bash
# CIRCT fails
circt-verilog --ir-hw minimal_testcase.sv | arcilator
# Verilator succeeds
verilator --lint-only --sv minimal_testcase.sv
# Icarus Verilog succeeds
iverilog -g2012 minimal_testcase.sv
```
### Actual Output
```
$ circt-verilog --ir-hw minimal_testcase.sv | arcilator
minimal_testcase.sv:6:12: warning: initializing a static variable in a procedural context requires an explicit 'static' keyword [-Wexplicit-static]
parent p = new();
^
minimal_testcase.sv:2:9: remark: Class builtin functions (needed for randomization, constraints, and covergroups) are not yet supported and will be dropped during lowering.
class parent;
^
:5:5: error: failed to legalize operation 'llhd.process' that was explicitly marked illegal: "llhd.process"() ({...}) : () -> ()
llhd.process {
^
:5:5: note: see current operation:
"llhd.process"() ({
%1 = "func.call"(%0) <{callee = @malloc}> : (i64) -> !llvm.ptr
"llhd.halt"() : () -> ()
}) : () -> ()
:1:1: error: conversion to arcs failed
module {
^
```
### Expected Output
The code should compile successfully without errors. The testcase is valid IEEE 1800-2023 SystemVerilog:
- Class declaration is valid (IEEE 1800-2023 Section 8.2)
- Class instantiation with `new()` is valid (IEEE 1800-2023 Section 8.13)
- Procedural context (`initial` block) is valid (IEEE 1800-2023 Section 9.2)
Verilator and Icarus Verilog both compile this code successfully.
### Cross-Tool Comparison
| Tool | Version | Result |
|------|---------|--------|
| Verilator | 5.022 | Success |
| Icarus Verilog | 13.0 (devel) | Success |
| CIRCT | v1.144.0 | Failure |
**Consensus**: Most tools handle this correctly; CIRCT has compilation issues with class instantiation due to incorrect lowering to `llhd.process` dialect.
### Root Cause (Preliminary)
CIRCT's `circt-verilog` frontend lowers class instantiation to `llhd.process` operations, but Arcilator lacks a legalization pattern to convert `llhd.process` to LLVM IR. This is a fundamental architectural issue:
1. **Incomplete Class Support**: CIRCT emits a remark acknowledging classes are unsupported but continues processing instead of rejecting the input with a clear error message.
2. **Missing Arcilator Pattern**: Arcilator's ConvertToArcs pass marks the entire LLHD dialect as illegal but lacks conversion patterns for `llhd.process` operations generated by class instantiation.
3. **Dialect Design Mismatch**: LLHD `process` constructs represent hardware simulation processes (concurrent behavior), while SystemVerilog class instantiation represents software object allocation. Using `llhd.process` for classes is a conceptual mismatch.
**Failure Point**: Arcilator (CIRCT's LLHD-to-LLVM conversion pass), legalization stage before LLVM IR generation.
### Standard Compliance Assessment
**Classification**: Tool Bug (CIRCT Implementation Issue)
**IEEE References**:
- IEEE 1800-2023 Section 8.2 (Class Declarations)
- IEEE 1800-2023 Section 8.13 (Class Instantiation)
- IEEE 1800-2023 Section 9.2 (Initial Procedures)
**Analysis**:
The testcase is fully IEEE 1800-2023 compliant. No undefined behavior or ambiguous constructs exist. CIRCT's failure to compile this code is a tool deficiency, not a standard compliance issue. The frontend generates invalid MLIR by lowering class instantiation to an incompatible dialect (`llhd.process` instead of LLVM dialect), and the backend lacks legalization patterns to handle the result.
**Recommended Fix**:
- **Short-term**: Emit a clear error message in `circt-verilog` when encountering class instantiation instead of attempting lowering
- **Long-term**: Implement proper class instantiation lowering directly to LLVM dialect (not LLHD dialect), similar to Verilator's C++ generation strategy
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with the minimal SystemVerilog example using circt-verilog --ir-hw followed by arcilator, then inspect the ConvertToArcs legalization stage and the generated llhd.process operation. Determine whether the intended scope is an early unsupported-feature error or class-instantiation lowering; done means the chosen behavior is implemented and covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend, compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100