peepopt.muldiv: Add a signedness check.
authorMarcelina Kościelnicka <mwk@0x04.net>
Tue, 4 Aug 2020 14:30:24 +0000 (16:30 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Tue, 4 Aug 2020 14:30:24 +0000 (16:30 +0200)
Fixes #2318.

passes/pmgen/peepopt_muldiv.pmg
tests/opt/bug2318.ys [new file with mode: 0644]

index 7cad759d0e5555d486fbc99299b4244bd8c236ca..a4e232342d84d489e5263fc8b151aee58b0b304b 100644 (file)
@@ -1,16 +1,18 @@
 pattern muldiv
 
 state <SigSpec> t x y
+state <bool> is_signed
 
 match mul
        select mul->type == $mul
        select GetSize(port(mul, \A)) + GetSize(port(mul, \B)) <= GetSize(port(mul, \Y))
 endmatch
 
-code t x y
+code t x y is_signed
        t = port(mul, \Y);
        x = port(mul, \A);
        y = port(mul, \B);
+       is_signed = param(mul, \A_SIGNED).as_bool();
        branch;
        std::swap(x, y);
 endcode
@@ -19,6 +21,7 @@ match div
        select div->type.in($div)
        index <SigSpec> port(div, \A) === t
        index <SigSpec> port(div, \B) === x
+       filter param(div, \A_SIGNED).as_bool() == is_signed
 endmatch
 
 code
diff --git a/tests/opt/bug2318.ys b/tests/opt/bug2318.ys
new file mode 100644 (file)
index 0000000..9de6f88
--- /dev/null
@@ -0,0 +1,12 @@
+read_verilog <<EOT
+module t(input [3:0] A, input [3:0] B, output signed [3:0] Y);
+
+wire [7:0] P = A * B;
+wire signed [7:0] SP = P;
+wire signed [3:0] SB = B;
+assign Y = SP / SB;
+
+endmodule
+EOT
+
+equiv_opt -assert peepopt