From a91fca16568584a9d18160819a4e56d1c4c1c00a Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Tue, 5 Aug 2025 03:07:49 -0400 Subject: add a bunch of rules to simplify comparisons --- ir.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/ir.c b/ir.c index 6bd1313..4f360b5 100644 --- a/ir.c +++ b/ir.c @@ -261,6 +261,14 @@ static inline int node_op_associative(NodeType t) { return 0; } +static inline int node_op_comparison(NodeType t) { + NodeType ops[] = { N_CMP_EQL, N_CMP_NEQ, N_CMP_LES, N_CMP_GTR, N_CMP_LTE, N_CMP_GTE }; + for (unsigned i = 0; i < sizeof ops / sizeof *ops; i++) { + if (ops[i] == t) return 1; + } + return 0; +} + /* when applied to the same input, at least one must be true */ static inline NodeType node_cmp_opposite(NodeType a) { struct { NodeType l, r; } pairs[] = { @@ -275,6 +283,16 @@ static inline NodeType node_cmp_opposite(NodeType a) { return N_NONE; } +static inline NodeType node_cmp_flip_sign(NodeType a) { + switch (a) { + case N_CMP_LES: return N_CMP_GTR; + case N_CMP_LTE: return N_CMP_GTE; + case N_CMP_GTR: return N_CMP_LES; + case N_CMP_GTE: return N_CMP_LTE; + default: return a; + } +} + /* when applied to the same input, at least one must be false */ static inline int node_cmp_incompat(NodeType a, NodeType b) { struct { NodeType l, r; } pairs[] = { @@ -661,6 +679,29 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); break; } + if (node_op_comparison(n->type)) { + if (T(CAR(n), N_OP_SHL) && T(CDR(n), N_OP_ADD) && node_eql_i64(CADR(n), 1)) { + if (node_equiv(CAAR(n), CDAR(n))) return NODE(n->type, CAAR(n), CDDR(n)); + if (node_equiv(CAAR(n), CDDR(n))) return NODE(n->type, CAAR(n), CDAR(n)); + } + if (T(CDR(n), N_OP_SHL) && T(CAR(n), N_OP_ADD) && node_eql_i64(CDDR(n), 1)) { + if (node_equiv(CDAR(n), CAAR(n))) return NODE(n->type, CDAR(n), CADR(n)); + if (node_equiv(CDAR(n), CADR(n))) return NODE(n->type, CDAR(n), CAAR(n)); + } + if (node_op_associative(CAR(n)->type) && T(CAR(n), CDR(n)->type)) { + if (node_equiv(CAAR(n), CDAR(n))) return NODE(n->type, CADR(n), CDDR(n)); + if (node_equiv(CADR(n), CDAR(n))) return NODE(n->type, CAAR(n), CDDR(n)); + if (node_equiv(CAAR(n), CDDR(n))) return NODE(n->type, CADR(n), CDAR(n)); + if (node_equiv(CADR(n), CDDR(n))) return NODE(n->type, CAAR(n), CDAR(n)); + } + if (T(CAR(n), N_OP_SUB) && T(CAR(n), N_OP_SUB) && node_equiv(CAAR(n), CDAR(n))) { + return NODE(node_cmp_flip_sign(n->type), CADR(n), CDDR(n)); + } + if (T(CAR(n), N_OP_NEG) && T(CDR(n), N_OP_NEG)) { + return NODE(node_cmp_flip_sign(n->type), CAAR(n), CDAR(n)); + } + } + return NULL; } -- cgit v1.2.3