diff --git a/docs/examples/autotune/README.md b/docs/examples/autotune/README.md
new file mode 100644
index 0000000..3cdadb7
--- /dev/null
+++ b/docs/examples/autotune/README.md
@@ -0,0 +1,30 @@
+# Autotune demo
+
+This directory contains a simple sequential integer divider circuit. The
+verilog implementation in [divider.sv](divider.sv) comes with assertions that
+this circuit will always produce the correct result and will always finish
+within a fixed number of cycles. The circuit has the divider bit-width as
+parameter.
+
+Increasing the WIDTH parameter quickly turns proving those assertions into a
+very difficult proof for fully autmated solvers. This makes it a good example
+for the `--autotune` option which tries different backend engines to find the
+best performing engine configuration for a given verification task.
+
+The [divider.sby](divider.sby) file defines 3 tasks named `small`, `medium` and
+`large` which configure the divider with different bit-widths. To verify the
+`small` divider using the default engine run:
+
+    sby -f divider.sby small
+
+To automatically try different backend engines using autotune, run
+
+    sby --autotune -f divider.sby small
+
+The `small` task should finish quickly using both the default engine and using
+autotune. The `medium` and `large` tasks take significantly longer and show
+greater differences between engine configurations. Note that the `large` tasks
+can take many minutes to hours, depending on the machine you are using.
+
+You can learn more about Sby's autotune feature from [Sby's
+documentation](https://symbiyosys.readthedocs.io/en/latest/autotune.html).
diff --git a/docs/examples/autotune/divider.sby b/docs/examples/autotune/divider.sby
new file mode 100644
index 0000000..61bed9a
--- /dev/null
+++ b/docs/examples/autotune/divider.sby
@@ -0,0 +1,24 @@
+[tasks]
+small default
+medium
+large
+
+[options]
+mode prove
+small: depth 11
+medium: depth 15
+large: depth 19
+
+[engines]
+smtbmc
+
+[script]
+small: read -define WIDTH=8
+medium: read -define WIDTH=12
+large: read -define WIDTH=16
+
+read -formal divider.sv
+prep -top divider
+
+[files]
+divider.sv
diff --git a/docs/examples/autotune/divider.sv b/docs/examples/autotune/divider.sv
new file mode 100644
index 0000000..b2ec2ad
--- /dev/null
+++ b/docs/examples/autotune/divider.sv
@@ -0,0 +1,85 @@
+`ifndef WIDTH
+`define WIDTH 4
+`endif
+
+module divider #(
+    parameter WIDTH=`WIDTH
+) (
+    input wire clk,
+    input wire start,
+    input wire [WIDTH-1:0] dividend,
+    input wire [WIDTH-1:0] divisor,
+
+    output reg done,
+    output reg [WIDTH-1:0] quotient,
+    output wire [WIDTH-1:0] remainder
+);
+
+    reg [WIDTH-1:0] acc;
+
+    reg [WIDTH*2-1:0] sub;
+    reg [WIDTH-1:0] pos;
+
+    assign remainder = acc;
+
+    always @(posedge clk) begin
+        if (start) begin
+            acc <= dividend;
+            quotient <= 0;
+            sub <= divisor << (WIDTH - 1);
+            pos <= 1 << (WIDTH - 1);
+            done <= 0;
+        end else if (!done) begin
+            if (acc >= sub) begin
+                acc <= acc - sub[WIDTH-1:0];
+                quotient <= quotient + pos;
+            end
+
+            sub <= sub >> 1;
+            {pos, done} <= pos;
+        end
+    end
+
+
+`ifdef FORMAL
+    reg [WIDTH-1:0] start_dividend = 0;
+    reg [WIDTH-1:0] start_divisor = 0;
+
+    reg started = 0;
+    reg finished = 0;
+    reg [$clog2(WIDTH + 1):0] counter = 0;
+
+    always @(posedge clk) begin
+        // Bound the number of cycles until the result is ready
+        assert (counter <= WIDTH);
+
+        if (started) begin
+            if (finished || done) begin
+                finished <= 1;
+                // Make sure result stays until we start a new division
+                assert (done);
+
+                // Check the result
+                if (start_divisor == 0) begin
+                    assert (&quotient);
+                    assert (remainder == start_dividend);
+                end else begin
+                    assert (quotient == start_dividend / start_divisor);
+                    assert (remainder == start_dividend % start_divisor);
+                end
+            end else begin
+                counter <= counter + 1'b1;
+            end
+        end
+
+        // Track the requested inputs
+        if (start) begin
+            start_divisor <= divisor;
+            start_dividend <= dividend;
+            started <= 1;
+            counter <= 0;
+            finished <= 0;
+        end
+    end
+`endif
+endmodule
diff --git a/docs/source/autotune.rst b/docs/source/autotune.rst
index 6fab860..909b838 100644
--- a/docs/source/autotune.rst
+++ b/docs/source/autotune.rst
@@ -3,7 +3,7 @@ Autotune: Automatic Engine Selection
 
 Selecting the best performing engine for a given verification task often
 requires some amount of trial and error. To reduce the manual work required for
-this, sby offers the ``--autotune`` option which takes an ``.sby`` file and
+this, sby offers the ``--autotune`` option. This takes an ``.sby`` file and
 runs it using engines and engine configurations. At the end it produces a
 report listing the fastest engines among these candidates.
 
@@ -11,15 +11,15 @@ Using Autotune
 --------------
 
 To run autotune, you can add the ``--autotune`` option to your usual sby
-invokation. For example if you usually run ``sby demo.sby`` you would run ``sby
---autotune demo.sby`` instead. When the ``.sby`` file contains multiple tasks,
-autotune is run for each task independently. As without ``--autotune``, it is
-possible to specify which tasks to run on the command line.
+invocation. For example, if you usually run ``sby demo.sby`` you would run
+``sby --autotune demo.sby`` instead. When the ``.sby`` file contains multiple
+tasks, autotune is run for each task independently. As without ``--autotune``,
+it is possible to specify which tasks to run on the command line.
 
-Autotune runs without requiring further interaction and will eventually print a
+Autotune runs without requiring further interaction, and will eventually print a
 list of engine configurations and their respective solving times. To
-permanently use an engine configuration you can copy if from the ``sby
---autotune`` output into the ``[engines]`` section of your ``.sby`` file.
+permanently use an engine configuration you can copy it from the
+``sby --autotune`` output into the ``[engines]`` section of your ``.sby`` file.
 
 Autotune Log Output
 -------------------
@@ -37,9 +37,9 @@ once and will be reused to run every candidate engine.
    SBY [demo] base: finished (returncode=0)
    SBY [demo] prepared model 'base'
 
-This is followed by selecting the engine candidates to run. For this the design
+This is followed by selecting the engine candidates to run. The design
 and sby configuration are analyzed to skip engines that are not compatible or
-unlikely to work well. When engines is skipped due to a recommendation, a
+unlikely to work well. When an engine is skipped due to a recommendation, a
 corresponding log message is displayed as well as the total number of
 candidates to try:
 
@@ -49,7 +49,7 @@ candidates to try:
    SBY [demo] testing 16 engine configurations...
 
 After this, the candidate engine configurations are started. Depending on the
-configuration engines can run in parallel. The engine output itself is not
+configuration, engines can run in parallel. The engine output itself is not
 logged to stdout when running autotune, so you will only see messages about
 starting an engine:
 
@@ -77,7 +77,7 @@ be interspersed with other log output.
    SBY [demo] smt2: finished (returncode=0)
    SBY [demo] prepared model 'smt2'
 
-Whenever an engine finishes a log message is printed:
+Whenever an engine finishes, a log message is printed:
 
 .. code-block:: text
 
@@ -91,7 +91,7 @@ When an engine takes longer than the current hard timeout, it is stopped:
    SBY [demo] engine_2 (smtbmc bitwuzla): timeout (150 seconds)
 
 Depending on the configuration, autotune will also stop an engine earlier when
-reaching a soft timeout. In that case, when no other engine finishes in less
+reaching a soft timeout. If no other engine finishes in less
 time, the engine will be retried later with a longer soft timeout:
 
 .. code-block:: text
