llvm / llvm/circt

[FIRRTL] InjectDUTHierarchy Creates Names that Conflict with ExtModule Defnames

Open
#8,508 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug FIRRTL
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

Consider the following circuit:

FIRRTL version 5.1.0
circuit Foo: %[[
  {
    "class": "sifive.enterprise.firrtl.MarkDUTAnnotation",
    "target": "~|Bar"
  },
  {
    "class": "sifive.enterprise.firrtl.InjectDUTHierarchyAnnotation",
    "name": "logic"
  }
]]

  extmodule Bar:
    output a: UInt<1>

    defname = Bar

  public module Foo:
    output a: UInt<1>

    inst bar of Bar
    connect a, bar.a

When compiled (without assertions) this will create an illegal circuit:

$ firtool Foo.fir
Foo.fir:13:3: error: 'firrtl.extmodule' op attribute 'defname' with value "Bar" conflicts with the name of another module in the circuit
  extmodule Bar:
  ^
Foo.fir:13:3: note: see current operation: 
"firrtl.extmodule"() <{annotations = [], convention = #firrtl<convention scalarized>, defname = "Bar", layers = [], parameters = [], portAnnotations = [[]], portDirections = array<i1: true>, portLocations = [loc("Foo.fir":14:12)], portNames = ["a"], portSymbols = [], portTypes = [!firrtl.uint<1>], sym_name = "logic"}> ({
}) : () -> ()
Foo.fir:13:3: note: previous module declared here

The problem is that the created wrapper module name conflicts with the defname of the external module. (I realize that this circuit is weird as the DUT is a blackbox.)

When compiled with assertions on, this will trip an assertion:

Assertion failed: (isa<To>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file Casting.h, line 566.
PLEASE submit a bug report to https://github.com/llvm/circt and include the crash backtrace.
Stack dump:
0.	Program arguments: firtool /Users/schuylereldridge/repos/github.com/seldridge/firrtl-snippets/inject-dut-hierarchy-extmodule.fir -verbose-pass-executions
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  firtool                  0x000000010476353c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  firtool                  0x00000001047619bc llvm::sys::RunSignalHandlers() + 112
2  firtool                  0x0000000104763ba4 SignalHandler(int, __siginfo*, void*) + 312
3  libsystem_platform.dylib 0x000000019150c624 _sigtramp + 56
4  libsystem_pthread.dylib  0x00000001914d288c pthread_kill + 296
5  libsystem_c.dylib        0x00000001913dbc60 abort + 124
6  libsystem_c.dylib        0x00000001913daeec err + 0
7  firtool                  0x000000010522d014 circt::ExportVerilog::isExpressionEmittedInline(mlir::Operation*, circt::LoweringOptions const&) (.cold.4) + 0
8  firtool                  0x00000001048a2c94 (anonymous namespace)::InjectDUTHierarchy::runOnOperation() + 5980
9  firtool                  0x00000001051d8784 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) + 588
10 firtool                  0x00000001051d8f8c mlir::detail::OpToOpPassAdaptor::runPipeline(mlir::OpPassManager&, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) + 312
11 firtool                  0x00000001051d9ee0 mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool) + 1652
12 firtool                  0x00000001051d8ae4 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) + 1452
13 firtool                  0x00000001051dacdc mlir::PassManager::run(mlir::Operation*) + 1112
14 firtool                  0x00000001046998b0 processBuffer(mlir::MLIRContext&, circt::firtool::FirtoolOptions&, mlir::TimingScope&, llvm::SourceMgr&, std::__1::optional<std::__1::unique_ptr<llvm::ToolOutputFile, std::__1::default_delete<llvm::ToolOutputFile>>>&) + 3388
15 firtool                  0x0000000104698aa8 processInputSplit(mlir::MLIRContext&, circt::firtool::FirtoolOptions&, mlir::TimingScope&, std::__1::unique_ptr<llvm::MemoryBuffer, std::__1::default_delete<llvm::MemoryBuffer>>, std::__1::optional<std::__1::unique_ptr<llvm::ToolOutputFile, std::__1::default_delete<llvm::ToolOutputFile>>>&) + 380
16 firtool                  0x00000001046944a0 executeFirtool(mlir::MLIRContext&, circt::firtool::FirtoolOptions&) + 936
17 firtool                  0x000000010469209c main + 336
18 dyld                     0x0000000191132b98 start + 6076
zsh: abort      firtool  -verbose-pass-executions

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the FIRRTL circuit shown in the report and inspect the InjectDUTHierarchy pass, identified in the assertion stack trace. Check that the generated wrapper and the extmodule defname no longer conflict and that compilation with assertions enabled completes without the reported crash.

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
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.