Add DfgPeephole patterns (#6149)

This commit is contained in:
Geza Lore 2025-07-07 16:25:29 +01:00 committed by GitHub
parent 5a6d5ed96b
commit e494cf22a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 221 additions and 16 deletions

View File

@ -241,6 +241,16 @@ class V3DfgPeephole final : public DfgVisitor {
return make<Vertex>(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<DfgConst>();
if (!aConstp) return false;
const DfgConst* const bConstp = bp->cast<DfgConst>();
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 <typename Other, typename Vertex>
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<Other>()) {
if (Other* const rp = rhsp->cast<Other>()) {
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<Other>(vtxp, ap, make<Vertex>(lhsp, bp, cp)));
return true;
}
}
}
}
}
return false;
}
// Bitwise operation with one side Const, and the other side a Concat
template <typename Vertex>
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<DfgOr, DfgAnd>(vtxp)) return;
if (tryPushBitwiseOpThroughReductions(vtxp)) return;
if (DfgNot* const lhsNotp = lhsp->cast<DfgNot>()) {
@ -946,19 +1015,38 @@ class V3DfgPeephole final : public DfgVisitor {
return;
}
}
// ~A & (A & _) or ~A & (_ & A) is all zeroes
if (DfgAnd* const rhsAndp = rhsp->cast<DfgAnd>()) {
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<DfgAnd, DfgOr>(vtxp)) return;
if (tryPushBitwiseOpThroughReductions(vtxp)) return;
if (DfgNot* const lhsNotp = lhsp->cast<DfgNot>()) {
@ -1039,20 +1129,40 @@ class V3DfgPeephole final : public DfgVisitor {
return;
}
}
// ~A | (A | _) or ~A | (_ | A) is all ones
if (DfgOr* const rhsOrp = rhsp->cast<DfgOr>()) {
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<DfgConst>()) {
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<DfgAnd>(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<DfgOr>(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<DfgNot>()) {
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<DfgOr>()) {
if (DfgCond* const thenCondp = thenp->cast<DfgCond>()) {
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<DfgCond>(vtxp, condOrp->lhsp(), thenCondp->thenp(),
make<DfgCond>(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<DfgCond>(vtxp, condOrp->rhsp(), thenCondp->thenp(),
make<DfgCond>(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<DfgAdd>()) {
@ -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<DfgOr>(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<DfgOr>(vtxp, condp, elsep);

View File

@ -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) \

View File

@ -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});

View File

@ -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()