@@ -99,7 +99,7 @@ time, the engine will be retried later with a longer soft timeout:
    SBY [demo] engine_0 (smtbmc boolector): timeout (60 seconds, will be retried if necessary)
 
 
-Finally at the end a summary of all finished engines is printed, sorted by
+Finally, a summary of all finished engines is printed, sorted by
 their solving time:
 
 .. code-block:: text
@@ -112,8 +112,8 @@ their solving time:
 
 If any tried engine encounters an error or produces an unexpected result,
 autotune will also output a list of failed engines. Note that when the sby file
-does not contain the ``expect`` option, autotune defaults to ``expect
-pass,fail`` to simplify running autotune on a verification task with a
+does not contain the ``expect`` option, autotune defaults to
+``expect pass,fail`` to simplify running autotune on a verification task with a
 currently unknown outcome.
 
 Configuring Autotune
@@ -121,7 +121,7 @@ Configuring Autotune
 
 Autotune can be configured by adding an ``[autotune]`` section to the ``.sby``
 file. Each line in that section has the form ``option_name value``, the
-possible options and their supported values are described below. In addition
+possible options and their supported values are described below. In addition,
 the ``--autotune-config`` command line option can be used to specify a file
 containing further autotune options, using the same syntax. When both are used,
 the command line option takes precedence. This makes it easy to run autotune
diff --git a/sbysrc/sby.py b/sbysrc/sby.py
index b802b7a..0628c6d 100644
--- a/sbysrc/sby.py
+++ b/sbysrc/sby.py
@@ -402,6 +402,8 @@ if (workdir is not None) and (len(tasknames) != 1):
     sys.exit(1)
 
 def run_task(taskname):
+    sbyconfig, _, _, _ = read_sbyconfig(sbydata, taskname)
+
     my_opt_tmpdir = opt_tmpdir
     my_workdir = None
 
@@ -461,7 +463,6 @@ def run_task(taskname):
     else:
         junit_filename = "junit"
 
-    sbyconfig, _, _, _ = read_sbyconfig(sbydata, taskname)
     task = SbyTask(sbyconfig, my_workdir, early_logmsgs, reusedir)
 
     for k, v in exe_paths.items():
