From a4f6a42d8f76a34b58d7b8d8963cb268c8962489 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Tue, 5 Aug 2025 01:02:45 -0400 Subject: known-not-equivalent identities: a [+/-] lit[x, x =/= 0] --- ir.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'ir.c') diff --git a/ir.c b/ir.c index f8c18f5..d681d9c 100644 --- a/ir.c +++ b/ir.c @@ -384,6 +384,16 @@ static inline int node_equiv(Node *a, Node *b) { return 1; } +/* of necessity, this has to be pretty conservative */ +/* TODO: figure out a more thorough way of comparing node graphs */ +static inline int node_known_not_equiv_ord(Node *a, Node *b) { + if ((T(b, N_OP_ADD) || T(b, N_OP_SUB)) && node_equiv(a, CAR(b)) && !node_eql_i64(CDR(b), 0)) return 1; + return 0; +} +static inline int node_known_not_equiv(Node *a, Node *b) { + return node_known_not_equiv_ord(a, b) || node_known_not_equiv_ord(b, a); +} + static inline int node_equiv_input(Node *a, Node *b) { if (a->in.len != b->in.len) return 0; for (int i = 0; i < a->in.len; i++) { @@ -563,12 +573,16 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); break; case N_CMP_EQL: if (same) return node_new_lit_bool(p, 1); + if (node_known_not_equiv(CAR(n), CDR(n))) return node_new_lit_bool(p, 0); if (BOOL_EQ(CDR(n), 1)) return CAR(n); if (BOOL_EQ(CDR(n), 0)) return NODE(N_OP_NOT, CAR(n)); if (T(CAR(n), N_OP_NOT) && node_equiv(CDR(n), CAAR(n))) return node_new_lit_bool(p, 0); break; case N_CMP_NEQ: if (same) return node_new_lit_bool(p, 0); + if (node_known_not_equiv(CAR(n), CDR(n))) return node_new_lit_bool(p, 1); + if (BOOL_EQ(CDR(n), 0)) return CAR(n); + if (BOOL_EQ(CDR(n), 1)) return NODE(N_OP_NOT, CAR(n)); break; case N_CMP_LES: if (same) return node_new_lit_bool(p, 0); -- cgit v1.2.3