diff --git a/Changes b/Changes index a8bddc209..8be0408bc 100644 --- a/Changes +++ b/Changes @@ -44,6 +44,7 @@ Verilator 5.021 devel * Fix NOT when checking EQ/NEQ under AND/OR tree (#4857) (#4863). [Yutetsu TAKATSUKASA] * Fix tracing chandles (#4860). [Nathan Graybeal] * Fix $fwrite of null (#4862). [Jose Tejada] +* Fix GCC tautological-compare warnings. Verilator 5.020 2024-01-01 diff --git a/configure.ac b/configure.ac index 9315730f4..004f9024c 100644 --- a/configure.ac +++ b/configure.ac @@ -428,6 +428,7 @@ m4_foreach([cflag],[ [-Wno-shadow], [-Wno-sign-compare], [-Wno-tautological-bitwise-compare], + [-Wno-tautological-compare], [-Wno-uninitialized], [-Wno-unused-but-set-parameter], [-Wno-unused-but-set-variable], diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 30747a1e8..94aa6b280 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1441,16 +1441,22 @@ class ConstVisitor final : public VNVisitor { static bool operandsSame(AstNode* node1p, AstNode* node2p) { // For now we just detect constants & simple vars, though it could be more generic - if (VN_IS(node1p, Const) && VN_IS(node2p, Const)) { - return node1p->sameGateTree(node2p); - } else if (VN_IS(node1p, VarRef) && VN_IS(node2p, VarRef)) { + if (VN_IS(node1p, Const) && VN_IS(node2p, Const)) return node1p->sameGateTree(node2p); + if (VN_IS(node1p, VarRef) && VN_IS(node2p, VarRef)) { // Avoid comparing widthMin's, which results in lost optimization attempts // If cleanup sameGateTree to be smarter, this can be restored. // return node1p->sameGateTree(node2p); return node1p->isSame(node2p); - } else { - return false; } + // Pattern created by coverage-line; avoid compiler tautological-compare warning + if (AstAnd* const and1p = VN_CAST(node1p, And)) { + if (AstAnd* const and2p = VN_CAST(node2p, And)) { + if (VN_IS(and1p->lhsp(), Const) && VN_IS(and1p->rhsp(), NodeVarRef) + && VN_IS(and2p->lhsp(), Const) && VN_IS(and2p->rhsp(), NodeVarRef)) + return node1p->sameGateTree(node2p); + } + } + return false; } bool ifSameAssign(const AstNodeIf* nodep) { const AstNodeAssign* const thensp = VN_CAST(nodep->thensp(), NodeAssign); diff --git a/test_regress/t/t_cover_const_compare.pl b/test_regress/t/t_cover_const_compare.pl new file mode 100755 index 000000000..205218f81 --- /dev/null +++ b/test_regress/t/t_cover_const_compare.pl @@ -0,0 +1,22 @@ +#!/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-2009 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); + +compile( + verilator_flags2 => ['--coverage-line'], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_cover_const_compare.v b/test_regress/t/t_cover_const_compare.v new file mode 100644 index 000000000..aba12c115 --- /dev/null +++ b/test_regress/t/t_cover_const_compare.v @@ -0,0 +1,32 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + integer cyc; initial cyc=1; + + wire a = cyc[0]; + wire b = cyc[0]; + + always @ (posedge clk) begin + cyc <= cyc + 1; + // Before this was optimized, with --coverage-line + // error: self-comparison always evaluates to true [-Werror=tautological-compare] + // if (((1U & vlSelf->t__DOT__cyc) == (1U & vlSelf->t__DOT__cyc))) + if (a != cyc[0]) $stop; // Becomes cyc == cyc after substitution + if (b != cyc[0]) $stop; + if (cyc==10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule