Skip to content

[Calyx] Segfault in SCFToCalyx when func.call exists inside loop body #9529

@m2kar

Description

@m2kar

Description

lower-scf-to-calyx pass crashes with a segmentation fault when processing a function containing func.call operations inside a loop body. The crash occurs in BuildControl::buildCFGControl when constructing mlir::SuccessorRange with an invalid Block pointer.

When an affine.for loop containing func.call is lowered through --lower-affine and --scf-for-to-while, the resulting SCF while loop triggers a null pointer access during Calyx control flow construction.

Crash Type: Segmentation Fault (SIGSEGV)
Dialect: Calyx
Failing Pass: lower-scf-to-calyx (SCFToCalyx)

Steps to Reproduce

  1. Save the test case below as test.mlir
  2. Run:
    mlir-opt --lower-affine --scf-for-to-while test.mlir | \
      circt-opt --pass-pipeline='builtin.module(lower-scf-to-calyx{top-level-function=f})'

Test Case

// Minimal test case: func.call inside affine.for triggers SCFToCalyx segfault

func.func private @ext()

func.func @f() {
  affine.for %i = 0 to 1 {
    func.call @ext() : () -> ()
  }
  return
}

Error Output

PLEASE submit a bug report to https://github.com/llvm/circt and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/firtool-1.139.0/bin/circt-opt --pass-pipeline=builtin.module(lower-scf-to-calyx{top-level-function=f})
 #0 0x00007fc013a018a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/firtool-1.139.0/bin/../lib/libLLVMSupport.so+0x2008a8)
 #1 0x00007fc0139ff2f5 llvm::sys::RunSignalHandlers() (/opt/firtool-1.139.0/bin/../lib/libLLVMSupport.so+0x1fe2f5)
 #2 0x00007fc013a02631 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007fc01350f330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007fc013c4a4f3 mlir::SuccessorRange::SuccessorRange(mlir::Block*) (/opt/firtool-1.139.0/bin/../lib/libMLIRIR.so+0x8f4f3)
 #5 0x00007fc0199004f7 circt::scftocalyx::BuildControl::buildCFGControl(llvm::DenseSet<mlir::Block*, llvm::DenseMapInfo<mlir::Block*, void>>, mlir::PatternRewriter&, mlir::Block*, mlir::Block*, mlir::Block*) const (/opt/firtool-1.139.0/bin/../lib/libCIRCTSCFToCalyx.so+0x644f7)
 #6 0x00007fc019900256 circt::scftocalyx::BuildControl::partiallyLowerFuncToComp(mlir::func::FuncOp, mlir::PatternRewriter&) const (/opt/firtool-1.139.0/bin/../lib/libCIRCTSCFToCalyx.so+0x64256)
 #7 0x00007fc0187e298d circt::calyx::FuncOpPartialLoweringPattern::partiallyLower(mlir::func::FuncOp, mlir::PatternRewriter&) const (/opt/firtool-1.139.0/bin/../lib/libCIRCTCalyxTransforms.so+0x1c98d)
 #8 0x00007fc0198f5047 circt::calyx::PartialLoweringPattern<mlir::func::FuncOp, mlir::OpRewritePattern>::matchAndRewrite(mlir::func::FuncOp, mlir::PatternRewriter&) const (/opt/firtool-1.139.0/bin/../lib/libCIRCTSCFToCalyx.so+0x59047)
 #9 0x00007fc015f6b8ed void llvm::function_ref<void ()>::callback_fn<mlir::PatternApplicator::matchAndRewrite(mlir::Operation*, mlir::PatternRewriter&, llvm::function_ref<bool (mlir::Pattern const&)>, llvm::function_ref<void (mlir::Pattern const&)>, llvm::function_ref<llvm::LogicalResult (mlir::Pattern const&)>)::$_0>(long) PatternApplicator.cpp:0:0
#10 0x00007fc015f68774 mlir::PatternApplicator::matchAndRewrite(mlir::Operation*, mlir::PatternRewriter&, llvm::function_ref<bool (mlir::Pattern const&)>, llvm::function_ref<void (mlir::Pattern const&)>, llvm::function_ref<llvm::LogicalResult (mlir::Pattern const&)>) (/opt/firtool-1.139.0/bin/../lib/libMLIRRewrite.so+0x7774)
#11 0x00007fc015fc04a7 (anonymous namespace)::GreedyPatternRewriteDriver::processWorklist() GreedyPatternRewriteDriver.cpp:0:0
#12 0x00007fc015fbdfd9 mlir::applyPatternsGreedily(mlir::Region&, mlir::FrozenRewritePatternSet const&, mlir::GreedyRewriteConfig, bool*) (/opt/firtool-1.139.0/bin/../lib/libMLIRTransformUtils.so+0x46fd9)
#13 0x00007fc0198ef341 circt::(anonymous namespace)::SCFToCalyxPass::runOnOperation() SCFToCalyx.cpp:0:0
#14 0x00007fc015d5b2a5 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) (/opt/firtool-1.139.0/bin/../lib/libMLIRPass.so+0x172a5)
#15 0x00007fc015d5e7a9 mlir::PassManager::run(mlir::Operation*) (/opt/firtool-1.139.0/bin/../lib/libMLIRPass.so+0x1a7a9)
#16 0x00007fc0196b906a performActions(llvm::raw_ostream&, std::shared_ptr<llvm::SourceMgr> const&, mlir::MLIRContext*, mlir::MlirOptMainConfig const&) MlirOptMain.cpp:0:0
#17 0x00007fc0196b81be llvm::LogicalResult llvm::function_ref<llvm::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::MemoryBufferRef const&, llvm::raw_ostream&)>::callback_fn<mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::DialectRegistry&, mlir::MlirOptMainConfig const&)::$_0>(long, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::MemoryBufferRef const&, llvm::raw_ostream&) MlirOptMain.cpp:0:0
#18 0x00007fc013b90257 mlir::splitAndProcessBuffer(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<llvm::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::MemoryBufferRef const&, llvm::raw_ostream&)>, llvm::raw_ostream&, llvm::StringRef, llvm::StringRef) (/opt/firtool-1.139.0/bin/../lib/libMLIRSupport.so+0x27257)
#19 0x00007fc0196ae4e8 mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::DialectRegistry&, mlir::MlirOptMainConfig const&) (/opt/firtool-1.139.0/bin/../lib/libMLIROptLib.so+0xa4e8)
#20 0x00007fc0196ae7d6 mlir::MlirOptMain(int, char**, llvm::StringRef, llvm::StringRef, mlir::DialectRegistry&) (/opt/firtool-1.139.0/bin/../lib/libMLIROptLib.so+0xa7d6)
#21 0x00007fc0196aea0d mlir::MlirOptMain(int, char**, llvm::StringRef, mlir::DialectRegistry&) (/opt/firtool-1.139.0/bin/../lib/libMLIROptLib.so+0xaa0d)
#22 0x0000560f2bbc5e10 main (/opt/firtool-1.139.0/bin/circt-opt+0xde10)
#23 0x00007fc0134f41ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#24 0x00007fc0134f428b call_init ./csu/../csu/libc-start.c:128:20
#25 0x00007fc0134f428b __libc_start_main ./csu/../csu/libc-start.c:347:5
#26 0x0000560f2bbc56a5 _start (/opt/firtool-1.139.0/bin/circt-opt+0xd6a5)

Root Cause Analysis

Cause: SCFToCalyx does not support func.call operations inside loop bodies

Mechanism: buildCFGControl encounters func.call which introduces unexpected CFG edges or Block successor structure, leading to null pointer access in SuccessorRange constructor.

Environment

  • CIRCT Version: firtool-1.139.0
  • OS: Linux
  • Architecture: x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions