From 0cee66e7591b6315f9e7dce91b789c1f6b53138f Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 4 Sep 2019 12:34:44 -0700
Subject: [PATCH 01/22] Add peepopt_dffmuxext tests

---
 tests/simple/peepopt.v | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tests/simple/peepopt.v b/tests/simple/peepopt.v
index 1bf427897..b4d113dba 100644
--- a/tests/simple/peepopt.v
+++ b/tests/simple/peepopt.v
@@ -11,3 +11,11 @@ wire [3:0] t;
 assign t = i * 3;
 assign o = t / 3;
 endmodule
+
+module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o);
+    always @(posedge clk) if (ce) o <= i;
+endmodule
+
+module peepopt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0] o);
+    always @(posedge clk) if (ce) o <= i;
+endmodule

From 2b86055848c396591c6ec693a8abd8826b300b2b Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 4 Sep 2019 12:35:15 -0700
Subject: [PATCH 02/22] Add peepopt_dffmuxext

---
 passes/pmgen/Makefile.inc          |  1 +
 passes/pmgen/peepopt.cc            |  1 +
 passes/pmgen/peepopt_dffmuxext.pmg | 58 ++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+)
 create mode 100644 passes/pmgen/peepopt_dffmuxext.pmg

diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc
index 4989c582a..6648e2ec0 100644
--- a/passes/pmgen/Makefile.inc
+++ b/passes/pmgen/Makefile.inc
@@ -27,6 +27,7 @@ $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h))
 
 PEEPOPT_PATTERN  = passes/pmgen/peepopt_shiftmul.pmg
 PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg
+PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmuxext.pmg
 
 passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
 	$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p peepopt $(filter-out $<,$^)
diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc
index e7f95cf85..b57d26cef 100644
--- a/passes/pmgen/peepopt.cc
+++ b/passes/pmgen/peepopt.cc
@@ -60,6 +60,7 @@ struct PeepoptPass : public Pass {
 				peepopt_pm pm(module, module->selected_cells());
 				pm.run_shiftmul();
 				pm.run_muldiv();
+				pm.run_dffmuxext();
 			}
 		}
 	}
diff --git a/passes/pmgen/peepopt_dffmuxext.pmg b/passes/pmgen/peepopt_dffmuxext.pmg
new file mode 100644
index 000000000..e99ce1602
--- /dev/null
+++ b/passes/pmgen/peepopt_dffmuxext.pmg
@@ -0,0 +1,58 @@
+pattern dffmuxext
+
+state <IdString> muxAB
+
+match dff
+	select dff->type == $dff
+	select GetSize(port(dff, \D)) > 1
+endmatch
+
+match mux
+	select mux->type == $mux
+	select GetSize(port(mux, \Y)) > 1
+	choice <IdString> AB {\A, \B}
+	//select port(mux, AB)[GetSize(port(mux, \Y))-1].wire
+	index <SigSpec> port(mux, \Y) === port(dff, \D)
+	define <IdString> BA (AB == \A ? \B : \A)
+	index <SigSpec> port(mux, BA) === port(dff, \Q)
+	filter port(mux, AB)[GetSize(port(mux, \Y))-1] == port(mux, AB)[GetSize(port(mux, \Y))-2]
+	set muxAB AB
+endmatch
+
+code
+	did_something = true;
+
+	log_cell(dff);
+	log_cell(mux);
+
+	SigSpec &D = mux->connections_.at(muxAB);
+	SigSpec &Q = dff->connections_.at(\Q);
+	int width = GetSize(D);
+
+	SigBit sign = D[width-1];
+	bool is_signed = sign.wire;
+	int i;
+	for (i = width-1; i >= 2; i--) {
+		if (!is_signed) {
+			module->connect(Q[i], sign);
+			if (D[i-1] != sign)
+				break;
+		}
+		else {
+			module->connect(Q[i], Q[i-1]);
+			if (D[i-2] != sign)
+				break;
+		}
+	}
+
+	mux->connections_.at(\A).remove(i, width-i);
+	mux->connections_.at(\B).remove(i, width-i);
+	mux->connections_.at(\Y).remove(i, width-i);
+	mux->fixup_parameters();
+	dff->connections_.at(\D).remove(i, width-i);
+	dff->connections_.at(\Q).remove(i, width-i);
+	dff->fixup_parameters();
+
+	log("dffmuxext pattern in %s: dff=%s, mux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(mux), width-i);
+	accept;
+endcode

From 433b0c677c16ef5cc2fa92c576c54cc1a3a09f7f Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 4 Sep 2019 13:42:44 -0700
Subject: [PATCH 03/22] Remove log_cell() calls

---
 passes/pmgen/peepopt_dffmuxext.pmg | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/passes/pmgen/peepopt_dffmuxext.pmg b/passes/pmgen/peepopt_dffmuxext.pmg
index e99ce1602..2465d6171 100644
--- a/passes/pmgen/peepopt_dffmuxext.pmg
+++ b/passes/pmgen/peepopt_dffmuxext.pmg
@@ -22,9 +22,6 @@ endmatch
 code
 	did_something = true;
 
-	log_cell(dff);
-	log_cell(mux);
-
 	SigSpec &D = mux->connections_.at(muxAB);
 	SigSpec &Q = dff->connections_.at(\Q);
 	int width = GetSize(D);

From 6fe1ca633d90fb238d2671dba3d7f772c263a497 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 4 Sep 2019 15:20:04 -0700
Subject: [PATCH 04/22] abc9 followed by clean otherwise netlist could be
 invalid for sim

---
 tests/simple_abc9/run-test.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh
index 0d4262005..4d15a3253 100755
--- a/tests/simple_abc9/run-test.sh
+++ b/tests/simple_abc9/run-test.sh
@@ -25,5 +25,6 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-n 300 -p '\
     synth -run coarse; \
     opt -full; \
     techmap; abc9 -lut 4 -box ../abc.box; \
+    clean; \
     check -assert; \
     select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'"

From d3eea82bc27f6e54b6c1e05a73be8456344ec8b7 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 4 Sep 2019 15:21:39 -0700
Subject: [PATCH 05/22] Revert "parse_xaiger() to do "clean -purge""

This reverts commit 5d16bf831688ff665b0ec2abd6835b71320b2db5.
---
 frontends/aiger/aigerparse.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 2e1fb8fad..06522939f 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -974,7 +974,7 @@ void AigerReader::post_process()
 	// operate (and run checks on) this one module
 	RTLIL::Design *mapped_design = new RTLIL::Design;
 	mapped_design->add(module);
-	Pass::call(mapped_design, "clean -purge");
+	Pass::call(mapped_design, "clean");
 	mapped_design->modules_.erase(module->name);
 	delete mapped_design;
 

From 11f623cbe0057ee752f2545eb7100966afb08676 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 5 Sep 2019 08:25:09 -0700
Subject: [PATCH 06/22] Revert "abc9 followed by clean otherwise netlist could
 be invalid for sim"

This reverts commit 6fe1ca633d90fb238d2671dba3d7f772c263a497.
---
 tests/simple_abc9/run-test.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh
index 4d15a3253..0d4262005 100755
--- a/tests/simple_abc9/run-test.sh
+++ b/tests/simple_abc9/run-test.sh
@@ -25,6 +25,5 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-n 300 -p '\
     synth -run coarse; \
     opt -full; \
     techmap; abc9 -lut 4 -box ../abc.box; \
-    clean; \
     check -assert; \
     select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'"

From ef0681ea4ca0b34689cbf14d5a4478e2785600d9 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 5 Sep 2019 08:43:22 -0700
Subject: [PATCH 07/22] simple/peepopt.v tests to various/peepopt.ys with
 equiv_opt & select

---
 tests/simple/peepopt.v   | 21 --------------
 tests/various/peepopt.ys | 63 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 21 deletions(-)
 delete mode 100644 tests/simple/peepopt.v
 create mode 100644 tests/various/peepopt.ys

diff --git a/tests/simple/peepopt.v b/tests/simple/peepopt.v
deleted file mode 100644
index b4d113dba..000000000
--- a/tests/simple/peepopt.v
+++ /dev/null
@@ -1,21 +0,0 @@
-module peepopt_shiftmul_0 #(parameter N=3, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output [W-1:0] o);
-assign o = i[s*W+:W];
-endmodule
-
-module peepopt_shiftmul_1 (output y, input [2:0] w);
-assign y = 1'b1 >> (w * (3'b110));
-endmodule
-
-module peepopt_muldiv_0(input [1:0] i, output [1:0] o);
-wire [3:0] t;
-assign t = i * 3;
-assign o = t / 3;
-endmodule
-
-module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o);
-    always @(posedge clk) if (ce) o <= i;
-endmodule
-
-module peepopt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0] o);
-    always @(posedge clk) if (ce) o <= i;
-endmodule
diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
new file mode 100644
index 000000000..91db22423
--- /dev/null
+++ b/tests/various/peepopt.ys
@@ -0,0 +1,63 @@
+read_verilog <<EOT
+module peepopt_shiftmul_0 #(parameter N=3, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output [W-1:0] o);
+assign o = i[s*W+:W];
+endmodule
+EOT
+
+prep -nokeepdc
+equiv_opt peepopt
+design -load postopt
+clean
+select -assert-count 1 t:$shiftx
+select -assert-count 0 t:$shiftx t:* %D
+
+####################
+
+design -reset
+read_verilog <<EOT
+module peepopt_shiftmul_1 (output [7:0] y, input [2:0] w);
+assign y = 1'b1 >> (w * (3'b110));
+endmodule
+EOT
+
+prep -nokeepdc
+equiv_opt peepopt
+design -load postopt
+clean
+select -assert-count 1 t:$shr
+select -assert-count 1 t:$mul
+select -assert-count 0 t:$shr t:$mul %% t:* %D
+
+####################
+
+design -reset
+read_verilog <<EOT
+module peepopt_muldiv_0(input [1:0] i, output [1:0] o);
+wire [3:0] t;
+assign t = i * 3;
+assign o = t / 3;
+endmodule
+EOT
+
+prep -nokeepdc
+equiv_opt peepopt
+design -load postopt
+clean
+select -assert-count 0 t:*
+
+####################
+
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o);
+    always @(posedge clk) if (ce) o <= i;
+endmodule
+EOT
+
+prep -nokeepdc
+equiv_opt peepopt
+design -load postopt
+clean
+select -assert-count 1 t:$dff r:WIDTH=2 %i
+select -assert-count 1 t:$mux r:WIDTH=2 %i
+select -assert-count 0 t:$dff t:$mux %% t:* %D

