Fix wrong bit op tree optimization (#3185)
* Add a test to reproduce bug3182. Run the same HDL with -Oo to confirm the result is same. * Hopefully fix #3182. The result can be 0 only when polarity is true (no AstNot is found during traversal).
This commit is contained in:
parent
e69a8e838d
commit
b08c694cd6
|
|
@ -537,7 +537,7 @@ class ConstBitOpTreeVisitor final : public AstNVisitor {
|
||||||
if (leafInfo.m_lsb < leafInfo.width()) {
|
if (leafInfo.m_lsb < leafInfo.width()) {
|
||||||
m_bitPolarities.emplace_back(leafInfo, isXorTree() || leafInfo.m_polarity,
|
m_bitPolarities.emplace_back(leafInfo, isXorTree() || leafInfo.m_polarity,
|
||||||
leafInfo.m_lsb);
|
leafInfo.m_lsb);
|
||||||
} else if (isAndTree()) {
|
} else if (isAndTree() && leafInfo.m_polarity) {
|
||||||
// If there is a constant 0 term in an And tree, we must include it. Fudge
|
// If there is a constant 0 term in an And tree, we must include it. Fudge
|
||||||
// this by adding a bit with both polarities, which will simplify to zero
|
// this by adding a bit with both polarities, which will simplify to zero
|
||||||
m_bitPolarities.emplace_back(leafInfo, true, 0);
|
m_bitPolarities.emplace_back(leafInfo, true, 0);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you
|
||||||
|
# can redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
top_filename("t/t_const_opt.v");
|
||||||
|
|
||||||
|
# Run the same design as t_const_opt.pl without bitopt tree optimization to make sure that the result is same.
|
||||||
|
compile(
|
||||||
|
verilator_flags2 => ["-Wno-UNOPTTHREADS", "--stats", "-Oo", "$Self->{t_dir}/t_const_opt.cpp"],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2021 by Yutetsu TAKATSUKASA. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
// Version 2.0.
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
// This function is used to introduce dependency and disturb optimization
|
||||||
|
extern "C" int fake_dependency() { return 0; }
|
||||||
|
|
@ -11,7 +11,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(simulator => 1);
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
compile(
|
compile(
|
||||||
verilator_flags2 => ["-Wno-UNOPTTHREADS", "--stats"],
|
verilator_flags2 => ["-Wno-UNOPTTHREADS", "--stats", "$Self->{t_dir}/$Self->{name}.cpp"],
|
||||||
);
|
);
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ module t(/*AUTOARG*/
|
||||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||||
// What checksum will we end up with (above print should match)
|
// What checksum will we end up with (above print should match)
|
||||||
`define EXPECTED_SUM 64'he78be35df15ae0ab
|
`define EXPECTED_SUM 64'ha916d9291821c6e0
|
||||||
if (sum !== `EXPECTED_SUM) $stop;
|
if (sum !== `EXPECTED_SUM) $stop;
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
|
|
@ -77,10 +77,11 @@ module Test(/*AUTOARG*/
|
||||||
input [31:0] i;
|
input [31:0] i;
|
||||||
logic [31:0] d;
|
logic [31:0] d;
|
||||||
logic d0, d1, d2, d3, d4, d5, d6, d7;
|
logic d0, d1, d2, d3, d4, d5, d6, d7;
|
||||||
|
logic bug3182_out;
|
||||||
|
|
||||||
output logic o;
|
output logic o;
|
||||||
|
|
||||||
logic [4:0] tmp;
|
logic [5:0] tmp;
|
||||||
assign o = ^tmp;
|
assign o = ^tmp;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
|
|
@ -101,6 +102,29 @@ module Test(/*AUTOARG*/
|
||||||
tmp[2] <= ((d0 & d1) | (d0 & d2))^ ((d3 & d4) | (d5 & d4)); // replaceAndOr()
|
tmp[2] <= ((d0 & d1) | (d0 & d2))^ ((d3 & d4) | (d5 & d4)); // replaceAndOr()
|
||||||
tmp[3] <= d0 <-> d1; // replaceLogEq()
|
tmp[3] <= d0 <-> d1; // replaceLogEq()
|
||||||
tmp[4] <= i[0] & (i[1] & (i[2] & (i[3] | d[4]))); // ConstBitOpTreeVisitor::m_frozenNodes
|
tmp[4] <= i[0] & (i[1] & (i[2] & (i[3] | d[4]))); // ConstBitOpTreeVisitor::m_frozenNodes
|
||||||
|
tmp[5] <= bug3182_out;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
bug3182 i_bug3182(.in(d[4:0]), .out(bug3182_out));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module bug3182(in, out);
|
||||||
|
input wire [4:0] in;
|
||||||
|
output wire out;
|
||||||
|
|
||||||
|
// This function always returns 0, so safe to take bitwise OR with any value.
|
||||||
|
// Calling this function stops constant folding as Verialtor does not know
|
||||||
|
// what this function returns.
|
||||||
|
import "DPI-C" context function int fake_dependency();
|
||||||
|
|
||||||
|
logic [4:0] bit_source;
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
always @(in)
|
||||||
|
bit_source = fake_dependency() | in;
|
||||||
|
|
||||||
|
wire [5:0] tmp = bit_source; // V3Gate should inline this
|
||||||
|
wire out = ~(tmp >> 5) & (bit_source == 5'd10);
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue