From e8bc25a220edbaeeb38dc4f11b1e328fdb8ddc6d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 10:37:17 +1200 Subject: [PATCH 01/11] bugpoint: Document -wires flag --- passes/cmds/bugpoint.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index da06acedf..e1f3544b4 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -89,6 +89,10 @@ struct BugpointPass : public Pass { log(" -updates\n"); log(" try to remove process updates from syncs.\n"); log("\n"); + log(" -wires\n"); + log(" try to remove wires. wires with a (* bugpoint_keep *) attribute will be\n"); + log(" skipped.\n"); + log("\n"); log(" -runner \"\"\n"); log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); log("\n"); From 996539a26fbddcff5412334a5aaafc41871aa11e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 10:37:17 +1200 Subject: [PATCH 02/11] bugpoint: Add -expect-return Allows checking return value from crashing design. Makes it possible to only accept designs that crash with e.g. SEGFAULT. Based on `exec -expect-return`. --- passes/cmds/bugpoint.cc | 62 +++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index e1f3544b4..24c778fdb 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -50,6 +50,10 @@ struct BugpointPass : public Pass { log(" -grep \"\"\n"); log(" only consider crashes that place this string in the log file.\n"); log("\n"); + log(" -expect-return \n"); + log(" only consider crashes that return the specified value. e.g. SEGFAULT\n"); + log(" returns a value of 139.\n"); + log("\n"); log(" -fast\n"); log(" run `proc_clean; clean -purge` after each minimization step. converges\n"); log(" faster, but produces larger testcases, and may fail to produce any\n"); @@ -98,7 +102,7 @@ struct BugpointPass : public Pass { log("\n"); } - bool run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg) + int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg) { design->sort(); @@ -107,7 +111,16 @@ struct BugpointPass : public Pass { f.close(); string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str()); - return run_command(yosys_cmdline) == 0; + auto status = run_command(yosys_cmdline); + // we're not processing lines, which means we're getting raw system() returns + if(WIFEXITED(status)) + return WEXITSTATUS(status); + else if(WIFSIGNALED(status)) + return WTERMSIG(status); + else if(WIFSTOPPED(status)) + return WSTOPSIG(status); + else + return 0; } bool check_logfile(string grep) @@ -404,6 +417,8 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { string yosys_cmd = "yosys", yosys_arg, grep, runner; + bool flag_expect_return = false, has_check = false; + int expect_return_value = 0; bool fast = false, clean = false; bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; @@ -430,9 +445,19 @@ struct BugpointPass : public Pass { continue; } if (args[argidx] == "-grep" && argidx + 1 < args.size()) { + has_check = true; grep = args[++argidx]; continue; } + if (args[argidx] == "-expect-return") { + flag_expect_return = true; + ++argidx; + if (argidx >= args.size()) + log_cmd_error("No expected return value specified.\n"); + + expect_return_value = atoi(args[argidx].c_str()); + continue; + } if (args[argidx] == "-fast") { fast = true; continue; @@ -496,6 +521,9 @@ struct BugpointPass : public Pass { if (yosys_arg.empty()) log_cmd_error("Missing -script or -command option.\n"); + if (flag_expect_return && expect_return_value == 0 && !has_check) + log_cmd_error("Nothing to match on for -expect-return 0; change value or use -grep.\n"); + if (!has_part) { modules = true; @@ -512,7 +540,10 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - if (run_yosys(crashing_design, runner, yosys_cmd, yosys_arg)) + int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg); + if (flag_expect_return && retval != expect_return_value) + log_cmd_error("The provided script file or command and Yosys binary returned value %d instead of expected %d on this design!\n", retval, expect_return_value); + if (!flag_expect_return && retval == 0) log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -525,21 +556,37 @@ struct BugpointPass : public Pass { { simplified = clean_design(simplified, fast, /*do_delete=*/true); - bool crashes; if (clean) { RTLIL::Design *testcase = clean_design(simplified); - crashes = !run_yosys(testcase, runner, yosys_cmd, yosys_arg); + retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg); delete testcase; } else { - crashes = !run_yosys(simplified, runner, yosys_cmd, yosys_arg); + retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg); } - if (crashes && check_logfile(grep)) + bool crashes = false; + if (flag_expect_return && retval == expect_return_value && check_logfile(grep)) + { + log("Testcase matches expected crash.\n"); + crashes = true; + } + else if (!flag_expect_return && retval == 0) + log("Testcase does not crash.\n"); + else if (!flag_expect_return && check_logfile(grep)) { log("Testcase crashes.\n"); + crashes = true; + } + else + // flag_expect_return && !(retval == expect_return_value && check_logfile(grep)) + // !flag_expect_return && !(retval == 0 && check_logfile(grep)) + log("Testcase does not match expected crash.\n"); + + if (crashes) + { if (crashing_design != design) delete crashing_design; crashing_design = simplified; @@ -547,7 +594,6 @@ struct BugpointPass : public Pass { } else { - log("Testcase does not crash.\n"); delete simplified; seed++; } From 50da04a75e5d7749ebdff384adcfb90a1a700292 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 15:01:45 +1200 Subject: [PATCH 03/11] bugpoint.cc: WIN32 exit signals --- passes/cmds/bugpoint.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 24c778fdb..06aae1885 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -20,6 +20,15 @@ #include "kernel/yosys.h" #include "backends/rtlil/rtlil_backend.h" +#if defined(_WIN32) +# define WIFEXITED(x) 1 +# define WIFSIGNALED(x) 0 +# define WIFSTOPPED(x) 0 +# define WEXITSTATUS(x) ((x) & 0xff) +# define WTERMSIG(x) SIGTERM +# define WSTOPSIG(x) 0 +#endif + USING_YOSYS_NAMESPACE using namespace RTLIL_BACKEND; PRIVATE_NAMESPACE_BEGIN From 107b768cddba1a2fdb8bfec1b4ffeeeaf6455be5 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 15:14:33 +1200 Subject: [PATCH 04/11] Add raise_error pass Raise errors from attributes for testing. I want it for bugpoint tests but it could be useful elsewhere. --- kernel/constids.inc | 1 + passes/tests/Makefile.inc | 1 + passes/tests/raise_error.cc | 61 +++++++++++++++++++++++++++++++++++++ tests/bugpoint/.gitignore | 2 ++ tests/bugpoint/err.ys | 27 ++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 passes/tests/raise_error.cc create mode 100644 tests/bugpoint/.gitignore create mode 100644 tests/bugpoint/err.ys diff --git a/kernel/constids.inc b/kernel/constids.inc index 4fdbb3dc8..df7b75269 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -284,3 +284,4 @@ X(A_WIDTHS) X(B_WIDTHS) X(C_WIDTHS) X(C_SIGNED) +X(raise_error) diff --git a/passes/tests/Makefile.inc b/passes/tests/Makefile.inc index 531943d78..25e11967c 100644 --- a/passes/tests/Makefile.inc +++ b/passes/tests/Makefile.inc @@ -2,4 +2,5 @@ OBJS += passes/tests/test_autotb.o OBJS += passes/tests/test_cell.o OBJS += passes/tests/test_abcloop.o +OBJS += passes/tests/raise_error.o diff --git a/passes/tests/raise_error.cc b/passes/tests/raise_error.cc new file mode 100644 index 000000000..edc42de65 --- /dev/null +++ b/passes/tests/raise_error.cc @@ -0,0 +1,61 @@ +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct RaiseErrorPass : public Pass { + RaiseErrorPass() : Pass("raise_error", "raise errors from attributes") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" raise_error [selection]\n"); + log("\n"); + log("Test error handling by raising arbitrary errors. This pass iterates over the\n"); + log("design (or selection of it) checking for objects with the 'raise_error'\n"); + log("attribute set.\n"); + log("\n"); + } + void execute(vector args, RTLIL::Design *design) override + { + log_header(design, "Executing RAISE_ERROR pass.\n"); + + extra_args(args, 1, design, true); + + RTLIL::NamedObject *err_obj = nullptr; + + for (auto mod : design->all_selected_modules()) { + if (mod->has_attribute(ID::raise_error)) { + err_obj = mod->clone(); + break; + } + for (auto memb : mod->selected_members()) { + if (memb->has_attribute(ID::raise_error)) { + err_obj = memb; + break; + } + } + if (err_obj != nullptr) break; + } + + if (err_obj != nullptr) { + log("Raising error from '%s'.\n", log_id(err_obj)); + auto err_no = err_obj->attributes[ID::raise_error].as_int(); + if (err_no < 256) { + log_flush(); + #if defined(_MSC_VER) + _exit(err_no); + #else + _Exit(err_no); + #endif + } else { + auto err_msg = err_obj->get_string_attribute(ID::raise_error); + log_error("%s\n", err_msg.c_str()); + } + } else { + log("'raise_error' attribute not found\n"); + } + } +} RaiseErrorPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/bugpoint/.gitignore b/tests/bugpoint/.gitignore new file mode 100644 index 000000000..072ed1097 --- /dev/null +++ b/tests/bugpoint/.gitignore @@ -0,0 +1,2 @@ +*.il +*.log \ No newline at end of file diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/err.ys new file mode 100644 index 000000000..d6a152144 --- /dev/null +++ b/tests/bugpoint/err.ys @@ -0,0 +1,27 @@ +read_verilog -noblackbox << EOF +(* raise_error=7 *) +module top(); +endmodule + +(* raise_error="help me" *) +module other(); +endmodule + +module zzy(); +endmodule +EOF +select -assert-mod-count 3 =* +design -stash read + +# raise_error with int exits with status +design -load read +bugpoint -yosys ../../yosys -command raise_error -expect-return 7 +select -assert-mod-count 1 =* +select -assert-mod-count 1 top + +# raise_error with string prints message +design -load read +rename top abc +bugpoint -yosys ../../yosys -command raise_error -grep "help me" +select -assert-mod-count 1 =* +select -assert-mod-count 1 other From b5c91c53a66b2e5aaa50c3ae14e33ca8ce5da4e0 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 17:05:17 +1200 Subject: [PATCH 05/11] raise_error.cc: Option for direct to stderr Add more to help text to describe usage. Add test for no value (should `exit(1)`). --- passes/tests/raise_error.cc | 40 ++++++++++++++++++++++++++++--------- tests/bugpoint/err.ys | 27 ++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/passes/tests/raise_error.cc b/passes/tests/raise_error.cc index edc42de65..f9055e6d2 100644 --- a/passes/tests/raise_error.cc +++ b/passes/tests/raise_error.cc @@ -9,18 +9,35 @@ struct RaiseErrorPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" raise_error [selection]\n"); + log(" raise_error [options] [selection]\n"); log("\n"); log("Test error handling by raising arbitrary errors. This pass iterates over the\n"); log("design (or selection of it) checking for objects with the 'raise_error'\n"); - log("attribute set.\n"); + log("attribute set. Assigning 'raise_error' to a string more than one character long\n"); + log("will log that string as an error message before exiting. Assigning 'raise_error'\n"); + log("to an integer (less than 256) will exit with that value as the exit code.\n"); + log("\n"); + log(" -stderr\n"); + log(" Log error messages directly to stderr instead of using 'log_error'.\n"); log("\n"); } void execute(vector args, RTLIL::Design *design) override { log_header(design, "Executing RAISE_ERROR pass.\n"); - extra_args(args, 1, design, true); + bool use_stderr = false; + + int argidx; + for (argidx = 1; argidx < GetSize(args); argidx++) + { + if (args[argidx] == "-stderr") { + use_stderr = true; + continue; + } + break; + } + + extra_args(args, argidx, design, true); RTLIL::NamedObject *err_obj = nullptr; @@ -43,15 +60,20 @@ struct RaiseErrorPass : public Pass { auto err_no = err_obj->attributes[ID::raise_error].as_int(); if (err_no < 256) { log_flush(); - #if defined(_MSC_VER) - _exit(err_no); - #else - _Exit(err_no); - #endif } else { auto err_msg = err_obj->get_string_attribute(ID::raise_error); - log_error("%s\n", err_msg.c_str()); + if (use_stderr) { + std::cerr << err_msg << std::endl; + err_no = 1; + } else { + log_error("%s\n", err_msg.c_str()); + } } + #if defined(_MSC_VER) + _exit(err_no); + #else + _Exit(err_no); + #endif } else { log("'raise_error' attribute not found\n"); } diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/err.ys index d6a152144..7b2fbcc81 100644 --- a/tests/bugpoint/err.ys +++ b/tests/bugpoint/err.ys @@ -7,7 +7,8 @@ endmodule module other(); endmodule -module zzy(); +(* raise_error *) +module def(); endmodule EOF select -assert-mod-count 3 =* @@ -25,3 +26,27 @@ rename top abc bugpoint -yosys ../../yosys -command raise_error -grep "help me" select -assert-mod-count 1 =* select -assert-mod-count 1 other + +# raise_error with no value exits with 1 +design -load read +rename def zzy +bugpoint -yosys ../../yosys -command raise_error -expect-return 1 +select -assert-mod-count 1 =* +select -assert-mod-count 1 zzy + +# raise_error -stderr exits with 1 +design -load read +rename top abc +delete def +bugpoint -yosys ../../yosys -command "raise_error -stderr" -expect-return 1 +select -assert-mod-count 1 =* +select -assert-mod-count 1 other + +#TODO +# raise_error -stderr prints to stderr +design -load read +rename top abc +delete def +# bugpoint -yosys ../../yosys -command "raise_error -stderr" -grep "help me" +# select -assert-mod-count 1 =* +# select -assert-mod-count 1 other From 2991be2a2d8fcc4a8781bf7b8ab54d2e9ba39697 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 13 May 2025 17:51:40 +1200 Subject: [PATCH 06/11] bugpoint: Add -greperr option `-greperr ` redirects stderr to 'bugpoint-case.err', and then searches that file for ``. Move `-runner` option up with the other options to reduce ambiguity (i.e. so it doesn't look like it's another design parts constraint). Also some shuffling of `err.ys`. --- passes/cmds/bugpoint.cc | 53 ++++++++++++++++++++++++++++----------- tests/bugpoint/.gitignore | 3 ++- tests/bugpoint/err.ys | 19 ++++---------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 06aae1885..11f6de35b 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -73,6 +73,13 @@ struct BugpointPass : public Pass { log(" finishing. produces smaller and more useful testcases, but may fail to\n"); log(" produce any testcase at all if the crash is related to dangling wires.\n"); log("\n"); + log(" -runner \"\"\n"); + log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); + log("\n"); + log(" -greperr \"\"\n"); + log(" only consider crashes that print this string on stderr. useful for\n"); + log(" errors outside of yosys.\n"); + log("\n"); log("It is possible to constrain which parts of the design will be considered for\n"); log("removal. Unless one or more of the following options are specified, all parts\n"); log("will be considered.\n"); @@ -106,12 +113,9 @@ struct BugpointPass : public Pass { log(" try to remove wires. wires with a (* bugpoint_keep *) attribute will be\n"); log(" skipped.\n"); log("\n"); - log(" -runner \"\"\n"); - log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); - log("\n"); } - int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg) + int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg, bool catch_err) { design->sort(); @@ -120,6 +124,7 @@ struct BugpointPass : public Pass { f.close(); string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str()); + if (catch_err) yosys_cmdline += " 2>bugpoint-case.err"; auto status = run_command(yosys_cmdline); // we're not processing lines, which means we're getting raw system() returns if(WIFEXITED(status)) @@ -132,7 +137,7 @@ struct BugpointPass : public Pass { return 0; } - bool check_logfile(string grep) + bool check_logfile(string grep, bool err=false) { if (grep.empty()) return true; @@ -140,7 +145,12 @@ struct BugpointPass : public Pass { if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') grep = grep.substr(1, grep.size() - 2); - std::ifstream f("bugpoint-case.log"); + std::ifstream f; + if (err) + f = std::ifstream("bugpoint-case.err"); + else + f = std::ifstream("bugpoint-case.log"); + while (!f.eof()) { string line; @@ -151,6 +161,11 @@ struct BugpointPass : public Pass { return false; } + bool check_logfiles(string grep, string greperr) + { + return check_logfile(grep) && check_logfile(greperr, true); + } + RTLIL::Design *clean_design(RTLIL::Design *design, bool do_clean = true, bool do_delete = false) { if (!do_clean) @@ -425,8 +440,8 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", yosys_arg, grep, runner; - bool flag_expect_return = false, has_check = false; + string yosys_cmd = "yosys", yosys_arg, grep, greperr, runner; + bool flag_expect_return = false, has_check = false, check_err = false; int expect_return_value = 0; bool fast = false, clean = false; bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; @@ -458,6 +473,12 @@ struct BugpointPass : public Pass { grep = args[++argidx]; continue; } + if (args[argidx] == "-greperr" && argidx + 1 < args.size()) { + has_check = true; + check_err = true; + greperr = args[++argidx]; + continue; + } if (args[argidx] == "-expect-return") { flag_expect_return = true; ++argidx; @@ -549,13 +570,15 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg); + int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg, check_err); if (flag_expect_return && retval != expect_return_value) log_cmd_error("The provided script file or command and Yosys binary returned value %d instead of expected %d on this design!\n", retval, expect_return_value); if (!flag_expect_return && retval == 0) log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); + if (!check_logfile(greperr, true)) + log_cmd_error("The provided grep string is not found in stderr log!\n"); int seed = 0; bool found_something = false, stage2 = false; @@ -568,30 +591,30 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg); + retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg, check_err); delete testcase; } else { - retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg); + retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg, check_err); } bool crashes = false; - if (flag_expect_return && retval == expect_return_value && check_logfile(grep)) + if (flag_expect_return && retval == expect_return_value && check_logfiles(grep, greperr)) { log("Testcase matches expected crash.\n"); crashes = true; } else if (!flag_expect_return && retval == 0) log("Testcase does not crash.\n"); - else if (!flag_expect_return && check_logfile(grep)) + else if (!flag_expect_return && check_logfiles(grep, greperr)) { log("Testcase crashes.\n"); crashes = true; } else - // flag_expect_return && !(retval == expect_return_value && check_logfile(grep)) - // !flag_expect_return && !(retval == 0 && check_logfile(grep)) + // flag_expect_return && !(retval == expect_return_value && check_logfiles(grep, greperr)) + // !flag_expect_return && !(retval == 0 && check_logfiles(grep, greperr)) log("Testcase does not match expected crash.\n"); if (crashes) diff --git a/tests/bugpoint/.gitignore b/tests/bugpoint/.gitignore index 072ed1097..818575593 100644 --- a/tests/bugpoint/.gitignore +++ b/tests/bugpoint/.gitignore @@ -1,2 +1,3 @@ *.il -*.log \ No newline at end of file +*.log +*.err diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/err.ys index 7b2fbcc81..c74e34b19 100644 --- a/tests/bugpoint/err.ys +++ b/tests/bugpoint/err.ys @@ -20,33 +20,24 @@ bugpoint -yosys ../../yosys -command raise_error -expect-return 7 select -assert-mod-count 1 =* select -assert-mod-count 1 top -# raise_error with string prints message +# raise_error with string prints message and exits with 1 design -load read rename top abc -bugpoint -yosys ../../yosys -command raise_error -grep "help me" +bugpoint -yosys ../../yosys -command raise_error -grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other # raise_error with no value exits with 1 design -load read rename def zzy +delete other bugpoint -yosys ../../yosys -command raise_error -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 zzy -# raise_error -stderr exits with 1 +# raise_error -stderr prints to stderr and exits with 1 design -load read rename top abc -delete def -bugpoint -yosys ../../yosys -command "raise_error -stderr" -expect-return 1 +bugpoint -yosys ../../yosys -command "raise_error -stderr" -greperr "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other - -#TODO -# raise_error -stderr prints to stderr -design -load read -rename top abc -delete def -# bugpoint -yosys ../../yosys -command "raise_error -stderr" -grep "help me" -# select -assert-mod-count 1 =* -# select -assert-mod-count 1 other From aa03da56cb8b0b98864269c4f88de6f135831b74 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 14 May 2025 10:06:06 +1200 Subject: [PATCH 07/11] bugpoint.cc: Include csignal for windows --- passes/cmds/bugpoint.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 11f6de35b..101d82bd6 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -21,6 +21,7 @@ #include "backends/rtlil/rtlil_backend.h" #if defined(_WIN32) +# include # define WIFEXITED(x) 1 # define WIFSIGNALED(x) 0 # define WIFSTOPPED(x) 0 From 65a5227c144887b74e3ab481e6416fe6089bab8e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 14 May 2025 10:19:06 +1200 Subject: [PATCH 08/11] bugpoint.cc: Rename to -err_grep --- passes/cmds/bugpoint.cc | 22 +++++++++++----------- tests/bugpoint/err.ys | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 101d82bd6..f740c2bcd 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -77,7 +77,7 @@ struct BugpointPass : public Pass { log(" -runner \"\"\n"); log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); log("\n"); - log(" -greperr \"\"\n"); + log(" -err_grep \"\"\n"); log(" only consider crashes that print this string on stderr. useful for\n"); log(" errors outside of yosys.\n"); log("\n"); @@ -162,9 +162,9 @@ struct BugpointPass : public Pass { return false; } - bool check_logfiles(string grep, string greperr) + bool check_logfiles(string grep, string err_grep) { - return check_logfile(grep) && check_logfile(greperr, true); + return check_logfile(grep) && check_logfile(err_grep, true); } RTLIL::Design *clean_design(RTLIL::Design *design, bool do_clean = true, bool do_delete = false) @@ -441,7 +441,7 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", yosys_arg, grep, greperr, runner; + string yosys_cmd = "yosys", yosys_arg, grep, err_grep, runner; bool flag_expect_return = false, has_check = false, check_err = false; int expect_return_value = 0; bool fast = false, clean = false; @@ -474,10 +474,10 @@ struct BugpointPass : public Pass { grep = args[++argidx]; continue; } - if (args[argidx] == "-greperr" && argidx + 1 < args.size()) { + if (args[argidx] == "-err_grep" && argidx + 1 < args.size()) { has_check = true; check_err = true; - greperr = args[++argidx]; + err_grep = args[++argidx]; continue; } if (args[argidx] == "-expect-return") { @@ -578,7 +578,7 @@ struct BugpointPass : public Pass { log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); - if (!check_logfile(greperr, true)) + if (!check_logfile(err_grep, true)) log_cmd_error("The provided grep string is not found in stderr log!\n"); int seed = 0; @@ -601,21 +601,21 @@ struct BugpointPass : public Pass { } bool crashes = false; - if (flag_expect_return && retval == expect_return_value && check_logfiles(grep, greperr)) + if (flag_expect_return && retval == expect_return_value && check_logfiles(grep, err_grep)) { log("Testcase matches expected crash.\n"); crashes = true; } else if (!flag_expect_return && retval == 0) log("Testcase does not crash.\n"); - else if (!flag_expect_return && check_logfiles(grep, greperr)) + else if (!flag_expect_return && check_logfiles(grep, err_grep)) { log("Testcase crashes.\n"); crashes = true; } else - // flag_expect_return && !(retval == expect_return_value && check_logfiles(grep, greperr)) - // !flag_expect_return && !(retval == 0 && check_logfiles(grep, greperr)) + // flag_expect_return && !(retval == expect_return_value && check_logfiles(grep, err_grep)) + // !flag_expect_return && !(retval == 0 && check_logfiles(grep, err_grep)) log("Testcase does not match expected crash.\n"); if (crashes) diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/err.ys index c74e34b19..08bf0a9c7 100644 --- a/tests/bugpoint/err.ys +++ b/tests/bugpoint/err.ys @@ -38,6 +38,6 @@ select -assert-mod-count 1 zzy # raise_error -stderr prints to stderr and exits with 1 design -load read rename top abc -bugpoint -yosys ../../yosys -command "raise_error -stderr" -greperr "help me" -expect-return 1 +bugpoint -yosys ../../yosys -command "raise_error -stderr" -err_grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other From ded51e7622a26e3b7e9880a049a77beacbf3badf Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 16 May 2025 14:12:38 +1200 Subject: [PATCH 09/11] tests: Add bugpoint to MK_TEST_DIRS Also change `-err_grep` to `-err-grep` for consistency with `-expect-return`. --- Makefile | 1 + passes/cmds/bugpoint.cc | 4 ++-- tests/bugpoint/err.ys | 2 +- tests/bugpoint/run-test.sh | 4 ++++ 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100755 tests/bugpoint/run-test.sh diff --git a/Makefile b/Makefile index fb0ad0e37..1f8a47470 100644 --- a/Makefile +++ b/Makefile @@ -866,6 +866,7 @@ MK_TEST_DIRS += tests/arch/nexus MK_TEST_DIRS += tests/arch/quicklogic/pp3 MK_TEST_DIRS += tests/arch/quicklogic/qlf_k6n10f MK_TEST_DIRS += tests/arch/xilinx +MK_TEST_DIRS += tests/bugpoint MK_TEST_DIRS += tests/opt MK_TEST_DIRS += tests/sat MK_TEST_DIRS += tests/sim diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index f740c2bcd..683430372 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -77,7 +77,7 @@ struct BugpointPass : public Pass { log(" -runner \"\"\n"); log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); log("\n"); - log(" -err_grep \"\"\n"); + log(" -err-grep \"\"\n"); log(" only consider crashes that print this string on stderr. useful for\n"); log(" errors outside of yosys.\n"); log("\n"); @@ -474,7 +474,7 @@ struct BugpointPass : public Pass { grep = args[++argidx]; continue; } - if (args[argidx] == "-err_grep" && argidx + 1 < args.size()) { + if (args[argidx] == "-err-grep" && argidx + 1 < args.size()) { has_check = true; check_err = true; err_grep = args[++argidx]; diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/err.ys index 08bf0a9c7..42e84241c 100644 --- a/tests/bugpoint/err.ys +++ b/tests/bugpoint/err.ys @@ -38,6 +38,6 @@ select -assert-mod-count 1 zzy # raise_error -stderr prints to stderr and exits with 1 design -load read rename top abc -bugpoint -yosys ../../yosys -command "raise_error -stderr" -err_grep "help me" -expect-return 1 +bugpoint -yosys ../../yosys -command "raise_error -stderr" -err-grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other diff --git a/tests/bugpoint/run-test.sh b/tests/bugpoint/run-test.sh new file mode 100755 index 000000000..006c731e3 --- /dev/null +++ b/tests/bugpoint/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../gen-tests-makefile.sh +generate_mk --yosys-scripts From 2d8fa9fbefdc2094988edcee887522fdc4656af8 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 16 May 2025 16:51:48 +1200 Subject: [PATCH 10/11] bugpoint: Add -suffix option Allows for adding a suffix to the `bugpoint-case` file name so that multiple `bugpoint`s can run in the same directory, e.g. during a `make test -j4`. --- passes/cmds/bugpoint.cc | 61 ++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 683430372..08dc76dda 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -81,6 +81,10 @@ struct BugpointPass : public Pass { log(" only consider crashes that print this string on stderr. useful for\n"); log(" errors outside of yosys.\n"); log("\n"); + log(" -suffix \"\"\n"); + log(" add suffix to generated file names. useful when running more than one\n"); + log(" instance of bugpoint in the same directory. limited to 8 characters.\n"); + log("\n"); log("It is possible to constrain which parts of the design will be considered for\n"); log("removal. Unless one or more of the following options are specified, all parts\n"); log("will be considered.\n"); @@ -116,16 +120,20 @@ struct BugpointPass : public Pass { log("\n"); } - int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg, bool catch_err) + int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg, string suffix, bool catch_err) { design->sort(); - std::ofstream f("bugpoint-case.il"); + string bugpoint_file = "bugpoint-case"; + if (suffix.size()) + bugpoint_file += stringf(".%.8s", suffix.c_str()); + + std::ofstream f(bugpoint_file + ".il"); RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); - string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str()); - if (catch_err) yosys_cmdline += " 2>bugpoint-case.err"; + string yosys_cmdline = stringf("%s %s -qq -L %s.log %s %s.il", runner.c_str(), yosys_cmd.c_str(), bugpoint_file.c_str(), yosys_arg.c_str(), bugpoint_file.c_str()); + if (catch_err) yosys_cmdline += stringf(" 2>%s.err", bugpoint_file.c_str()); auto status = run_command(yosys_cmdline); // we're not processing lines, which means we're getting raw system() returns if(WIFEXITED(status)) @@ -138,7 +146,7 @@ struct BugpointPass : public Pass { return 0; } - bool check_logfile(string grep, bool err=false) + bool check_logfile(string grep, string suffix, bool err=false) { if (grep.empty()) return true; @@ -146,11 +154,12 @@ struct BugpointPass : public Pass { if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') grep = grep.substr(1, grep.size() - 2); - std::ifstream f; - if (err) - f = std::ifstream("bugpoint-case.err"); - else - f = std::ifstream("bugpoint-case.log"); + string bugpoint_file = "bugpoint-case"; + if (suffix.size()) + bugpoint_file += stringf(".%.8s", suffix.c_str()); + bugpoint_file += err ? ".err" : ".log"; + + std::ifstream f(bugpoint_file); while (!f.eof()) { @@ -162,9 +171,9 @@ struct BugpointPass : public Pass { return false; } - bool check_logfiles(string grep, string err_grep) + bool check_logfiles(string grep, string err_grep, string suffix) { - return check_logfile(grep) && check_logfile(err_grep, true); + return check_logfile(grep, suffix) && check_logfile(err_grep, suffix, true); } RTLIL::Design *clean_design(RTLIL::Design *design, bool do_clean = true, bool do_delete = false) @@ -441,7 +450,7 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", yosys_arg, grep, err_grep, runner; + string yosys_cmd = "yosys", yosys_arg, grep, err_grep, runner, suffix; bool flag_expect_return = false, has_check = false, check_err = false; int expect_return_value = 0; bool fast = false, clean = false; @@ -545,6 +554,14 @@ struct BugpointPass : public Pass { } continue; } + if (args[argidx] == "-suffix" && argidx + 1 < args.size()) { + suffix = args[++argidx]; + if (suffix.size() && suffix.at(0) == '"') { + log_assert(suffix.back() == '"'); + suffix = suffix.substr(1, suffix.size() - 2); + } + continue; + } break; } extra_args(args, argidx, design); @@ -571,14 +588,14 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg, check_err); + int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg, suffix, check_err); if (flag_expect_return && retval != expect_return_value) log_cmd_error("The provided script file or command and Yosys binary returned value %d instead of expected %d on this design!\n", retval, expect_return_value); if (!flag_expect_return && retval == 0) log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); - if (!check_logfile(grep)) + if (!check_logfile(grep, suffix)) log_cmd_error("The provided grep string is not found in the log file!\n"); - if (!check_logfile(err_grep, true)) + if (!check_logfile(err_grep, suffix, true)) log_cmd_error("The provided grep string is not found in stderr log!\n"); int seed = 0; @@ -592,30 +609,30 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg, check_err); + retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg, suffix, check_err); delete testcase; } else { - retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg, check_err); + retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg, suffix, check_err); } bool crashes = false; - if (flag_expect_return && retval == expect_return_value && check_logfiles(grep, err_grep)) + if (flag_expect_return && retval == expect_return_value && check_logfiles(grep, err_grep, suffix)) { log("Testcase matches expected crash.\n"); crashes = true; } else if (!flag_expect_return && retval == 0) log("Testcase does not crash.\n"); - else if (!flag_expect_return && check_logfiles(grep, err_grep)) + else if (!flag_expect_return && check_logfiles(grep, err_grep, suffix)) { log("Testcase crashes.\n"); crashes = true; } else - // flag_expect_return && !(retval == expect_return_value && check_logfiles(grep, err_grep)) - // !flag_expect_return && !(retval == 0 && check_logfiles(grep, err_grep)) + // flag_expect_return && !(retval == expect_return_value && check_logfiles(grep, err_grep, suffix)) + // !flag_expect_return && !(retval == 0 && check_logfiles(grep, err_grep, suffix)) log("Testcase does not match expected crash.\n"); if (crashes) From 20b0ab26b1d26b3a50a50640197b9e3ea874dffb Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 16 May 2025 16:55:54 +1200 Subject: [PATCH 11/11] tests/bugpoint: More tests More coverage. --- tests/bugpoint/.gitignore | 4 +- tests/bugpoint/failures.ys | 29 ++++++++ tests/bugpoint/mod_constraints.ys | 83 +++++++++++++++++++++++ tests/bugpoint/mods.il | 38 +++++++++++ tests/bugpoint/proc_constraints.ys | 49 +++++++++++++ tests/bugpoint/procs.il | 42 ++++++++++++ tests/bugpoint/{err.ys => raise_error.ys} | 8 +-- 7 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 tests/bugpoint/failures.ys create mode 100644 tests/bugpoint/mod_constraints.ys create mode 100644 tests/bugpoint/mods.il create mode 100644 tests/bugpoint/proc_constraints.ys create mode 100644 tests/bugpoint/procs.il rename tests/bugpoint/{err.ys => raise_error.ys} (71%) diff --git a/tests/bugpoint/.gitignore b/tests/bugpoint/.gitignore index 818575593..1012c66cc 100644 --- a/tests/bugpoint/.gitignore +++ b/tests/bugpoint/.gitignore @@ -1,3 +1,5 @@ -*.il +bugpoint-case.* *.log *.err +*.temp +run-test.mk diff --git a/tests/bugpoint/failures.ys b/tests/bugpoint/failures.ys new file mode 100644 index 000000000..ce8daa8cc --- /dev/null +++ b/tests/bugpoint/failures.ys @@ -0,0 +1,29 @@ +write_file fail.temp << EOF +logger -expect error "Missing -script or -command option." 1 +bugpoint -suffix fail -yosys ../../yosys +EOF +exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp + +write_file fail.temp << EOF +logger -expect error "do not crash on this design" 1 +bugpoint -suffix fail -yosys ../../yosys -command "dump" +EOF +exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp + +write_file fail.temp << EOF +logger -expect error "returned value 3 instead of expected 7" 1 +bugpoint -suffix fail -yosys ../../yosys -command raise_error -expect-return 7 +EOF +exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp + +write_file fail.temp << EOF +logger -expect error "not found in the log file!" 1 +bugpoint -suffix fail -yosys ../../yosys -command raise_error -grep "nope" +EOF +exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp + +write_file fail.temp << EOF +logger -expect error "not found in stderr log!" 1 +bugpoint -suffix fail -yosys ../../yosys -command raise_error -err-grep "nope" +EOF +exec -expect-return 0 -- ../../yosys -qq mods.il -s fail.temp diff --git a/tests/bugpoint/mod_constraints.ys b/tests/bugpoint/mod_constraints.ys new file mode 100644 index 000000000..f35095510 --- /dev/null +++ b/tests/bugpoint/mod_constraints.ys @@ -0,0 +1,83 @@ +read_rtlil mods.il +select -assert-count 7 w:* +select -assert-mod-count 3 =* +select -assert-count 4 c:* +design -stash base + +# everything is removed by default +design -load base +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +select -assert-count 1 w:* +select -assert-mod-count 1 =* +select -assert-none c:* + +# don't remove wires +design -load base +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -modules -cells +select -assert-count 3 w:* +select -assert-mod-count 1 =* +select -assert-none c:* + +# don't remove cells or their connections +design -load base +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -modules +select -assert-count 5 w:* +select -assert-mod-count 1 =* +select -assert-count 4 c:* + +# don't remove cells but do remove their connections +design -load base +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -modules -connections +select -assert-count 1 w:* +select -assert-mod-count 1 =* +select -assert-count 4 c:* + +# don't remove modules +design -load base +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 -wires -cells +select -assert-count 1 w:* +select -assert-mod-count 3 =* +select -assert-none c:* + +# can keep wires +design -load base +setattr -set bugpoint_keep 1 w:w_b +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +select -assert-count 2 w:* +select -assert-mod-count 1 =* +select -assert-none c:* + +# a wire with keep won't keep the cell/module containing it +design -load base +setattr -set bugpoint_keep 1 w:w_o +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +select -assert-count 1 w:* +select -assert-mod-count 1 =* +select -assert-none c:* + +# can keep cells (and do it without the associated module) +design -load base +setattr -set bugpoint_keep 1 c:c_a +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +select -assert-count 1 w:* +select -assert-mod-count 1 =* +select -assert-count 1 c:* + +# can keep modules +design -load base +setattr -mod -set bugpoint_keep 1 m_a +bugpoint -suffix mods -yosys ../../yosys -command raise_error -expect-return 3 +select -assert-count 1 w:* +select -assert-mod-count 2 =* +select -assert-none c:* + +# minimize to just the path connecting w_a and w_c +# which happens via w_b, w_i, w_o, m_a, c_a and c_b +write_file script.temp << EOF +select -assert-none w:w_a %co* w:w_c %ci* %i +EOF +design -load base +bugpoint -suffix mods -yosys ../../yosys -script script.temp -grep "Assertion failed" +select -assert-count 5 w:* +select -assert-mod-count 2 =* +select -assert-count 2 c:* diff --git a/tests/bugpoint/mods.il b/tests/bugpoint/mods.il new file mode 100644 index 000000000..fe3ce6522 --- /dev/null +++ b/tests/bugpoint/mods.il @@ -0,0 +1,38 @@ +module \m_a + wire input 1 \w_i + wire output 2 \w_o + connect \w_o \w_i +end + +module \m_b + wire input 1 \w_i + wire output 2 \w_o +end + +attribute \top 1 +module \top + attribute \raise_error 3 + wire \w_a + wire \w_b + wire \w_c + + cell \m_a \c_a + connect \w_i \w_a + connect \w_o \w_b + end + + cell \m_a \c_b + connect \w_i \w_b + connect \w_o \w_c + end + + cell \m_b \c_c + connect \w_i \w_c + connect \w_o \w_a + end + + cell \m_b \c_d + connect \w_i 1'0 + connect \w_o 1'1 + end +end diff --git a/tests/bugpoint/proc_constraints.ys b/tests/bugpoint/proc_constraints.ys new file mode 100644 index 000000000..22b8b3c60 --- /dev/null +++ b/tests/bugpoint/proc_constraints.ys @@ -0,0 +1,49 @@ +read_rtlil procs.il +select -assert-count 2 p:* +design -stash err_q + +# processes get removed by default +design -load err_q +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 +select -assert-none p:* + +# individual processes can be kept +design -load err_q +setattr -set bugpoint_keep 1 p:proc_a +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 +select -assert-count 1 p:* + +# all processes can be kept +design -load err_q +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -wires +select -assert-count 2 p:* + +# d and clock are connected after proc +design -load err_q +proc +select -assert-count 3 w:d %co +select -assert-count 3 w:clock %co + +# no assigns means no d +design -load err_q +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -assigns +proc +select -assert-count 1 w:d %co + +# no updates means no clock +design -load err_q +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -updates +proc +select -assert-count 1 w:clock %co + +# can remove ports +design -load err_q +select -assert-count 5 x:* +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -ports +select -assert-none x:* + +# can keep ports +design -load err_q +setattr -set bugpoint_keep 1 i:d o:q +bugpoint -suffix procs -yosys ../../yosys -command raise_error -expect-return 4 -ports +select -assert-count 2 x:* diff --git a/tests/bugpoint/procs.il b/tests/bugpoint/procs.il new file mode 100644 index 000000000..cb9f7c8dd --- /dev/null +++ b/tests/bugpoint/procs.il @@ -0,0 +1,42 @@ +module \ff_with_en_and_sync_reset + wire $0\q[1:1] + wire $0\q[0:0] + attribute \raise_error 4 + wire width 2 output 5 \q + wire width 2 input 4 \d + wire input 3 \enable + wire input 2 \reset + wire input 1 \clock + + process \proc_a + assign $0\q[0:0] \q [0] + switch \reset + case 1'1 + assign $0\q[0:0] 1'0 + case + switch \enable + case 1'1 + assign $0\q[0:0] \d [0] + case + end + end + sync posedge \clock + update \q [0] $0\q[0:0] + end + + process \proc_b + assign $0\q[1:1] \q [1] + switch \reset + case 1'1 + assign $0\q[1:1] 1'0 + case + switch \enable + case 1'1 + assign $0\q[1:1] \d [1] + case + end + end + sync posedge \clock + update \q [1] $0\q[1:1] + end +end diff --git a/tests/bugpoint/err.ys b/tests/bugpoint/raise_error.ys similarity index 71% rename from tests/bugpoint/err.ys rename to tests/bugpoint/raise_error.ys index 42e84241c..a0a03f447 100644 --- a/tests/bugpoint/err.ys +++ b/tests/bugpoint/raise_error.ys @@ -16,14 +16,14 @@ design -stash read # raise_error with int exits with status design -load read -bugpoint -yosys ../../yosys -command raise_error -expect-return 7 +bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 7 select -assert-mod-count 1 =* select -assert-mod-count 1 top # raise_error with string prints message and exits with 1 design -load read rename top abc -bugpoint -yosys ../../yosys -command raise_error -grep "help me" -expect-return 1 +bugpoint -suffix error -yosys ../../yosys -command raise_error -grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other @@ -31,13 +31,13 @@ select -assert-mod-count 1 other design -load read rename def zzy delete other -bugpoint -yosys ../../yosys -command raise_error -expect-return 1 +bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 zzy # raise_error -stderr prints to stderr and exits with 1 design -load read rename top abc -bugpoint -yosys ../../yosys -command "raise_error -stderr" -err-grep "help me" -expect-return 1 +bugpoint -suffix error -yosys ../../yosys -command "raise_error -stderr" -err-grep "help me" -expect-return 1 select -assert-mod-count 1 =* select -assert-mod-count 1 other