From 51b559af2cc60226d85880efc3705f0860ffaed6 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 6 Sep 2019 22:48:04 -0700
Subject: [PATCH 08/22] Usee equiv_opt -assert

---
 tests/various/peepopt.ys | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 91db22423..a476133a2 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -5,7 +5,7 @@ endmodule
 EOT
 
 prep -nokeepdc
-equiv_opt peepopt
+equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 1 t:$shiftx
@@ -21,7 +21,7 @@ endmodule
 EOT
 
 prep -nokeepdc
-equiv_opt peepopt
+equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 1 t:$shr
@@ -40,7 +40,7 @@ endmodule
 EOT
 
 prep -nokeepdc
-equiv_opt peepopt
+equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 0 t:*

From e2c2d784c8217e4bcf29fb6b156b6a8285036b80 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 6 Sep 2019 22:48:23 -0700
Subject: [PATCH 09/22] Make one check $shift(x)? only; change testcase to be
 8b

---
 passes/pmgen/peepopt_shiftmul.pmg | 5 +++--
 tests/various/peepopt.ys          | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/passes/pmgen/peepopt_shiftmul.pmg b/passes/pmgen/peepopt_shiftmul.pmg
index d4748ae19..e1da52182 100644
--- a/passes/pmgen/peepopt_shiftmul.pmg
+++ b/passes/pmgen/peepopt_shiftmul.pmg
@@ -50,8 +50,9 @@ code
 	if (GetSize(const_factor_cnst) > 20)
 		reject;
 
-	if (GetSize(port(shift, \Y)) > const_factor)
-		reject;
+	if (shift->type.in($shift, $shiftx))
+		if (GetSize(port(shift, \Y)) > const_factor)
+			reject;
 
 	int factor_bits = ceil_log2(const_factor);
 	SigSpec mul_din = port(mul, const_factor_port == \A ? \B : \A);
diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index a476133a2..dcf3cacbd 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -16,7 +16,7 @@ select -assert-count 0 t:$shiftx t:* %D
 design -reset
 read_verilog <<EOT
 module peepopt_shiftmul_1 (output [7:0] y, input [2:0] w);
-assign y = 1'b1 >> (w * (3'b110));
+assign y = 1'b1 >> (w * (8'b110));
 endmodule
 EOT
 
@@ -25,7 +25,7 @@ equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 1 t:$shr
-select -assert-count 1 t:$mul
+select -assert-count 0 t:$mul
 select -assert-count 0 t:$shr t:$mul %% t:* %D
 
 ####################

From 97e1520b13231c8170cec73774eee7a22c5dc065 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 6 Sep 2019 22:50:03 -0700
Subject: [PATCH 10/22] Missing equiv_opt -assert

---
 tests/various/peepopt.ys | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index dcf3cacbd..33555264d 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -55,7 +55,7 @@ endmodule
 EOT
 
 prep -nokeepdc
-equiv_opt peepopt
+equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 1 t:$dff r:WIDTH=2 %i

From 580faae8ad608981ef6ef6a99ca6b771dc0368ae Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 00:07:17 -0700
Subject: [PATCH 11/22] Add unsigned case

---
 tests/various/peepopt.ys | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 33555264d..e930015a4 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -47,6 +47,23 @@ select -assert-count 0 t:*
 
 ####################
 
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0] o);
+    always @(posedge clk) if (ce) o <= i;
+endmodule
+EOT
+
+prep -nokeepdc
+equiv_opt -assert peepopt
+design -load postopt
+clean
+select -assert-count 1 t:$dff r:WIDTH=2 %i
+select -assert-count 1 t:$mux r:WIDTH=2 %i
+select -assert-count 0 t:$dff t:$mux %% t:* %D
+
+####################
+
 design -reset
 read_verilog <<EOT
 module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o);

From 3a8582081e1eda7e4a41ec1ec7292e7d247559da Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 00:14:06 -0700
Subject: [PATCH 12/22] proc instead of prep

---
 tests/various/peepopt.ys | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index e930015a4..2a660d5c9 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -54,7 +54,7 @@ module peepopt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0]
 endmodule
 EOT
 
-prep -nokeepdc
+proc
 equiv_opt -assert peepopt
 design -load postopt
 clean
