Fix #4864 of wrong runtime result (#4867)

* Fix #4864. Ignore if EQ/NE is under SHIFTR.
This commit is contained in:
Yutetsu TAKATSUKASA 2024-01-30 00:00:00 +09:00 committed by GitHub
parent c715cfc254
commit 999c9ae21c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 59 additions and 4 deletions

View File

@ -586,6 +586,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
} else if ((isAndTree() && VN_IS(nodep, Eq)) || (isOrTree() && VN_IS(nodep, Neq))) {
Restorer restorer{*this};
CONST_BITOP_RETURN_IF(!m_polarity, nodep);
CONST_BITOP_RETURN_IF(m_lsb, nodep); // the result of EQ/NE is 1 bit width
const AstNode* lhsp = nodep->lhsp();
if (const AstCCast* const castp = VN_CAST(lhsp, CCast)) lhsp = castp->lhsp();
const AstConst* const constp = VN_CAST(lhsp, Const);

View File

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

View File

@ -62,7 +62,7 @@ module t(/*AUTOARG*/
$write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
`define EXPECTED_SUM 64'h5a76f060ff8aba3e
`define EXPECTED_SUM 64'h4c5aa8d19cd13750
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
@ -96,10 +96,11 @@ module Test(/*AUTOARG*/
logic bug4832_out;
logic bug4837_out;
logic bug4857_out;
logic bug4864_out;
output logic o;
logic [17:0] tmp;
logic [18:0] tmp;
assign o = ^tmp;
always_ff @(posedge clk) begin
@ -133,6 +134,7 @@ module Test(/*AUTOARG*/
tmp[15]<= bug4832_out;
tmp[16]<= bug4837_out;
tmp[17]<= bug4857_out;
tmp[18]<= bug4864_out;
end
bug3182 i_bug3182(.in(d[4:0]), .out(bug3182_out));
@ -147,6 +149,7 @@ module Test(/*AUTOARG*/
bug4832 i_bug4832(.clk(clk), .in(d), .out(bug4832_out));
bug4837 i_bug4837(.clk(clk), .in(d), .out(bug4837_out));
bug4857 i_bug4857(.clk(clk), .in(d), .out(bug4857_out));
bug4864 i_bug4864(.clk(clk), .in(d), .out(bug4864_out));
endmodule
@ -489,3 +492,54 @@ module bug4857(input wire clk, input wire [31:0] in, output out);
result <= out_data[32];
assign out = result;
endmodule
// See issue #4864
// (((in_data[32*1] & 32'h3000000 != 0) | (in_data[32*2 + 25])| (sig_b != 9'b0)) >> 4) | sig_b[2]
// was wrongly optimized as below.
// ((in_data[32] & 32'h30000000) != 0 >> 0) | (in_data[32*2 + 29])|((sig_b & 9'h1f4) != 0)
// The result of EQ/NE is just 1 bit width, so EQ/NE under SHFITR cannot be treated as a multi-bit term
// such as AND/OR.
module bug4864(input wire clk, input wire [31:0] in, output wire out);
logic [159:0] clkin_data = '0;
logic [95:0] in_data = '0;
int cycle = 0;
always @(posedge clk) begin
if (in[0]) begin
cycle <= cycle + 1;
if (cycle == 0) begin
clkin_data <= 160'hFFFFFFFF_00000000_00000000_00000000_00000000;
end else if (cycle == 1) begin
in_data <= 96'h00000000_FFFFFFFF_00000000;
end else begin
clkin_data <= 160'hFFFFFFFF_00000000_00000000_00000000_FFFFFFFF;
end
end
end
wire moveme;
wire sig_a;
reg [8:0] sig_b;
wire sig_c;
wire [20:0] sig_d;
reg sig_e;
logic myfirst, mysecond;
assign myfirst = 1'b0;
assign mysecond = 1'b0;
always_ff @(posedge clkin_data[0], posedge myfirst, posedge mysecond)
if (myfirst) sig_e <= 1'b0;
else if (mysecond) sig_e <= 1'b1;
else if (clkin_data[128]) sig_e <= sig_d[7];
always_ff @(posedge clkin_data[128])
sig_b <= '0;
assign sig_a = in_data[89]; // 1'b0;
assign sig_c = | { in_data[61:60], sig_b, sig_a };
assign sig_d = ~ { moveme, 6'b0, sig_b, 1'b0, sig_c, 3'b0 };
assign moveme = 1'b1;
assign out = sig_e;
endmodule

View File

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