ir_relation new_relation = a_relation & b_relation;
return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
}
- /* Cmp(a==0) and Cmp(b==0) can be optimized to Cmp(a|b==0) */
- if (is_Const(a_right) && is_Const_null(a_right)
- && is_Const(b_right) && is_Const_null(b_right)
- && a_relation == b_relation && a_relation == ir_relation_equal
- && !mode_is_float(get_irn_mode(a_left))
- && !mode_is_float(get_irn_mode(b_left))) {
- dbg_info *dbgi = get_irn_dbg_info(n);
- ir_node *block = get_nodes_block(n);
- ir_mode *mode = get_irn_mode(a_left);
- ir_node *n_b_left = get_irn_mode(b_left) != mode ?
- new_rd_Conv(dbgi, block, b_left, mode) : b_left;
- ir_node *or = new_rd_Or(dbgi, block, a_left, n_b_left, mode);
- ir_graph *irg = get_irn_irg(n);
- ir_node *zero = create_zero_const(irg, mode);
+ /* Cmp(a==b) and Cmp(c==d) can be optimized to Cmp((a^b)|(c^d)==0) */
+ if (a_relation == b_relation && a_relation == ir_relation_equal
+ && !mode_is_float(get_irn_mode(a_left))
+ && !mode_is_float(get_irn_mode(b_left))
+ && values_in_mode(get_irn_mode(a_left), get_irn_mode(b_left))) {
+ dbg_info *dbgi = get_irn_dbg_info(n);
+ ir_node *block = get_nodes_block(n);
+ ir_mode *a_mode = get_irn_mode(a_left);
+ ir_mode *b_mode = get_irn_mode(b_left);
+ ir_node *xora = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
+ ir_node *xorb = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
+ ir_node *conv = new_rd_Conv(dbgi, block, xorb, a_mode);
+ ir_node *or = new_rd_Or(dbgi, block, xora, conv, a_mode);
+ ir_graph *irg = get_irn_irg(n);
+ ir_node *zero = create_zero_const(irg, a_mode);
return new_rd_Cmp(dbgi, block, or, zero, ir_relation_equal);
}
}
return n;
} /* transform_node_Or_Rotl */
-static bool is_cmp_unequal_zero(const ir_node *node)
+static bool is_cmp_unequal(const ir_node *node)
{
ir_relation relation = get_Cmp_relation(node);
ir_node *left = get_Cmp_left(node);
ir_node *right = get_Cmp_right(node);
ir_mode *mode = get_irn_mode(left);
- if (!is_Const(right) || !is_Const_null(right))
- return false;
- if (mode_is_signed(mode)) {
- return relation == ir_relation_less_greater;
- } else {
+ if (relation == ir_relation_less_greater)
+ return true;
+
+ if (!mode_is_signed(mode) && is_Const(right) && is_Const_null(right))
return relation == ir_relation_greater;
- }
+ return false;
}
/**
ir_relation new_relation = a_relation | b_relation;
return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
}
- /* Cmp(a!=0) or Cmp(b!=0) => Cmp(a|b != 0) */
- if (is_cmp_unequal_zero(a) && is_cmp_unequal_zero(b)
- && !mode_is_float(get_irn_mode(a_left))
- && !mode_is_float(get_irn_mode(b_left))) {
- ir_graph *irg = get_irn_irg(n);
- dbg_info *dbgi = get_irn_dbg_info(n);
- ir_node *block = get_nodes_block(n);
- ir_mode *mode = get_irn_mode(a_left);
- ir_node *n_b_left = get_irn_mode(b_left) != mode ?
- new_rd_Conv(dbgi, block, b_left, mode) : b_left;
- ir_node *or = new_rd_Or(dbgi, block, a_left, n_b_left, mode);
- ir_node *zero = create_zero_const(irg, mode);
+ /* Cmp(a!=b) or Cmp(c!=d) => Cmp((a^b)|(c^d) != 0) */
+ if (is_cmp_unequal(a) && is_cmp_unequal(b)
+ && !mode_is_float(get_irn_mode(a_left))
+ && !mode_is_float(get_irn_mode(b_left))
+ && values_in_mode(get_irn_mode(a_left), get_irn_mode(b_left))) {
+ ir_graph *irg = get_irn_irg(n);
+ dbg_info *dbgi = get_irn_dbg_info(n);
+ ir_node *block = get_nodes_block(n);
+ ir_mode *a_mode = get_irn_mode(a_left);
+ ir_mode *b_mode = get_irn_mode(b_left);
+ ir_node *xora = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
+ ir_node *xorb = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
+ ir_node *conv = new_rd_Conv(dbgi, block, xorb, a_mode);
+ ir_node *or = new_rd_Or(dbgi, block, xora, conv, a_mode);
+ ir_node *zero = create_zero_const(irg, a_mode);
return new_rd_Cmp(dbgi, block, or, zero, ir_relation_less_greater);
}
}