diff --git a/sbysrc/sby_core.py b/sbysrc/sby_core.py
index 6be86a0..3462c36 100644
--- a/sbysrc/sby_core.py
+++ b/sbysrc/sby_core.py
@@ -176,13 +176,57 @@ class SbyProc:
                 fcntl.fcntl(self.p.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
 
             else:
-                self.p = subprocess.Popen(self.cmdline, shell=True, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
+                self.p = subprocess.Popen(self.cmdline + " & exit !errorlevel!", shell=True, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
                         stderr=(subprocess.STDOUT if self.logstderr else None))
 
             self.task.update_proc_running(self)
             self.running = True
             return
 
+        self.read_output()
+
+        if self.p.poll() is not None:
+            # The process might have written something since the last time we checked
+            self.read_output()
+
+            if not self.silent:
+                self.task.log(f"{self.info}: finished (returncode={self.p.returncode})")
+            self.task.update_proc_stopped(self)
+            self.running = False
+            self.exited = True
+
+            if os.name == "nt":
+                if self.p.returncode == 9009:
+                    returncode = 127
+                else:
+                    returncode = self.p.returncode & 0xff
+            else:
+                returncode = self.p.returncode
+
+            if returncode == 127:
+                if not self.silent:
+                    self.task.log(f"{self.info}: COMMAND NOT FOUND. ERROR.")
+                self.handle_error(returncode)
+                self.terminated = True
+                self.task.proc_failed(self)
+                return
+
+            if self.checkretcode and returncode not in self.retcodes:
+                if not self.silent:
+                    self.task.log(f"{self.info}: task failed. ERROR.")
+                self.handle_error(returncode)
+                self.terminated = True
+                self.task.proc_failed(self)
+                return
+
+            self.handle_exit(returncode)
+
+            self.finished = True
+            for next_proc in self.notify:
+                next_proc.poll()
+            return
+
+    def read_output(self):
         while True:
             outs = self.p.stdout.readline().decode("utf-8")
             if len(outs) == 0: break
@@ -193,36 +237,6 @@ class SbyProc:
             self.linebuffer = ""
             self.handle_output(outs)
 
-        if self.p.poll() is not None:
-            if not self.silent:
-                self.task.log(f"{self.info}: finished (returncode={self.p.returncode})")
-            self.task.update_proc_stopped(self)
-            self.running = False
-            self.exited = True
-
-            if self.p.returncode == 127:
-                if not self.silent:
-                    self.task.log(f"{self.info}: COMMAND NOT FOUND. ERROR.")
-                self.handle_error(self.p.returncode)
-                self.terminated = True
-                self.task.proc_failed(self)
-                return
-
-            if self.checkretcode and self.p.returncode not in self.retcodes:
-                if not self.silent:
-                    self.task.log(f"{self.info}: task failed. ERROR.")
-                self.handle_error(self.p.returncode)
-                self.terminated = True
-                self.task.proc_failed(self)
-                return
-
-            self.handle_exit(self.p.returncode)
-
-            self.finished = True
-            for next_proc in self.notify:
-                next_proc.poll()
-            return
-
 
 class SbyAbort(BaseException):
     pass
@@ -552,7 +566,8 @@ class SbyTask(SbyConfig):
         if not os.path.isdir(f"{self.workdir}/model"):
             os.makedirs(f"{self.workdir}/model")
 
-        def print_common_prep():
+        def print_common_prep(check):
+            print("scc -select; simplemap; select -clear", file=f)
             if self.opt_multiclock:
                 print("clk2fflogic", file=f)
             else:
@@ -569,7 +584,7 @@ class SbyTask(SbyConfig):
             print("setundef -anyseq", file=f)
             print("opt -keepdc -fast", file=f)
             print("check", file=f)
-            print("hierarchy -simcheck", file=f)
+            print(f"hierarchy {check}", file=f)
 
         if model_name == "base":
             with open(f"""{self.workdir}/model/design.ys""", "w") as f:
@@ -577,7 +592,7 @@ class SbyTask(SbyConfig):
                 for cmd in self.script:
                     print(cmd, file=f)
                 # the user must designate a top module in [script]
-                print("hierarchy -simcheck", file=f)
+                print("hierarchy -smtcheck", file=f)
                 print(f"""write_jny -no-connections ../model/design.json""", file=f)
                 print(f"""write_rtlil ../model/design.il""", file=f)
 
@@ -610,7 +625,7 @@ class SbyTask(SbyConfig):
                     print("memory_map", file=f)
                 else:
                     print("memory_nordff", file=f)
-                print_common_prep()
+                print_common_prep("-smtcheck")
                 if "_syn" in model_name:
                     print("techmap", file=f)
                     print("opt -fast", file=f)
@@ -643,7 +658,7 @@ class SbyTask(SbyConfig):
                     print("memory_map", file=f)
                 else:
                     print("memory_nordff", file=f)
-                print_common_prep()
+                print_common_prep("-simcheck")
                 print("flatten", file=f)
                 print("setundef -undriven -anyseq", file=f)
                 if "_syn" in model_name:
@@ -653,7 +668,7 @@ class SbyTask(SbyConfig):
                     print("abc", file=f)
                     print("opt_clean", file=f)
                 else:
-                    print("opt -fast", file=f)
+                    print("opt -fast -keepdc", file=f)
                 print("delete -output", file=f)
                 print("dffunmap", file=f)
                 print("stat", file=f)
@@ -675,7 +690,7 @@ class SbyTask(SbyConfig):
                 print(f"# running in {self.workdir}/model/", file=f)
                 print("read_ilang design.il", file=f)
                 print("memory_map", file=f)
-                print_common_prep()
+                print_common_prep("-simcheck")
                 print("flatten", file=f)
                 print("setundef -undriven -anyseq", file=f)
                 print("setattr -unset keep", file=f)
diff --git a/sbysrc/sby_engine_abc.py b/sbysrc/sby_engine_abc.py
index 4635ee1..e96ddb8 100644
--- a/sbysrc/sby_engine_abc.py
+++ b/sbysrc/sby_engine_abc.py
@@ -41,6 +41,7 @@ def run(mode, task, engine_idx, engine):
     elif abc_command[0] == "pdr":
         if mode != "prove":
             task.error("ABC command 'pdr' is only valid in prove mode.")
+        abc_command[0] += f" -v"
 
     else:
         task.error(f"Invalid ABC command {abc_command[0]}.")
diff --git a/tests/Makefile b/tests/Makefile
index 9b65da7..805d190 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,11 +2,27 @@ test:
 
 .PHONY: test clean refresh help
 
+OS_NAME := $(shell python3 -c "import os;print(os.name)")
+ifeq (nt,$(OS_NAME))
+ifeq (quoted,$(shell echo "quoted"))
+OS_NAME := nt-unix-like
+endif
+endif
+
+ifeq (nt,$(OS_NAME))
+$(error This Makefile requires unix-like tools and shell, e.g. MSYS2.)
+endif
+
 help:
 	@cat make/help.txt
 
-export SBY_WORKDIR_GITIGNORE=1
-export SBY_MAIN=$(realpath $(dir $(firstword $(MAKEFILE_LIST)))/../sbysrc/sby.py)
+export SBY_WORKDIR_GITIGNORE := 1
+
+SBY_MAIN := $(realpath $(dir $(firstword $(MAKEFILE_LIST)))/../sbysrc/sby.py)
+ifeq (nt-unix-like,$(OS_NAME))
+SBY_MAIN := $(shell cygpath -w $(SBY_MAIN))
+endif
+export SBY_MAIN
 
 make/rules/collect.mk: make/collect_tests.py
 	python3 make/collect_tests.py
diff --git a/tests/make/collect_tests.py b/tests/make/collect_tests.py
index 89a68ec..b5f7699 100644
--- a/tests/make/collect_tests.py
+++ b/tests/make/collect_tests.py
@@ -4,7 +4,8 @@ import re
 tests = []
 checked_dirs = []
 
-SAFE_PATH = re.compile(r"^[a-zA-Z0-9_./]*$")
+SAFE_PATH = re.compile(r"^[a-zA-Z0-9_./\\]*$")
+
 
 def collect(path):
     # don't pick up any paths that need escaping nor any sby workdirs
@@ -15,8 +16,6 @@ def collect(path):
     for entry in path.glob("*.sby"):
         filename = str(entry)
         if not SAFE_PATH.match(filename):
-            continue
-        if not re.match(r"^[a-zA-Z0-9_./]*$", filename):
             print(f"skipping {filename!r}, use only [a-zA-Z0-9_./] in filenames")
             continue
         tests.append(entry)
@@ -25,6 +24,10 @@ def collect(path):
             collect(entry)
 
 
+def unix_path(path):
+    return "/".join(path.parts)
+
+
 collect(Path("."))
 collect(Path("../docs/examples"))
 
@@ -33,16 +36,18 @@ out_file.parent.mkdir(exist_ok=True)
 
 with out_file.open("w") as output:
 
-
     for checked_dir in checked_dirs:
         print(f"{out_file}: {checked_dir}", file=output)
 
     for test in tests:
-        print(f"make/rules/test/{test}.mk: {test}", file=output)
+        test_unix = unix_path(test)
+        print(f"make/rules/test/{test_unix}.mk: {test_unix}", file=output)
         for ext in [".sh", ".py"]:
             script_file = test.parent / (test.stem + ext)
             if script_file.exists():
-                print(f"make/rules/test/{test}.mk: {script_file}", file=output)
-        print(f"make/rules/test/{test}.mk: make/test_rules.py", file=output)
+                script_file_unix = unix_path(script_file)
+                print(f"make/rules/test/{test_unix}.mk: {script_file_unix}", file=output)
+        print(f"make/rules/test/{test_unix}.mk: make/test_rules.py", file=output)
     for test in tests:
-        print(f"-include make/rules/test/{test}.mk", file=output)
+        test_unix = unix_path(test)
+        print(f"-include make/rules/test/{test_unix}.mk", file=output)
diff --git a/tests/make/required_tools.py b/tests/make/required_tools.py
index 203ccd7..ce33356 100644
--- a/tests/make/required_tools.py
+++ b/tests/make/required_tools.py
@@ -4,6 +4,7 @@ REQUIRED_TOOLS = {
     ("smtbmc", "yices"): ["yices-smt2"],
     ("smtbmc", "z3"): ["z3"],
     ("smtbmc", "cvc4"): ["cvc4"],
+    ("smtbmc", "cvc5"): ["cvc5"],
     ("smtbmc", "mathsat"): ["mathsat"],
     ("smtbmc", "boolector"): ["boolector"],
     ("smtbmc", "bitwuzla"): ["bitwuzla"],
diff --git a/tests/make/test_rules.py b/tests/make/test_rules.py
index 5c18aca..9607d81 100644
--- a/tests/make/test_rules.py
+++ b/tests/make/test_rules.py
@@ -7,6 +7,11 @@ from pathlib import Path
 
 from required_tools import REQUIRED_TOOLS
 
+
+def unix_path(path):
+    return "/".join(path.parts)
+
+
 sby_file = Path(sys.argv[1])
 sby_dir = sby_file.parent
 
@@ -56,7 +61,10 @@ with rules_file.open("w") as rules:
                 solvers.add(solver)
                 engine_solvers.add((engine, solver))
 
-        if any(line.startswith("read -verific") or line.startswith("verific") for line in info["script"]):
+        if any(
+            line.startswith("read -verific") or line.startswith("verific")
+            for line in info["script"]
+        ):
             required_tools.add("verific")
 
         required_tools = sorted(required_tools)
@@ -66,12 +74,17 @@ with rules_file.open("w") as rules:
 
         shell_script = sby_dir / f"{sby_file.stem}.sh"
 
-        if shell_script.exists():
-            command = f"cd {sby_dir} && SBY_FILE={sby_file.name} WORKDIR={workdirname} TASK={task} bash {shell_script.name}"
-        else:
-            command = f"cd {sby_dir} && python3 $(SBY_MAIN) -f {sby_file.name} {task}"
+        sby_dir_unix = unix_path(sby_dir)
 
-        print(f"\t@python3 make/required_tools.py run {target} {shlex.quote(command)} {shlex.join(required_tools)}", file=rules)
+        if shell_script.exists():
+            command = f"cd {sby_dir_unix} && env SBY_FILE={sby_file.name} WORKDIR={workdirname} TASK={task} bash {shell_script.name}"
+        else:
+            command = f"cd {sby_dir_unix} && python3 $(SBY_MAIN) -f {sby_file.name} {task}"
+
+        print(
+            f"\t@python3 make/required_tools.py run {target} {shlex.quote(command)} {shlex.join(required_tools)}",
+            file=rules,
+        )
 
         print(f".PHONY: clean-{target}", file=rules)
         print(f"clean-{target}:", file=rules)
diff --git a/tests/regression/const_clocks.sby b/tests/regression/const_clocks.sby
new file mode 100644
index 0000000..245358b
--- /dev/null
+++ b/tests/regression/const_clocks.sby
@@ -0,0 +1,43 @@
+[tasks]
+btor
+smt
+btor_m btor multiclock
+smt_m smt multiclock
+
+[options]
+mode bmc
+
+multiclock: multiclock on
+
+[engines]
+#smtbmc
+btor: btor btormc
+smt: smtbmc boolector
+
+[script]
+read_verilog -formal const_clocks.sv
+prep -flatten -top top
+
+[file const_clocks.sv]
+module top(
+    input clk,
+    input [7:0] d
+);
+
+    (* keep *)
+    wire [7:0] some_const = $anyconst;
+
+    wire [7:0] q;
+
+    ff ff1(.clk(1'b0), .d(d), .q(q));
+
+    initial assume (some_const == q);
+    initial assume (q != 0);
+
+
+    always @(posedge clk) assert(some_const == q);
+endmodule
+
+module ff(input clk, input [7:0] d, (* keep *) output reg [7:0] q);
+    always @(posedge clk) q <= d;
+endmodule
diff --git a/tests/regression/fake_loop.sby b/tests/regression/fake_loop.sby
new file mode 100644
index 0000000..419e267
--- /dev/null
+++ b/tests/regression/fake_loop.sby
@@ -0,0 +1,23 @@
+[options]
+mode cover
+
+[engines]
+smtbmc boolector
+
+[script]
+read -formal fake_loop.sv
+hierarchy -top fake_loop
+proc
+
+[file fake_loop.sv]
+module fake_loop(input clk, input a, input b, output [9:0] x);
+    wire [9:0] ripple;
+    reg [9:0] prev_ripple = 9'b0;
+
+    always @(posedge clk) prev_ripple <= ripple;
+
+    assign ripple = {ripple[8:0], a} ^ prev_ripple; // only cyclic at the coarse-grain level
+    assign x = ripple[9] + b;
+
+    always @(posedge clk) cover(ripple[9]);
+endmodule
diff --git a/tests/regression/ff_xinit_opt.sby b/tests/regression/ff_xinit_opt.sby
new file mode 100644
index 0000000..2078ad1
--- /dev/null
+++ b/tests/regression/ff_xinit_opt.sby
@@ -0,0 +1,39 @@
+[options]
+mode bmc
+
+[engines]
+smtbmc boolector
+
+[script]
+read_verilog -formal ff_xinit_opt.sv
+prep -flatten -top top
+
+opt -fast -keepdc
+
+[file ff_xinit_opt.sv]
+module top(
+    input clk,
+    input [7:0] d
+);
+
+    (* keep *)
+    wire [7:0] some_const = $anyconst;
+
+    wire [7:0] q1;
+    wire [7:0] q2;
+
+    ff ff1(.clk(clk), .d(q1), .q(q1));
+    ff ff2(.clk(1'b0), .d(d), .q(q2));
+
+    initial assume (some_const == q1);
+    initial assume (some_const == q2);
+    initial assume (q1 != 0);
+    initial assume (q2 != 0);
+
+    always @(posedge clk) assert(some_const == q1);
+    always @(posedge clk) assert(some_const == q2);
+endmodule
+
+module ff(input clk, input [7:0] d, (* keep *) output reg [7:0] q);
+    always @(posedge clk) q <= d;
+endmodule
diff --git a/tests/unsorted/blackbox.sby b/tests/unsorted/blackbox.sby
new file mode 100644
index 0000000..ca9400e
--- /dev/null
+++ b/tests/unsorted/blackbox.sby
@@ -0,0 +1,31 @@
+[options]
+mode bmc
+depth 1
+expect error
+
+[engines]
+smtbmc
+
+[script]
+read_verilog -formal test.v
+prep -top top
+
+[file test.v]
+(* blackbox *)
+module submod(a, b);
+	input [7:0] a;
+	output [7:0] b;
+endmodule
+
+module top;
+	wire [7:0] a = $anyconst, b;
+
+	submod submod(
+		.a(a),
+		.b(b)
+	);
+
+	always @* begin
+		assert(~a == b);
+	end
+endmodule
diff --git a/tests/unsorted/smtlib2_module.sby b/tests/unsorted/smtlib2_module.sby
new file mode 100644
index 0000000..43dfcb2
--- /dev/null
+++ b/tests/unsorted/smtlib2_module.sby
@@ -0,0 +1,32 @@
+[options]
+mode bmc
+depth 1
+
+[engines]
+smtbmc
+
+[script]
+read_verilog -formal test.v
+prep -top top
+
+[file test.v]
+(* blackbox *)
+(* smtlib2_module *)
+module submod(a, b);
+	input [7:0] a;
+	(* smtlib2_comb_expr = "(bvnot a)" *)
+	output [7:0] b;
+endmodule
+
+module top;
+	wire [7:0] a = $anyconst, b;
+
+	submod submod(
+		.a(a),
+		.b(b)
+	);
+
+	always @* begin
+		assert(~a == b);
+	end
+endmodule