Fix #4857 consider NOT when checking EQ/NEQ under AND/OR tree (#4863)

This commit is contained in:
Yutetsu TAKATSUKASA 2024-01-28 22:36:09 +09:00 committed by GitHub
parent d6f8ccd20b
commit e4a0e5aad6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 70 additions and 4 deletions

View File

@ -594,7 +594,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
const V3Number& compNum = constp->num(); const V3Number& compNum = constp->num();
auto setPolarities = [this, &compNum](const LeafInfo& ref, const V3Number* maskp) { auto setPolarities = [this, &compNum](const LeafInfo& ref, const V3Number* maskp) {
const bool maskFlip = isOrTree(); const bool maskFlip = isAndTree() ^ ref.polarity();
int constantWidth = compNum.width(); int constantWidth = compNum.width();
if (maskp) constantWidth = std::max(constantWidth, maskp->width()); if (maskp) constantWidth = std::max(constantWidth, maskp->width());
const int maxBitIdx = std::max(ref.lsb() + constantWidth, ref.msb() + 1); const int maxBitIdx = std::max(ref.lsb() + constantWidth, ref.msb() + 1);

View File

@ -20,7 +20,7 @@ execute(
); );
if ($Self->{vlt}) { if ($Self->{vlt}) {
file_grep($Self->{stats}, qr/Optimizations, Const bit op reduction\s+(\d+)/i, 37); file_grep($Self->{stats}, qr/Optimizations, Const bit op reduction\s+(\d+)/i, 39);
} }
ok(1); ok(1);
1; 1;

View File

@ -62,7 +62,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'hd1610f7181cbc1b4 `define EXPECTED_SUM 64'h5a76f060ff8aba3e
if (sum !== `EXPECTED_SUM) $stop; if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
@ -95,10 +95,11 @@ module Test(/*AUTOARG*/
logic bug4059_out; logic bug4059_out;
logic bug4832_out; logic bug4832_out;
logic bug4837_out; logic bug4837_out;
logic bug4857_out;
output logic o; output logic o;
logic [16:0] tmp; logic [17:0] tmp;
assign o = ^tmp; assign o = ^tmp;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
@ -131,6 +132,7 @@ module Test(/*AUTOARG*/
tmp[14]<= bug4059_out; tmp[14]<= bug4059_out;
tmp[15]<= bug4832_out; tmp[15]<= bug4832_out;
tmp[16]<= bug4837_out; tmp[16]<= bug4837_out;
tmp[17]<= bug4857_out;
end end
bug3182 i_bug3182(.in(d[4:0]), .out(bug3182_out)); bug3182 i_bug3182(.in(d[4:0]), .out(bug3182_out));
@ -144,6 +146,7 @@ module Test(/*AUTOARG*/
bug4059 i_bug4059(.clk(clk), .in(d), .out(bug4059_out)); bug4059 i_bug4059(.clk(clk), .in(d), .out(bug4059_out));
bug4832 i_bug4832(.clk(clk), .in(d), .out(bug4832_out)); bug4832 i_bug4832(.clk(clk), .in(d), .out(bug4832_out));
bug4837 i_bug4837(.clk(clk), .in(d), .out(bug4837_out)); bug4837 i_bug4837(.clk(clk), .in(d), .out(bug4837_out));
bug4857 i_bug4857(.clk(clk), .in(d), .out(bug4857_out));
endmodule endmodule
@ -450,3 +453,39 @@ module bug4837(input wire clk, input wire [31:0] in, output out);
assign out = out_data[33] ^ out_data[32] ^ out_data[0]; assign out = out_data[33] ^ out_data[32] ^ out_data[0];
endmodule endmodule
// See issue #4857
// (1'b0 != (!a)) | b was wrongly optimized to
// (a | b) & 1'b1
// polarity was not considered when traversing NEQ under AND/OR tree
module bug4857(input wire clk, input wire [31:0] in, output out);
logic [95:0] d;
always_ff @(posedge clk)
d <= {d[63:0], in};
wire celloutsig_12z;
wire celloutsig_15z;
wire celloutsig_17z;
wire celloutsig_4z;
wire celloutsig_67z;
wire celloutsig_9z;
logic [95:0] in_data;
logic result;
// verilator lint_off UNDRIVEN
wire [95:0] out_data;
// verilator lint_on UNDRIVEN
assign celloutsig_4z = ~(in_data[72] & in_data[43]); // 1
assign celloutsig_67z = | { in_data[64], celloutsig_12z }; // 0
assign celloutsig_15z = in_data[43] & ~(celloutsig_4z); // 0
assign celloutsig_9z = celloutsig_17z & ~(in_data[43]); // 00000000
assign celloutsig_17z = celloutsig_15z & ~(in_data[43]);// 0
assign celloutsig_12z = celloutsig_4z != celloutsig_9z; // 1
assign out_data[32] = celloutsig_67z; // 1
assign in_data = d;
always_ff @ (posedge clk)
result <= out_data[32];
assign out = result;
endmodule

View File

@ -0,0 +1,27 @@
#!/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");
compile(
verilator_flags2 => ["-Wno-UNOPTTHREADS",
"--stats", "$Self->{t_dir}/t_const_opt.cpp"],
);
execute(
check_finished => 1,
);
if ($Self->{vlt}) {
file_grep($Self->{stats}, qr/Optimizations, Const bit op reduction\s+(\d+)/i, 34);
}
ok(1);
1;