circt
circt copied to clipboard
[Calyx] Verified-valid IR crashes in canonicalizer
Consider this snippet, created while trying to reduce example in #7050:
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
%c1_1 = hw.constant 1 : i1
calyx.wires {
}
calyx.control {
calyx.seq {
calyx.if %eq.out {
calyx.seq {
}
} else {
calyx.seq {
}
}
}
}
}
}
Feeding this through circt-opt -canonicalize crashes:
circt-opt: /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/ilist_iterator.h:138: reference llvm::ilist_iterator<llvm::ilist_detail::node_options<mlir::Operation, true, false, void, false>, true, false>::operator*() const [OptionsT = llvm::ilist_detail::node_options<mlir::Operation, true, false, void, false>, IsReverse = true, IsConst = false]: Assertion `!NodePtr->isKnownSentinel()' failed.
PLEASE submit a bug report to https://github.com/llvm/circt and include the crash backtrace.
Stack dump:
0. Program arguments: ./build/bin/circt-opt -canonicalize calyx-crash.mlir
#0 0x00005560165c0346 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/will/src/sifive/circt/llvm/llvm/lib/Support/Unix/Signals.inc:723:13
#1 0x00005560165be420 llvm::sys::RunSignalHandlers() /home/will/src/sifive/circt/llvm/llvm/lib/Support/Signals.cpp:106:18
#2 0x00005560165c09eb SignalHandler(int) /home/will/src/sifive/circt/llvm/llvm/lib/Support/Unix/Signals.inc:413:1
#3 0x00007f9bd7854eb0 __restore_rt (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x3deb0)
#4 0x00007f9bd78a402c __pthread_kill_implementation (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x8d02c)
#5 0x00007f9bd7854e06 gsignal (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x3de06)
#6 0x00007f9bd783d8f5 abort (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x268f5)
#7 0x00007f9bd783d819 _nl_load_domain.cold (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x26819)
#8 0x00007f9bd784d686 (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x36686)
#9 0x000055601679510a std::optional<circt::calyx::EnableOp> getLastEnableOp<circt::calyx::SeqOp>(circt::calyx::SeqOp) /home/will/src/sifive/circt/lib/Dialect/Calyx/CalyxOps.cpp:0:0
#10 0x00005560167579a3 mlir::LogicalResult commonTailPatternWithSeq<circt::calyx::IfOp, circt::calyx::SeqOp>(circt::calyx::IfOp, mlir::PatternRewriter&) /home/will/src/sifive/circt/lib/Dialect/Calyx/CalyxOps.cpp:2308:46
#11 0x0000556017e52e31 mlir::PatternApplicator::matchAndRewrite(mlir::Operation*, mlir::PatternRewriter&, llvm::function_ref<bool (mlir::Pattern const&)>, llvm::function_ref<void (mlir::Pattern const&)>, llvm::function_ref<mlir::LogicalResult (mlir::Pattern const&)>)::$_0::operator()() const /home/will/src/sifive/circt/llvm/mlir/lib/Rewrite/PatternApplicator.cpp:212:13
#12 0x0000556017e52e31 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<mlir::LogicalResult (mlir::Pattern const&)>)::$_0>(long) /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#13 0x0000556017e5196d mlir::PatternApplicator::matchAndRewrite(mlir::Operation*, mlir::PatternRewriter&, llvm::function_ref<bool (mlir::Pattern const&)>, llvm::function_ref<void (mlir::Pattern const&)>, llvm::function_ref<mlir::LogicalResult (mlir::Pattern const&)>) /home/will/src/sifive/circt/llvm/mlir/lib/Rewrite/PatternApplicator.cpp:233:9
#14 0x0000556017e2ffaf (anonymous namespace)::GreedyPatternRewriteDriver::processWorklist() /home/will/src/sifive/circt/llvm/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:0:0
#15 0x0000556017e2cfbc (anonymous namespace)::RegionPatternRewriteDriver::simplify(bool*) &&::$_2::operator()() const /home/will/src/sifive/circt/llvm/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:870:11
#16 0x0000556017e2cfbc void llvm::function_ref<void ()>::callback_fn<(anonymous namespace)::RegionPatternRewriteDriver::simplify(bool*) &&::$_2>(long) /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#17 0x0000556017e2cfbc llvm::function_ref<void ()>::operator()() const /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:12
#18 0x0000556017e2cfbc void mlir::MLIRContext::executeAction<(anonymous namespace)::GreedyPatternRewriteIteration, long&>(llvm::function_ref<void ()>, llvm::ArrayRef<mlir::IRUnit>, long&) /home/will/src/sifive/circt/llvm/mlir/include/mlir/IR/MLIRContext.h:275:7
#19 0x0000556017e2cfbc (anonymous namespace)::RegionPatternRewriteDriver::simplify(bool*) && /home/will/src/sifive/circt/llvm/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:868:10
#20 0x0000556017e2cfbc mlir::applyPatternsAndFoldGreedily(mlir::Region&, mlir::FrozenRewritePatternSet const&, mlir::GreedyRewriteConfig, bool*) /home/will/src/sifive/circt/llvm/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp:910:47
#21 0x0000556017ab0ffb mlir::LogicalResult::failed() const /home/will/src/sifive/circt/llvm/mlir/include/mlir/Support/LogicalResult.h:44:33
#22 0x0000556017ab0ffb mlir::applyPatternsAndFoldGreedily(mlir::Operation*, mlir::FrozenRewritePatternSet const&, mlir::GreedyRewriteConfig, bool*) /home/will/src/sifive/circt/llvm/mlir/include/mlir/Transforms/GreedyPatternRewriteDriver.h:149:14
#23 0x0000556017ab0ffb (anonymous namespace)::Canonicalizer::runOnOperation() /home/will/src/sifive/circt/llvm/mlir/lib/Transforms/Canonicalizer.cpp:63:9
#24 0x000055601814097f mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int)::$_1::operator()() const /home/will/src/sifive/circt/llvm/mlir/lib/Pass/Pass.cpp:0:17
#25 0x000055601814097f void llvm::function_ref<void ()>::callback_fn<mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int)::$_1>(long) /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#26 0x000055601814097f llvm::function_ref<void ()>::operator()() const /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:12
#27 0x000055601814097f void mlir::MLIRContext::executeAction<mlir::PassExecutionAction, mlir::Pass&>(llvm::function_ref<void ()>, llvm::ArrayRef<mlir::IRUnit>, mlir::Pass&) /home/will/src/sifive/circt/llvm/mlir/include/mlir/IR/MLIRContext.h:275:7
#28 0x000055601814097f mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /home/will/src/sifive/circt/llvm/mlir/lib/Pass/Pass.cpp:521:21
#29 0x00005560181433a2 mlir::LogicalResult::failed() const /home/will/src/sifive/circt/llvm/mlir/include/mlir/Support/LogicalResult.h:44:33
#30 0x00005560181433a2 mlir::failed(mlir::LogicalResult) /home/will/src/sifive/circt/llvm/mlir/include/mlir/Support/LogicalResult.h:72:58
#31 0x00005560181433a2 mlir::detail::OpToOpPassAdaptor::runPipeline(mlir::OpPassManager&, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /home/will/src/sifive/circt/llvm/mlir/lib/Pass/Pass.cpp:593:9
#32 0x00005560181433a2 mlir::PassManager::runPasses(mlir::Operation*, mlir::AnalysisManager) /home/will/src/sifive/circt/llvm/mlir/lib/Pass/Pass.cpp:904:10
#33 0x00005560181433a2 mlir::PassManager::run(mlir::Operation*) /home/will/src/sifive/circt/llvm/mlir/lib/Pass/Pass.cpp:884:60
#34 0x0000556017a88c66 mlir::LogicalResult::failed() const /home/will/src/sifive/circt/llvm/mlir/include/mlir/Support/LogicalResult.h:44:33
#35 0x0000556017a88c66 mlir::failed(mlir::LogicalResult) /home/will/src/sifive/circt/llvm/mlir/include/mlir/Support/LogicalResult.h:72:58
#36 0x0000556017a88c66 performActions(llvm::raw_ostream&, std::shared_ptr<llvm::SourceMgr> const&, mlir::MLIRContext*, mlir::MlirOptMainConfig const&) /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:407:7
#37 0x0000556017a888b6 processBuffer(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::MlirOptMainConfig const&, mlir::DialectRegistry&, llvm::ThreadPoolInterface*) /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:472:12
#38 0x0000556017a888b6 mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::DialectRegistry&, mlir::MlirOptMainConfig const&)::$_0::operator()(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) const /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:547:12
#39 0x0000556017a888b6 mlir::LogicalResult llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, 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::raw_ostream&) /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#40 0x0000556017aaf93b llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>::operator()(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) const /home/will/src/sifive/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:12
#41 0x0000556017aaf93b mlir::splitAndProcessBuffer(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>, llvm::raw_ostream&, llvm::StringRef, llvm::StringRef) /home/will/src/sifive/circt/llvm/mlir/lib/Support/ToolUtilities.cpp:28:12
#42 0x0000556017a868b1 mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::DialectRegistry&, mlir::MlirOptMainConfig const&) /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:550:10
#43 0x0000556017a86b93 mlir::MlirOptMain(int, char**, llvm::StringRef, llvm::StringRef, mlir::DialectRegistry&) /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:588:14
#44 0x0000556017a86de5 mlir::MlirOptMain(int, char**, llvm::StringRef, mlir::DialectRegistry&) /home/will/src/sifive/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:604:10
#45 0x0000556016514f16 main /home/will/src/sifive/circt/tools/circt-opt/circt-opt.cpp:76:23
#46 0x00007f9bd783f0ce __libc_start_call_main (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x280ce)
#47 0x00007f9bd783f189 __libc_start_main@GLIBC_2.2.5 (/nix/store/p3jshbwxiwifm1py0yq544fmdyy98j8a-glibc-2.38-27/lib/libc.so.6+0x28189)
#48 0x0000556016514785 _start (./build/bin/circt-opt+0x1509785)
I've made some progress on this issue, and the reason for the crash is that the calyx.seq in the if structure is empty, and the pattern checking mechanism isn't strict enough, causing the crash when fetching the last op in the seq. After fixing this issue, a new problem arose.Apparently calyx.control is empty after canonicalize, which is the exact reason.
test.mlir:2:3: note: see current operation:
"calyx.component"() ({
^bb0(%arg0: i1, %arg1: i1, %arg2: i1, %arg3: i1):
%0:6 = "calyx.register"() {sym_name = "r"} : () -> (i1, i1, i1, i1, i1, i1)
"calyx.wires"() ({
^bb0:
}) : () -> ()
"calyx.control"() ({
^bb0:
}) : () -> ()
}) {function_type = (i1, i1, i1, i1) -> (), portAttributes = [{go}, {clk}, {reset}, {done}], portDirections = -8 : i4, portNames = ["go", "clk", "reset", "done"], sym_name = "main"} : () -> ()
I think the contents of calyx.control need to be scrutinized more closely, if there is no execute semantics in it, an error should be reported, it is too late to report an error after canonicalize.