diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index a1adf0af9..8cbe90104 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -241,6 +241,16 @@ class V3DfgPeephole final : public DfgVisitor { return make(examplep->fileline(), examplep->dtypep(), operands...); } + // Check two vertex are the same, or the same constant value + static bool isSame(const DfgVertex* ap, const DfgVertex* bp) { + if (ap == bp) return true; + const DfgConst* const aConstp = ap->cast(); + if (!aConstp) return false; + const DfgConst* const bConstp = bp->cast(); + if (!bConstp) return false; + return aConstp->num().isCaseEq(bConstp->num()); + } + // Note: If any of the following transformers return true, then the vertex was replaced and the // caller must not do any further changes, so the caller must check the return value, otherwise // there will be hard to debug issues. @@ -417,6 +427,55 @@ class V3DfgPeephole final : public DfgVisitor { return false; } + // Transformations that apply to all distributive and associative binary + // vertices 'Other' is the type that is distributive over 'Vertex', + // that is: a Other (b Vertex c) == (a Other b) Vertex (a Other c) + template + VL_ATTR_WARN_UNUSED_RESULT bool distributiveAndAssociativeBinary(Vertex* vtxp) { + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + if (!lhsp->hasMultipleSinks() && !rhsp->hasMultipleSinks()) { + // Convert '(a Other b) Vertex (a Other c)' and associative + // variations to 'a Other (b Vertex c)' + if (Other* const lp = lhsp->cast()) { + if (Other* const rp = rhsp->cast()) { + DfgVertex* const llp = lp->lhsp(); + DfgVertex* const lrp = lp->rhsp(); + DfgVertex* const rlp = rp->lhsp(); + DfgVertex* const rrp = rp->rhsp(); + DfgVertex* ap = nullptr; + DfgVertex* bp = nullptr; + DfgVertex* cp = nullptr; + if (llp == rlp) { + ap = llp; + bp = lrp; + cp = rrp; + } else if (llp == rrp) { + ap = llp; + bp = lrp; + cp = rlp; + } else if (lrp == rlp) { + ap = lrp; + bp = llp; + cp = rrp; + } else if (lrp == rrp) { + ap = lrp; + bp = llp; + cp = rlp; + } + if (ap) { + APPLYING(REPLACE_DISTRIBUTIVE_BINARY) { + replace(vtxp, make(vtxp, ap, make(lhsp, bp, cp))); + return true; + } + } + } + } + } + + return false; + } + // Bitwise operation with one side Const, and the other side a Concat template VL_ATTR_WARN_UNUSED_RESULT bool tryPushBitwiseOpThroughConcat(Vertex* vtxp, DfgConst* constp, @@ -881,15 +940,23 @@ class V3DfgPeephole final : public DfgVisitor { //========================================================================= void visit(DfgAnd* vtxp) override { - UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched LHS width"); - UASSERT_OBJ(vtxp->dtypep() == vtxp->rhsp()->dtypep(), vtxp, "Mismatched RHS width"); + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + + UASSERT_OBJ(vtxp->dtypep() == lhsp->dtypep(), vtxp, "Mismatched LHS width"); + UASSERT_OBJ(vtxp->dtypep() == rhsp->dtypep(), vtxp, "Mismatched RHS width"); + + if (lhsp == rhsp) { + APPLYING(REMOVE_AND_WITH_SELF) { + replace(vtxp, lhsp); + return; + } + } if (associativeBinary(vtxp)) return; if (commutativeBinary(vtxp)) return; - DfgVertex* const lhsp = vtxp->lhsp(); - DfgVertex* const rhsp = vtxp->rhsp(); FileLine* const flp = vtxp->fileline(); // Bubble pushing (De Morgan) @@ -935,6 +1002,8 @@ class V3DfgPeephole final : public DfgVisitor { } } + if (distributiveAndAssociativeBinary(vtxp)) return; + if (tryPushBitwiseOpThroughReductions(vtxp)) return; if (DfgNot* const lhsNotp = lhsp->cast()) { @@ -946,19 +1015,38 @@ class V3DfgPeephole final : public DfgVisitor { return; } } + + // ~A & (A & _) or ~A & (_ & A) is all zeroes + if (DfgAnd* const rhsAndp = rhsp->cast()) { + if (lhsNotp->srcp() == rhsAndp->lhsp() || lhsNotp->srcp() == rhsAndp->rhsp()) { + APPLYING(REPLACE_CONTRADICTORY_AND_3) { + DfgConst* const replacementp = makeZero(flp, vtxp->width()); + replace(vtxp, replacementp); + return; + } + } + } } } void visit(DfgOr* vtxp) override { - UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched LHS width"); - UASSERT_OBJ(vtxp->dtypep() == vtxp->rhsp()->dtypep(), vtxp, "Mismatched RHS width"); + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + + UASSERT_OBJ(vtxp->dtypep() == lhsp->dtypep(), vtxp, "Mismatched LHS width"); + UASSERT_OBJ(vtxp->dtypep() == rhsp->dtypep(), vtxp, "Mismatched RHS width"); + + if (lhsp == rhsp) { + APPLYING(REMOVE_OR_WITH_SELF) { + replace(vtxp, lhsp); + return; + } + } if (associativeBinary(vtxp)) return; if (commutativeBinary(vtxp)) return; - DfgVertex* const lhsp = vtxp->lhsp(); - DfgVertex* const rhsp = vtxp->rhsp(); FileLine* const flp = vtxp->fileline(); // Bubble pushing (De Morgan) @@ -1027,6 +1115,8 @@ class V3DfgPeephole final : public DfgVisitor { } } + if (distributiveAndAssociativeBinary(vtxp)) return; + if (tryPushBitwiseOpThroughReductions(vtxp)) return; if (DfgNot* const lhsNotp = lhsp->cast()) { @@ -1039,20 +1129,40 @@ class V3DfgPeephole final : public DfgVisitor { return; } } + + // ~A | (A | _) or ~A | (_ | A) is all ones + if (DfgOr* const rhsOrp = rhsp->cast()) { + if (lhsNotp->srcp() == rhsOrp->lhsp() || lhsNotp->srcp() == rhsOrp->rhsp()) { + APPLYING(REPLACE_TAUTOLOGICAL_OR_3) { + DfgConst* const replacementp = makeZero(flp, vtxp->width()); + replacementp->num().setAllBits1(); + replace(vtxp, replacementp); + return; + } + } + } } } void visit(DfgXor* vtxp) override { - UASSERT_OBJ(vtxp->dtypep() == vtxp->lhsp()->dtypep(), vtxp, "Mismatched LHS width"); - UASSERT_OBJ(vtxp->dtypep() == vtxp->rhsp()->dtypep(), vtxp, "Mismatched RHS width"); + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + + UASSERT_OBJ(vtxp->dtypep() == lhsp->dtypep(), vtxp, "Mismatched LHS width"); + UASSERT_OBJ(vtxp->dtypep() == rhsp->dtypep(), vtxp, "Mismatched RHS width"); + + if (lhsp == rhsp) { + APPLYING(REPLACE_XOR_WITH_SELF) { + DfgConst* const replacementp = makeZero(vtxp->fileline(), vtxp->width()); + replace(vtxp, replacementp); + return; + } + } if (associativeBinary(vtxp)) return; if (commutativeBinary(vtxp)) return; - DfgVertex* const lhsp = vtxp->lhsp(); - DfgVertex* const rhsp = vtxp->rhsp(); - if (DfgConst* const lConstp = lhsp->cast()) { if (lConstp->isZero()) { APPLYING(REMOVE_XOR_WITH_ZERO) { @@ -1252,6 +1362,16 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgLogAnd* vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + + if (lhsp->width() == 1 && rhsp->width() == 1) { + APPLYING(REPLACE_LOGAND_WITH_AND) { + replace(vtxp, make(vtxp, lhsp, rhsp)); + return; + } + } } void visit(DfgLogEq* vtxp) override { @@ -1264,6 +1384,16 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgLogOr* vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + + if (lhsp->width() == 1 && rhsp->width() == 1) { + APPLYING(REPLACE_LOGOR_WITH_OR) { + replace(vtxp, make(vtxp, lhsp, rhsp)); + return; + } + } } void visit(DfgLt* vtxp) override { @@ -1409,6 +1539,13 @@ class V3DfgPeephole final : public DfgVisitor { } } + if (isSame(thenp, elsep)) { + APPLYING(REMOVE_COND_WITH_BRANCHES_SAME) { + replace(vtxp, elsep); + return; + } + } + if (DfgNot* const condNotp = condp->cast()) { if (!condp->hasMultipleSinks() || condNotp->hasMultipleSinks()) { APPLYING(SWAP_COND_WITH_NOT_CONDITION) { @@ -1447,6 +1584,35 @@ class V3DfgPeephole final : public DfgVisitor { } } + if (DfgOr* const condOrp = condp->cast()) { + if (DfgCond* const thenCondp = thenp->cast()) { + if (!thenCondp->hasMultipleSinks()) { + if (condOrp->lhsp() == thenCondp->condp()) { + // '(a | b) ? (a ? x : y) : z' -> 'a ? x : b ? y : z' + APPLYING(REPLACE_COND_OR_THEN_COND_LHS) { + DfgCond* const replacementp + = make(vtxp, condOrp->lhsp(), thenCondp->thenp(), + make(thenCondp, condOrp->rhsp(), + thenCondp->elsep(), elsep)); + replace(vtxp, replacementp); + return; + } + } + if (condOrp->rhsp() == thenCondp->condp()) { + // '(a | b) ? (a ? x : y) : z' -> 'a ? x : b ? y : z' + APPLYING(REPLACE_COND_OR_THEN_COND_RHS) { + DfgCond* const replacementp + = make(vtxp, condOrp->rhsp(), thenCondp->thenp(), + make(thenCondp, condOrp->lhsp(), + thenCondp->elsep(), elsep)); + replace(vtxp, replacementp); + return; + } + } + } + } + } + if (vtxp->width() > 1) { // 'cond ? a + 1 : a' -> 'a + cond' if (DfgAdd* const thenAddp = thenp->cast()) { @@ -1495,6 +1661,13 @@ class V3DfgPeephole final : public DfgVisitor { return; } } + if (thenp == condp) { // a ? a : b becomes a | b + APPLYING(REPLACE_COND_WITH_THEN_BRANCH_COND) { + DfgOr* const repalcementp = make(vtxp, condp, elsep); + replace(vtxp, repalcementp); + return; + } + } if (thenp->isOnes()) { // a ? 1 : b becomes a | b APPLYING(REPLACE_COND_WITH_THEN_BRANCH_ONES) { DfgOr* const repalcementp = make(vtxp, condp, elsep); diff --git a/src/V3DfgPeephole.h b/src/V3DfgPeephole.h index 02895dfa0..f08627660 100644 --- a/src/V3DfgPeephole.h +++ b/src/V3DfgPeephole.h @@ -48,11 +48,14 @@ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_REPLICATE) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_SHIFTL) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_AND_WITH_ONES) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_AND_WITH_SELF) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_CONCAT_OF_ADJOINING_SELS) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_COND_WITH_BRANCHES_SAME) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_COND_WITH_FALSE_CONDITION) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_COND_WITH_TRUE_CONDITION) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_FULL_WIDTH_SEL) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_NOT_NOT) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_OR_WITH_SELF) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_OR_WITH_ZERO) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_REDUNDANT_ZEXT_ON_RHS_OF_SHIFT) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_REPLICATE_ONCE) \ @@ -68,12 +71,19 @@ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_CONCAT_ZERO_AND_SEL_TOP_WITH_SHIFTR) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_DEC) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_INC) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_OR_THEN_COND_LHS) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_OR_THEN_COND_RHS) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_WITH_ELSE_BRANCH_ONES) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_WITH_ELSE_BRANCH_ZERO) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_WITH_THEN_BRANCH_COND) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_WITH_THEN_BRANCH_ONES) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_COND_WITH_THEN_BRANCH_ZERO) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_CONTRADICTORY_AND) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_CONTRADICTORY_AND_3) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_DISTRIBUTIVE_BINARY) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_EXTEND) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_LOGAND_WITH_AND) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_LOGOR_WITH_OR) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_LHS) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_NOT_EQ) \ @@ -86,7 +96,9 @@ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_SEL_FROM_SEL) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_SUB_WITH_NOT) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_TAUTOLOGICAL_OR) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_TAUTOLOGICAL_OR_3) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_XOR_WITH_ONES) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_XOR_WITH_SELF) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, RIGHT_LEANING_ASSOC) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, SWAP_COND_WITH_NEQ_CONDITION) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, SWAP_COND_WITH_NOT_CONDITION) \ diff --git a/test_regress/t/t_dfg_peephole.v b/test_regress/t/t_dfg_peephole.v index ae91ea574..fb4644387 100644 --- a/test_regress/t/t_dfg_peephole.v +++ b/test_regress/t/t_dfg_peephole.v @@ -124,20 +124,33 @@ module t ( `signal(REPLACE_NOT_NEQ, ~(rand_a != rand_b)); `signal(REPLACE_NOT_EQ, ~(srand_a == srand_b)); `signal(REPLACE_NOT_OF_CONST, ~4'd0); + `signal(REPLACE_DISTRIBUTIVE_AND_OR_ABAC, ((rand_a >> 10) | (rand_b >> 10)) & ((rand_a >> 10) | (srand_b >> 10))); + `signal(REPLACE_DISTRIBUTIVE_AND_OR_ABCA, ((rand_a >> 11) | (rand_b >> 11)) & ((srand_b >> 11) | (rand_a >> 11))); + `signal(REPLACE_DISTRIBUTIVE_AND_OR_BAAC, ((rand_b >> 12) | (rand_a >> 12)) & ((rand_a >> 12) | (srand_b >> 12))); + `signal(REPLACE_DISTRIBUTIVE_AND_OR_BACA, ((rand_b >> 13) | (rand_a >> 13)) & ((srand_b >> 13) | (rand_a >> 13))); `signal(REPLACE_AND_OF_NOT_AND_NOT, ~rand_a[1] & ~rand_b[1]); `signal(REPLACE_AND_OF_NOT_AND_NEQ, ~rand_a[2] & (rand_b != 64'd2)); `signal(REPLACE_AND_OF_CONST_AND_CONST, const_a & const_b); `signal(REPLACE_AND_WITH_ZERO, 64'd0 & rand_a); `signal(REMOVE_AND_WITH_ONES, -64'd1 & rand_a); + `signal(REMOVE_AND_WITH_SELF, ~rand_a & ~rand_a); `signal(REPLACE_CONTRADICTORY_AND, rand_a & ~rand_a); + `signal(REPLACE_CONTRADICTORY_AND_3, ~(rand_a + 1) & ((rand_a + 1) & rand_b)); + `signal(REPLACE_OR_DISTRIBUTIVE, (rand_a & rand_b) | (rand_a & srand_b)); + `signal(REPLACE_DISTRIBUTIVE_OR_AND_ABAC, ((rand_a >> 14) & (rand_b >> 14)) | ((rand_a >> 14) & (srand_b >> 14))); + `signal(REPLACE_DISTRIBUTIVE_OR_AND_ABCA, ((rand_a >> 15) & (rand_b >> 15)) | ((srand_b >> 15) & (rand_a >> 15))); + `signal(REPLACE_DISTRIBUTIVE_OR_AND_BAAC, ((rand_b >> 16) & (rand_a >> 16)) | ((rand_a >> 16) & (srand_b >> 16))); + `signal(REPLACE_DISTRIBUTIVE_OR_AND_BACA, ((rand_b >> 17) & (rand_a >> 17)) | ((srand_b >> 17) & (rand_a >> 17))); `signal(REPLACE_OR_OF_NOT_AND_NOT, ~rand_a[3] | ~rand_b[3]); `signal(REPLACE_OR_OF_NOT_AND_NEQ, ~rand_a[4] | (rand_b != 64'd3)); `signal(REPLACE_OR_OF_CONCAT_ZERO_LHS_AND_CONCAT_RHS_ZERO, {2'd0, rand_a[1:0]} | {rand_b[1:0], 2'd0}); `signal(REPLACE_OR_OF_CONCAT_LHS_ZERO_AND_CONCAT_ZERO_RHS, {rand_a[1:0], 2'd0} | {2'd0, rand_b[1:0]}); `signal(REPLACE_OR_OF_CONST_AND_CONST, const_a | const_b); - `signal(REMOVE_OR_WITH_ZERO, 64'd0 | rand_a); `signal(REPLACE_OR_WITH_ONES, -64'd1 | rand_a); + `signal(REMOVE_OR_WITH_SELF, ~rand_a | ~rand_a); + `signal(REMOVE_OR_WITH_ZERO, 64'd0 | rand_a); `signal(REPLACE_TAUTOLOGICAL_OR, rand_a | ~rand_a); + `signal(REPLACE_TAUTOLOGICAL_OR_3, ~(rand_a + 1) | ((rand_a + 1) | rand_b)); `signal(REMOVE_SUB_ZERO, rand_a - 64'd0); `signal(REPLACE_SUB_WITH_NOT, rand_a[0] - 1'b1); `signal(REMOVE_REDUNDANT_ZEXT_ON_RHS_OF_SHIFT, rand_a << {2'b0, rand_a[2:0]}); @@ -159,9 +172,13 @@ module t ( `signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS, {{rand_b, rand_a[10:3]}, rand_a[2:1]}); `signal(REMOVE_COND_WITH_FALSE_CONDITION, 1'd0 ? rand_a : rand_b); `signal(REMOVE_COND_WITH_TRUE_CONDITION, 1'd1 ? rand_a : rand_b); + `signal(REMOVE_COND_WITH_BRANCHES_SAME, rand_a[0] ? ~rand_b : ~rand_b); `signal(SWAP_COND_WITH_NOT_CONDITION, (~rand_a[0] & 1'd1) ? rand_a : rand_b); `signal(SWAP_COND_WITH_NEQ_CONDITION, rand_b != rand_a ? rand_a : rand_b); `signal(PULL_NOTS_THROUGH_COND, rand_a[0] ? ~rand_a[4:0] : ~rand_b[4:0]); + `signal(REPLACE_COND_OR_THEN_COND_LHS, (rand_a[0] | rand_b[0] ? (rand_a[0] ? rand_a : rand_b) : srand_a)); + `signal(REPLACE_COND_OR_THEN_COND_RHS, (rand_a[0] | rand_b[0] ? (rand_b[0] ? rand_a : rand_b) : srand_a)); + `signal(REPLACE_COND_WITH_THEN_BRANCH_COND, rand_a[0] ? rand_a[0] : rand_a[1]); `signal(REPLACE_COND_WITH_THEN_BRANCH_ZERO, rand_a[0] ? 1'd0 : rand_a[1]); `signal(REPLACE_COND_WITH_THEN_BRANCH_ONES, rand_a[0] ? 1'd1 : rand_a[1]); `signal(REPLACE_COND_WITH_ELSE_BRANCH_ZERO, rand_a[0] ? rand_a[1] : 1'd0); @@ -177,11 +194,14 @@ module t ( `signal(REMOVE_WIDTH_ONE_REDUCTION_OR, |rand_a[0]); `signal(REMOVE_WIDTH_ONE_REDUCTION_XOR, ^rand_a[0]); `signal(REMOVE_XOR_WITH_ZERO, 64'd0 ^ rand_a); - `signal(REMOVE_XOR_WITH_ONES, -64'd1 ^ rand_a); + `signal(REPLACE_XOR_WITH_SELF, ~rand_a ^ ~rand_a); + `signal(REPLACE_XOR_WITH_ONES, -64'd1 ^ rand_a); `signal(REPLACE_COND_DEC, randbit_a ? rand_b - 64'b1 : rand_b); `signal(REPLACE_COND_INC, randbit_a ? rand_b + 64'b1 : rand_b); `signal(NO_REPLACE_COND_DEC, randbit_a ? rand_b - 64'hf000000000000000 : rand_b); `signal(NO_REPLACE_COND_INC, randbit_a ? rand_b + 64'hf000000000000000 : rand_b); + `signal(REPLACE_LOGAND_WITH_AND, rand_a[0] && rand_a[1]); + `signal(REPLACE_LOGOR_WITH_OR, rand_a[0] || rand_a[1]); `signal(RIGHT_LEANING_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b)); `signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b}); diff --git a/test_regress/t/t_opt_const_dfg.py b/test_regress/t/t_opt_const_dfg.py index 45033fc3f..7fd8decd0 100755 --- a/test_regress/t/t_opt_const_dfg.py +++ b/test_regress/t/t_opt_const_dfg.py @@ -18,7 +18,7 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats", test.pli_filename test.execute() if test.vlt: - test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 38) + test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 37) test.file_grep(test.stats, r'SplitVar, packed variables split automatically\s+(\d+)', 1) test.passes()