summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/ir.c b/ir.c
index a6f0c04..1449281 100644
--- a/ir.c
+++ b/ir.c
@@ -482,6 +482,11 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
&& C(CADR(n), CDR(n))) {
return OP(OP(CAAR(n), CDR(n)), CADR(n));
}
+
+ /* op(not(X), Y) -> op(Y, not(X)) */
+ if (CAR(n)->type == N_OP_NOT && CDR(n)->type != N_OP_NOT) {
+ return NODE(n->type, CDR(n), CAR(n));
+ }
}
/* optimize based on situations where the input is partly known (e.g.
@@ -499,7 +504,6 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (same) return NODE(N_OP_MUL, CAR(n), node_new_lit_i64(p, 2));
if (CAR(n)->val.type.t == T_INT) {
/* a + ~a = -1 */
- if (T(CAR(n), N_OP_NOT) && node_equiv(CAAR(n), CDR(n))) return node_new_lit_i64(p, -1);
if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) return node_new_lit_i64(p, -1);
}
if (T(CAR(n), N_OP_NEG)) return NODE(N_OP_SUB, CDR(n), CAAR(n));
@@ -537,7 +541,6 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (same) return CAR(n);
if (BOOL_EQ(CDR(n), 1)) return CAR(n);
if (is_zero(CDR(n))) return node_new_zero(p, CDR(n));
- if (T(CAR(n), N_OP_NOT) && node_equiv(CAAR(n), CDR(n))) return node_new_zero(p, CDR(n));
if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) return node_new_zero(p, CAR(n));
if (node_cmp_incompat(CAR(n)->type, CDR(n)->type) && node_equiv_input(CAR(n), CDR(n))) {
return node_new_lit_bool(p, 0);
@@ -548,10 +551,11 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (node_cmp_opposite(CAR(n)->type, CDR(n)->type) && node_equiv_input(CAR(n), CDR(n))) {
return node_new_lit_bool(p, 1);
}
- if (CAR(n)->val.type.t == T_INT) {
- /* a ^ ~a = -1 */
- if (T(CAR(n), N_OP_NOT) && node_equiv(CAAR(n), CDR(n))) return node_new_lit_i64(p, -1);
- if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) return node_new_lit_i64(p, -1);
+ /* bool ^ ~bool = 1 */
+ /* i64 ^ ~i64 = -1 */
+ if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) {
+ if (CAR(n)->val.type.t == T_INT) return node_new_lit_i64(p, -1);
+ if (CAR(n)->val.type.t == T_BOOL) return node_new_lit_bool(p, 1);
}
zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
if (node_eql_i64(CDR(n), 0)) return CAR(n);
@@ -560,6 +564,7 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
if (same) return node_new_lit_bool(p, 1);
if (BOOL_EQ(CDR(n), 1)) return CAR(n);
if (BOOL_EQ(CDR(n), 0)) return NODE(N_OP_NOT, CAR(n));
+ if (CDR(n)->type == N_OP_NOT && node_equiv(CAR(n), CDAR(n))) return node_new_lit_bool(p, 0);
break;
case N_CMP_NEQ:
if (same) return node_new_lit_bool(p, 0);