From 32ba90e9dab52be7b306c793c6fca4b10a78274d Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 24 Sep 2025 15:30:15 +0200 Subject: [PATCH 1/2] Fixed an assert violation and a SIGSEGV in emap. The former resulting from a missing value reset and floating-point type mismatch, and the latter stemming from an overlooked corner case in arrival time propagation --- include/mockturtle/algorithms/emap.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/mockturtle/algorithms/emap.hpp b/include/mockturtle/algorithms/emap.hpp index 055d9b25b..e4b02605a 100644 --- a/include/mockturtle/algorithms/emap.hpp +++ b/include/mockturtle/algorithms/emap.hpp @@ -1107,7 +1107,7 @@ class emap_impl node_data.est_refs[0] = node_data.est_refs[1] = static_cast( ntk.fanout_size( n ) ); node_data.map_refs[0] = node_data.map_refs[1] = 0; - node_data.required[0] = node_data.required[1] = std::numeric_limits::max(); + node_data.required[0] = node_data.required[1] = std::numeric_limits::max(); if ( ntk.is_constant( n ) ) { @@ -1618,6 +1618,8 @@ class emap_impl /* reset mapping */ node_match[index].map_refs[0] = node_match[index].map_refs[1] = 0u; + node_match[index].arrival[0] = node_match[index].arrival[1] = 0.0; + node_match[index].required[0] = node_match[index].required[1] = std::numeric_limits::max(); if ( ntk.is_constant( n ) ) continue; @@ -2343,6 +2345,13 @@ class emap_impl } } + // guard against unmapped nodes: if neither phase has a best gate, skip + if ( node_data.best_gate[0] == nullptr && node_data.best_gate[1] == nullptr ) + { + // no valid mapping stored for this node (e.g., not in cover); skip arrival/area. + continue; + } + uint8_t use_phase = node_data.best_gate[0] != nullptr ? 0 : 1; /* compute arrival of use_phase */ @@ -5969,4 +5978,4 @@ void emap_load_mapping( Ntk& ntk ) } ); } -} /* namespace mockturtle */ \ No newline at end of file +} /* namespace mockturtle */ From 39d8572cb9d713722bc097037e945015121a60e1 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 25 Sep 2025 12:01:49 +0200 Subject: [PATCH 2/2] Add failing test case --- test/algorithms/emap.cpp | 47 +++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/test/algorithms/emap.cpp b/test/algorithms/emap.cpp index 514c405e8..dd8d7a0e8 100644 --- a/test/algorithms/emap.cpp +++ b/test/algorithms/emap.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -273,7 +274,7 @@ TEST_CASE( "Emap on ripple carry adder with multi-output gates", "[emap]" ) tech_library<3, classification_type::p_configurations> lib( gates, tps ); aig_network aig; - + std::vector a( 8 ), b( 8 ); std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } ); std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } ); @@ -316,7 +317,7 @@ TEST_CASE( "Emap on ripple carry adder with multi-output cells", "[emap]" ) tech_library<3, classification_type::p_configurations> lib( gates, tps ); aig_network aig; - + std::vector a( 8 ), b( 8 ); std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } ); std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } ); @@ -721,7 +722,7 @@ TEST_CASE( "Emap with global required times", "[emap]" ) tech_library<6> lib( gates ); aig_network aig; - + std::vector a( 8 ), b( 8 ); std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } ); std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } ); @@ -761,7 +762,7 @@ TEST_CASE( "Emap with required times", "[emap]" ) tech_library<6> lib( gates ); aig_network aig; - + std::vector a( 8 ), b( 8 ); std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } ); std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } ); @@ -802,7 +803,7 @@ TEST_CASE( "Emap with required time relaxation", "[emap]" ) tech_library<6> lib( gates ); aig_network aig; - + std::vector a( 8 ), b( 8 ); std::generate( a.begin(), a.end(), [&aig]() { return aig.create_pi(); } ); std::generate( b.begin(), b.end(), [&aig]() { return aig.create_pi(); } ); @@ -1011,4 +1012,38 @@ TEST_CASE( "Emap on circuit with don't touch cells", "[emap]" ) CHECK( st.area < 11.0f + eps ); CHECK( st.delay > 5.8f - eps ); CHECK( st.delay < 5.8f + eps ); -} \ No newline at end of file +} + +TEST_CASE( "Failing test case", "[emap]" ) +{ + std::string const failing_library = "GATE zero 0 O=CONST0;\n" + "GATE one 0 O=CONST1;\n" + "GATE buf 1 O=a; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n" + "GATE inv1 1 O=!a; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n" + "GATE and2 1 O=a*b; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n" + "GATE or2 1 O=a+b; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n" + "GATE maj3 1 O=a*b+a*c+b*c; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; + + std::vector gates; + + std::istringstream in( failing_library ); + auto result = lorina::read_genlib( in, genlib_reader( gates ) ); + CHECK( result == lorina::return_code::success ); + + tech_library<3> lib( gates ); + + xag_network xag; + const auto a = xag.create_pi(); + const auto b = xag.create_pi(); + const auto c = xag.create_pi(); + + const auto f = xag.create_maj( a, b, c ); + xag.create_po( f ); + + emap_params ps; + emap_stats st; + cell_view ntk = emap( xag, lib, ps, &st ); + + CHECK( ntk.num_pis() == 3u ); + CHECK( ntk.num_pos() == 1u ); +}