@@ -71,7 +71,7 @@ module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg
 endmodule
 EOT
 
-prep -nokeepdc
+proc
 equiv_opt -assert peepopt
 design -load postopt
 clean

From edf90afd20046cb48273be8bc3da6ae2ea58d644 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 00:56:38 -0700
Subject: [PATCH 13/22] Rename dffmuxext -> dffmux, also remove constants in
 dff+mux

---
 passes/pmgen/Makefile.inc          |  2 +-
 passes/pmgen/peepopt.cc            |  2 +-
 passes/pmgen/peepopt_dffmux.pmg    | 89 ++++++++++++++++++++++++++++++
 passes/pmgen/peepopt_dffmuxext.pmg | 55 ------------------
 4 files changed, 91 insertions(+), 57 deletions(-)
 create mode 100644 passes/pmgen/peepopt_dffmux.pmg
 delete mode 100644 passes/pmgen/peepopt_dffmuxext.pmg

diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc
index 6648e2ec0..98691d0fe 100644
--- a/passes/pmgen/Makefile.inc
+++ b/passes/pmgen/Makefile.inc
@@ -27,7 +27,7 @@ $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h))
 
 PEEPOPT_PATTERN  = passes/pmgen/peepopt_shiftmul.pmg
 PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg
-PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmuxext.pmg
+PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmux.pmg
 
 passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
 	$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p peepopt $(filter-out $<,$^)
diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc
index b57d26cef..72b02127a 100644
--- a/passes/pmgen/peepopt.cc
+++ b/passes/pmgen/peepopt.cc
@@ -60,7 +60,7 @@ struct PeepoptPass : public Pass {
 				peepopt_pm pm(module, module->selected_cells());
 				pm.run_shiftmul();
 				pm.run_muldiv();
-				pm.run_dffmuxext();
+				pm.run_dffmux();
 			}
 		}
 	}
diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
new file mode 100644
index 000000000..4fc8e3b4c
--- /dev/null
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -0,0 +1,89 @@
+pattern dffmux
+
+state <IdString> muxAB
+
+match dff
+	select dff->type == $dff
+	select GetSize(port(dff, \D)) > 1
+endmatch
+
+match mux
+	select mux->type == $mux
+	select GetSize(port(mux, \Y)) > 1
+	choice <IdString> AB {\A, \B}
+	//select port(mux, AB)[GetSize(port(mux, \Y))-1].wire
+	index <SigSpec> port(mux, \Y) === port(dff, \D)
+	define <IdString> BA (AB == \A ? \B : \A)
+	index <SigSpec> port(mux, BA) === port(dff, \Q)
+	set muxAB AB
+endmatch
+
+code
+	SigSpec &D = mux->connections_.at(muxAB);
+	SigSpec &Q = dff->connections_.at(\Q);
+	int width = GetSize(D);
+
+	SigSpec AB = port(mux, muxAB);
+	if (AB[width-1] == AB[width-2]) {
+		did_something = true;
+
+		SigBit sign = D[width-1];
+		bool is_signed = sign.wire;
+		int i;
+		for (i = width-1; i >= 2; i--) {
+			if (!is_signed) {
+				module->connect(Q[i], sign);
+				if (D[i-1] != sign)
+					break;
+			}
+			else {
+				module->connect(Q[i], Q[i-1]);
+				if (D[i-2] != sign)
+					break;
+			}
+		}
+
+		mux->connections_.at(\A).remove(i, width-i);
+		mux->connections_.at(\B).remove(i, width-i);
+		mux->connections_.at(\Y).remove(i, width-i);
+		mux->fixup_parameters();
+		dff->connections_.at(\D).remove(i, width-i);
+		dff->connections_.at(\Q).remove(i, width-i);
+		dff->fixup_parameters();
+
+		log("dffmux pattern in %s: dff=%s, mux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(mux), width-i);
+		accept;
+	}
+	else {
+		int count = 0;
+		for (int i = width-1; i >= 0; i--) {
+			if (AB[i].wire)
+				continue;
+			Wire *w = Q[i].wire;
+			auto it = w->attributes.find(\init);
+			State init;
+			if (it != w->attributes.end())
+				init = it->second[Q[i].offset];
+			else
+				init = State::Sx;
+
+			if (init == State::Sx || init == AB[i].data) {
+				count++;
+				module->connect(Q[i], AB[i]);
+				mux->connections_.at(\A).remove(i);
+				mux->connections_.at(\B).remove(i);
+				mux->connections_.at(\Y).remove(i);
+				dff->connections_.at(\D).remove(i);
+				dff->connections_.at(\Q).remove(i);
+			}
+		}
+		if (count > 0) {
+			did_something = true;
+			mux->fixup_parameters();
+			dff->fixup_parameters();
+		}
+
+		log("dffmux pattern in %s: dff=%s, mux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(mux), count);
+		accept;
+	}
+endcode
diff --git a/passes/pmgen/peepopt_dffmuxext.pmg b/passes/pmgen/peepopt_dffmuxext.pmg
deleted file mode 100644
index 2465d6171..000000000
--- a/passes/pmgen/peepopt_dffmuxext.pmg
+++ /dev/null
@@ -1,55 +0,0 @@
-pattern dffmuxext
-
-state <IdString> muxAB
-
-match dff
-	select dff->type == $dff
-	select GetSize(port(dff, \D)) > 1
-endmatch
-
-match mux
-	select mux->type == $mux
-	select GetSize(port(mux, \Y)) > 1
-	choice <IdString> AB {\A, \B}
-	//select port(mux, AB)[GetSize(port(mux, \Y))-1].wire
-	index <SigSpec> port(mux, \Y) === port(dff, \D)
-	define <IdString> BA (AB == \A ? \B : \A)
-	index <SigSpec> port(mux, BA) === port(dff, \Q)
-	filter port(mux, AB)[GetSize(port(mux, \Y))-1] == port(mux, AB)[GetSize(port(mux, \Y))-2]
-	set muxAB AB
-endmatch
-
-code
-	did_something = true;
-
-	SigSpec &D = mux->connections_.at(muxAB);
-	SigSpec &Q = dff->connections_.at(\Q);
-	int width = GetSize(D);
-
-	SigBit sign = D[width-1];
-	bool is_signed = sign.wire;
-	int i;
-	for (i = width-1; i >= 2; i--) {
-		if (!is_signed) {
-			module->connect(Q[i], sign);
-			if (D[i-1] != sign)
-				break;
-		}
-		else {
-			module->connect(Q[i], Q[i-1]);
-			if (D[i-2] != sign)
-				break;
-		}
-	}
-
-	mux->connections_.at(\A).remove(i, width-i);
-	mux->connections_.at(\B).remove(i, width-i);
-	mux->connections_.at(\Y).remove(i, width-i);
-	mux->fixup_parameters();
-	dff->connections_.at(\D).remove(i, width-i);
-	dff->connections_.at(\Q).remove(i, width-i);
-	dff->fixup_parameters();
-
-	log("dffmuxext pattern in %s: dff=%s, mux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(mux), width-i);
-	accept;
-endcode

From bbef0d2ac8a84299109d9bd93b5eb69a5500d594 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 12:29:26 -0700
Subject: [PATCH 14/22] Only display log message if did_something

---
 passes/pmgen/peepopt_dffmux.pmg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
index 4fc8e3b4c..da3a66577 100644
--- a/passes/pmgen/peepopt_dffmux.pmg
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -81,9 +81,9 @@ code
 			did_something = true;
 			mux->fixup_parameters();
 			dff->fixup_parameters();
+			log("dffmux pattern in %s: dff=%s, mux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(mux), count);
 		}
 
-		log("dffmux pattern in %s: dff=%s, mux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(mux), count);
 		accept;
 	}
 endcode

From f46ef47893b4d2cb01fc5914fe0ee89d206f686f Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 13:22:41 -0700
Subject: [PATCH 15/22] Add more tests

---
 tests/various/peepopt.ys | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 2a660d5c9..8dce679ff 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -78,3 +78,35 @@ clean
 select -assert-count 1 t:$dff r:WIDTH=2 %i
 select -assert-count 1 t:$mux r:WIDTH=2 %i
 select -assert-count 0 t:$dff t:$mux %% t:* %D
+
+###################
+
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_const(input clk, ce, input [1:0] i, output reg [5:0] o);
+    always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz};
+endmodule
+EOT
+
+proc
+equiv_opt -assert peepopt
+design -load postopt
+select -assert-count 1 t:$dff r:WIDTH=2 %i
+select -assert-count 1 t:$mux r:WIDTH=2 %i
+select -assert-count 0 t:$dff t:$mux %% t:* %D
+
+###################
+
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_const_init(input clk, ce, input [1:0] i, (* init=6'b0x00x1 *) output reg [5:0] o);
+    always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz};
+endmodule
+EOT
+
+proc
+equiv_opt -assert peepopt
+design -load postopt
+select -assert-count 1 t:$dff r:WIDTH=5 %i
+select -assert-count 1 t:$mux r:WIDTH=5 %i
+select -assert-count 0 t:$dff t:$mux %% t:* %D

From 4937917cd8fb351740ffd936ea8a227795872775 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 13:22:52 -0700
Subject: [PATCH 16/22] Cleanup

---
 passes/pmgen/peepopt_dffmux.pmg | 47 +++++++++++++++------------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
index da3a66577..9b4fef76f 100644
--- a/passes/pmgen/peepopt_dffmux.pmg
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -1,30 +1,27 @@
 pattern dffmux
 
-state <IdString> muxAB
+state <IdString> cemuxAB
 
 match dff
 	select dff->type == $dff
 	select GetSize(port(dff, \D)) > 1
 endmatch
 
-match mux
-	select mux->type == $mux
-	select GetSize(port(mux, \Y)) > 1
+match cemux
+	select cemux->type == $mux
+	select GetSize(port(cemux, \Y)) > 1
+	index <SigSpec> port(cemux, \Y) === port(dff, \D)
 	choice <IdString> AB {\A, \B}
-	//select port(mux, AB)[GetSize(port(mux, \Y))-1].wire
-	index <SigSpec> port(mux, \Y) === port(dff, \D)
-	define <IdString> BA (AB == \A ? \B : \A)
-	index <SigSpec> port(mux, BA) === port(dff, \Q)
-	set muxAB AB
+	index <SigSpec> port(cemux, AB) === port(dff, \Q)
+	set cemuxAB AB
 endmatch
 
 code
-	SigSpec &D = mux->connections_.at(muxAB);
+	SigSpec &D = cemux->connections_.at(cemuxAB == \A ? \B : \A);
 	SigSpec &Q = dff->connections_.at(\Q);
 	int width = GetSize(D);
 
-	SigSpec AB = port(mux, muxAB);
-	if (AB[width-1] == AB[width-2]) {
+	if (D[width-1] == D[width-2]) {
 		did_something = true;
 
 		SigBit sign = D[width-1];
@@ -43,21 +40,21 @@ code
 			}
 		}
 
-		mux->connections_.at(\A).remove(i, width-i);
-		mux->connections_.at(\B).remove(i, width-i);
-		mux->connections_.at(\Y).remove(i, width-i);
-		mux->fixup_parameters();
+		cemux->connections_.at(\A).remove(i, width-i);
+		cemux->connections_.at(\B).remove(i, width-i);
+		cemux->connections_.at(\Y).remove(i, width-i);
+		cemux->fixup_parameters();
 		dff->connections_.at(\D).remove(i, width-i);
 		dff->connections_.at(\Q).remove(i, width-i);
 		dff->fixup_parameters();
 
-		log("dffmux pattern in %s: dff=%s, mux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(mux), width-i);
+		log("dffcemux pattern in %s: dff=%s, cemux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux), width-i);
 		accept;
 	}
 	else {
 		int count = 0;
 		for (int i = width-1; i >= 0; i--) {
-			if (AB[i].wire)
+			if (D[i].wire)
 				continue;
 			Wire *w = Q[i].wire;
 			auto it = w->attributes.find(\init);
@@ -67,21 +64,21 @@ code
 			else
 				init = State::Sx;
 
-			if (init == State::Sx || init == AB[i].data) {
+			if (init == State::Sx || init == D[i].data) {
 				count++;
-				module->connect(Q[i], AB[i]);
-				mux->connections_.at(\A).remove(i);
-				mux->connections_.at(\B).remove(i);
-				mux->connections_.at(\Y).remove(i);
+				module->connect(Q[i], D[i]);
+				cemux->connections_.at(\A).remove(i);
+				cemux->connections_.at(\B).remove(i);
+				cemux->connections_.at(\Y).remove(i);
 				dff->connections_.at(\D).remove(i);
 				dff->connections_.at(\Q).remove(i);
 			}
 		}
 		if (count > 0) {
 			did_something = true;
-			mux->fixup_parameters();
+			cemux->fixup_parameters();
 			dff->fixup_parameters();
-			log("dffmux pattern in %s: dff=%s, mux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(mux), count);
+			log("dffcemux pattern in %s: dff=%s, cemux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(cemux), count);
 		}
 
 		accept;

From bdb5e0f29c3e913fb4e701317105363064b9a7d3 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 13:36:37 -0700
Subject: [PATCH 17/22] Cope with presence of reset muxes too

---
 passes/pmgen/peepopt_dffmux.pmg | 29 ++++++++++++++++++++----
 tests/various/peepopt.ys        | 39 +++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
index 9b4fef76f..60a708616 100644
--- a/passes/pmgen/peepopt_dffmux.pmg
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -1,16 +1,34 @@
 pattern dffmux
 
-state <IdString> cemuxAB
+state <IdString> cemuxAB rstmuxBA
+state <SigSpec> sigD
 
 match dff
 	select dff->type == $dff
 	select GetSize(port(dff, \D)) > 1
 endmatch
 
+match rstmux
+	select rstmux->type == $mux
+	select GetSize(port(rstmux, \Y)) > 1
+	index <SigSpec> port(rstmux, \Y) === port(dff, \D)
+	choice <IdString> BA {\B, \A}
+	select port(rstmux, BA).is_fully_const()
+	set rstmuxBA BA
+	optional
+endmatch
+
+code sigD
+	if (rstmux)
+		sigD = port(rstmux, rstmuxBA == \B ? \A : \B);
+	else
+		sigD = port(dff, \D);
+endcode
+
 match cemux
 	select cemux->type == $mux
 	select GetSize(port(cemux, \Y)) > 1
-	index <SigSpec> port(cemux, \Y) === port(dff, \D)
+	index <SigSpec> port(cemux, \Y) === sigD
 	choice <IdString> AB {\A, \B}
 	index <SigSpec> port(cemux, AB) === port(dff, \Q)
 	set cemuxAB AB
@@ -19,6 +37,9 @@ endmatch
 code
 	SigSpec &D = cemux->connections_.at(cemuxAB == \A ? \B : \A);
 	SigSpec &Q = dff->connections_.at(\Q);
+	Const rst;
+	if (rstmux)
+		rst = port(rstmux, rstmuxBA).as_const();
 	int width = GetSize(D);
 
 	if (D[width-1] == D[width-2]) {
@@ -30,12 +51,12 @@ code
 		for (i = width-1; i >= 2; i--) {
 			if (!is_signed) {
 				module->connect(Q[i], sign);
-				if (D[i-1] != sign)
+				if (D[i-1] != sign || (rst.size() && rst[i-1] != rst[width-1]))
 					break;
 			}
 			else {
 				module->connect(Q[i], Q[i-1]);
-				if (D[i-2] != sign)
+				if (D[i-2] != sign || (rst.size() && rst[i-1] != rst[width-1]))
 					break;
 			}
 		}
diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 8dce679ff..886c8cd9d 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -110,3 +110,42 @@ design -load postopt
 select -assert-count 1 t:$dff r:WIDTH=5 %i
 select -assert-count 1 t:$mux r:WIDTH=5 %i
 select -assert-count 0 t:$dff t:$mux %% t:* %D
+
+####################
+
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_unsigned_rst(input clk, ce, rst, input [1:0] i, output reg [3:0] o);
+    always @(posedge clk) if (rst) o <= 0; else if (ce) o <= i;
+endmodule
+EOT
+
+proc
+equiv_opt -assert peepopt
+design -load postopt
+wreduce
+select -assert-count 1 t:$dff r:WIDTH=2 %i
+select -assert-count 2 t:$mux
+select -assert-count 2 t:$mux r:WIDTH=2 %i
+select -assert-count 0 t:$dff t:$mux %% t:* %D
+
+####################
+
+design -reset
+read_verilog <<EOT
+module peepopt_dffmuxext_signed_rst(input clk, ce, rstn, input signed [1:0] i, output reg signed [3:0] o);
+    always @(posedge clk) begin
+        if (ce) o <= i;
+        if (!rstn) o <= 4'b1111;
+    end
+endmodule
+EOT
+
+proc
+equiv_opt -assert peepopt
+design -load postopt
+wreduce
+select -assert-count 1 t:$dff r:WIDTH=2 %i
+select -assert-count 2 t:$mux
+select -assert-count 2 t:$mux r:WIDTH=2 %i
+select -assert-count 0 t:$logic_not t:$dff t:$mux %% t:* %D

From 817ac7c5e051b2f0947bd9cb9044ac7c3e2f089c Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 14:17:45 -0700
Subject: [PATCH 18/22] Fix UB

---
 passes/pmgen/peepopt_dffmux.pmg | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
index 60a708616..fbabf90f0 100644
--- a/passes/pmgen/peepopt_dffmux.pmg
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -35,8 +35,8 @@ match cemux
 endmatch
 
 code
-	SigSpec &D = cemux->connections_.at(cemuxAB == \A ? \B : \A);
-	SigSpec &Q = dff->connections_.at(\Q);
+	SigSpec D = port(cemux, cemuxAB == \A ? \B : \A);
+	SigSpec Q = port(dff, \Q);
 	Const rst;
 	if (rstmux)
 		rst = port(rstmux, rstmuxBA).as_const();

From 3a49aa6b4a707f558ec378a25d28c3e0d914cfac Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 11 Sep 2019 14:20:49 -0700
Subject: [PATCH 19/22] Tidy up

---
 passes/pmgen/peepopt_dffmux.pmg | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg
index fbabf90f0..c88a52226 100644
--- a/passes/pmgen/peepopt_dffmux.pmg
+++ b/passes/pmgen/peepopt_dffmux.pmg
@@ -42,6 +42,12 @@ code
 		rst = port(rstmux, rstmuxBA).as_const();
 	int width = GetSize(D);
 
+	SigSpec &ceA = cemux->connections_.at(\A);
+	SigSpec &ceB = cemux->connections_.at(\B);
+	SigSpec &ceY = cemux->connections_.at(\Y);
+	SigSpec &dffD = dff->connections_.at(\D);
+	SigSpec &dffQ = dff->connections_.at(\Q);
+
 	if (D[width-1] == D[width-2]) {
 		did_something = true;
 
@@ -61,12 +67,12 @@ code
 			}
 		}
 
-		cemux->connections_.at(\A).remove(i, width-i);
-		cemux->connections_.at(\B).remove(i, width-i);
-		cemux->connections_.at(\Y).remove(i, width-i);
+		ceA.remove(i, width-i);
+		ceB.remove(i, width-i);
+		ceY.remove(i, width-i);
 		cemux->fixup_parameters();
-		dff->connections_.at(\D).remove(i, width-i);
-		dff->connections_.at(\Q).remove(i, width-i);
+		dffD.remove(i, width-i);
+		dffQ.remove(i, width-i);
 		dff->fixup_parameters();
 
 		log("dffcemux pattern in %s: dff=%s, cemux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux), width-i);
@@ -88,11 +94,11 @@ code
 			if (init == State::Sx || init == D[i].data) {
 				count++;
 				module->connect(Q[i], D[i]);
-				cemux->connections_.at(\A).remove(i);
-				cemux->connections_.at(\B).remove(i);
-				cemux->connections_.at(\Y).remove(i);
-				dff->connections_.at(\D).remove(i);
-				dff->connections_.at(\Q).remove(i);
+				ceA.remove(i);
+				ceB.remove(i);
+				ceY.remove(i);
+				dffD.remove(i);
+				dffQ.remove(i);
 			}
 		}
 		if (count > 0) {

From 14d72c39c385bba3005085815a0d66989a437eff Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 13 Sep 2019 16:33:18 -0700
Subject: [PATCH 20/22] Revert "Make one check $shift(x)? only; change testcase
 to be 8b"

This reverts commit e2c2d784c8217e4bcf29fb6b156b6a8285036b80.
---
 passes/pmgen/peepopt_shiftmul.pmg | 5 ++---
 tests/various/peepopt.ys          | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/passes/pmgen/peepopt_shiftmul.pmg b/passes/pmgen/peepopt_shiftmul.pmg
index e1da52182..d4748ae19 100644
--- a/passes/pmgen/peepopt_shiftmul.pmg
+++ b/passes/pmgen/peepopt_shiftmul.pmg
@@ -50,9 +50,8 @@ code
 	if (GetSize(const_factor_cnst) > 20)
 		reject;
 
-	if (shift->type.in($shift, $shiftx))
-		if (GetSize(port(shift, \Y)) > const_factor)
-			reject;
+	if (GetSize(port(shift, \Y)) > const_factor)
+		reject;
 
 	int factor_bits = ceil_log2(const_factor);
 	SigSpec mul_din = port(mul, const_factor_port == \A ? \B : \A);
diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 886c8cd9d..abee9cc0a 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -16,7 +16,7 @@ select -assert-count 0 t:$shiftx t:* %D
 design -reset
 read_verilog <<EOT
 module peepopt_shiftmul_1 (output [7:0] y, input [2:0] w);
-assign y = 1'b1 >> (w * (8'b110));
+assign y = 1'b1 >> (w * (3'b110));
 endmodule
 EOT
 
@@ -25,7 +25,7 @@ equiv_opt -assert peepopt
 design -load postopt
 clean
 select -assert-count 1 t:$shr
-select -assert-count 0 t:$mul
+select -assert-count 1 t:$mul
 select -assert-count 0 t:$shr t:$mul %% t:* %D
 
 ####################

From a2eee9ebefc6e8089c815b4355bc64d1ac3396b5 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 13 Sep 2019 16:41:10 -0700
Subject: [PATCH 21/22] Add counter-example from @cliffordwolf

---
 tests/various/peepopt.ys | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index abee9cc0a..7c1c3b5bc 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -30,6 +30,30 @@ select -assert-count 0 t:$shr t:$mul %% t:* %D
 
 ####################
 
+design -reset
+read_verilog <<EOT
+module peepopt_shiftmul_2 (input [11:0] D, input [1:0] S, output [11:0] Y);
+	assign Y = D >> (S*3);
+endmodule
+EOT
+
+prep
+design -save gold
+peepopt
+design -stash gate
+
+design -import gold -as gold peepopt_shiftmul_2
+design -import gate -as gate peepopt_shiftmul_2
+
+miter -equiv -make_assert -make_outputs -ignore_gold_x -flatten gold gate miter
+sat -show-public -enable_undef -prove-asserts miter
+select -assert-count 1 t:$shr
+select -assert-count 1 t:$mul
+select -assert-count 0 t:$shr t:$mul %% t:* %D
+exit
+
+####################
+
 design -reset
 read_verilog <<EOT
 module peepopt_muldiv_0(input [1:0] i, output [1:0] o);

From f492567c872c1f6bc864fe0a3d86021558f8101e Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Fri, 13 Sep 2019 18:19:07 -0700
Subject: [PATCH 22/22] Oops

---
 tests/various/peepopt.ys | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys
index 7c1c3b5bc..6bca62e2b 100644
--- a/tests/various/peepopt.ys
+++ b/tests/various/peepopt.ys
@@ -47,10 +47,10 @@ design -import gate -as gate peepopt_shiftmul_2
 
 miter -equiv -make_assert -make_outputs -ignore_gold_x -flatten gold gate miter
 sat -show-public -enable_undef -prove-asserts miter
+cd gate
 select -assert-count 1 t:$shr
 select -assert-count 1 t:$mul
 select -assert-count 0 t:$shr t:$mul %% t:* %D
-exit
 
 ####################