beflags: transform modifies_flags property into a callback, use default rematerialisa...
[libfirm] / ir / opt / combo.c
index 972bca5..7a0e856 100644 (file)
@@ -2290,6 +2290,37 @@ static void compute_Eor(node_t *node)
        }
 }  /* compute_Eor */
 
+/**
+ * (Re-)compute the type for Cmp.
+ *
+ * @param node  the node
+ */
+static void compute_Cmp(node_t *node)
+{
+       ir_node        *cmp  = node->node;
+       node_t         *l    = get_irn_node(get_Cmp_left(cmp));
+       node_t         *r    = get_irn_node(get_Cmp_right(cmp));
+       lattice_elem_t a     = l->type;
+       lattice_elem_t b     = r->type;
+       ir_mode        *mode = get_irn_mode(get_Cmp_left(cmp));
+
+       if (a.tv == tarval_top || b.tv == tarval_top) {
+               node->type.tv = tarval_top;
+       } else if (r->part == l->part) {
+               /* both nodes congruent, we can probably do something */
+               if (mode_is_float(mode)) {
+                       /* beware of NaN's */
+                       node->type.tv = tarval_bottom;
+               } else {
+                       node->type.tv = tarval_b_true;
+               }
+       } else if (is_con(a) && is_con(b)) {
+               node->type.tv = tarval_b_true;
+       } else {
+               node->type.tv = tarval_bottom;
+       }
+}  /* compute_Cmp */
+
 /**
  * (Re-)compute the type for a Proj(Cmp).
  *
@@ -2310,13 +2341,16 @@ static void compute_Proj_Cmp(node_t *node, ir_node *cmp)
                node->type.tv = tarval_undefined;
        } else if (is_con(a) && is_con(b)) {
                default_compute(node);
-       } else if (r->part == l->part &&
-                  (!mode_is_float(get_irn_mode(l->node)) || pnc == pn_Cmp_Lt || pnc == pn_Cmp_Gt)) {
-               /*
-                * BEWARE: a == a is NOT always True for floating Point values, as
-                * NaN != NaN is defined, so we must check this here.
-                */
-               tv = pnc & pn_Cmp_Eq ? tarval_b_true: tarval_b_false;
+
+       /*
+        * BEWARE: a == a is NOT always True for floating Point values, as
+        * NaN != NaN is defined, so we must check this here.
+        * (while for some pnc we could still optimize we have to stay
+        *  consistent with compute_Cmp, so don't do anything for floats)
+        */
+       } else if (r->part == l->part && !mode_is_float(get_irn_mode(l->node))) {
+
+               tv = pnc & pn_Cmp_Eq ? tarval_b_true : tarval_b_false;
 
                /* if the node was ONCE evaluated by all constants, but now
                   this breaks AND we get from the argument partitions a different
@@ -3444,7 +3478,7 @@ static void apply_result(ir_node *irn, void *ctx)
 static void apply_end(ir_node *end, environment_t *env)
 {
        int i, j,  n = get_End_n_keepalives(end);
-       ir_node **in;
+       ir_node **in = NULL;
 
        if (n > 0)
                NEW_ARR_A(ir_node *, in, n);
@@ -3491,6 +3525,7 @@ static void set_compute_functions(void)
        SET(Sub);
        SET(Eor);
        SET(SymConst);
+       SET(Cmp);
        SET(Proj);
        SET(Confirm);
        SET(Return);