- vrp_attr *a_vrp, *b_vrp;
-
- if (is_Cmp(a) && is_Cmp(b)) {
- ir_node *a_left = get_Cmp_left(a);
- ir_node *a_right = get_Cmp_right(a);
- ir_node *b_left = get_Cmp_left(b);
- ir_node *b_right = get_Cmp_right(b);
- ir_relation a_relation = get_Cmp_relation(a);
- ir_relation b_relation = get_Cmp_relation(b);
- /* we can combine the relations of two compares with the same
- * operands */
- if (a_left == b_left && b_left == b_right) {
- dbg_info *dbgi = get_irn_dbg_info(n);
- ir_node *block = get_nodes_block(n);
- ir_relation new_relation = a_relation & b_relation;
- return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
- }
- /* 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))) {
- if (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, xora, b_mode);
- ir_node *or = new_rd_Or(dbgi, block, conv, xorb, b_mode);
- ir_graph *irg = get_irn_irg(n);
- ir_node *zero = create_zero_const(irg, b_mode);
- return new_rd_Cmp(dbgi, block, or, zero, ir_relation_equal);
- }
- if (values_in_mode(get_irn_mode(b_left), get_irn_mode(a_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);
- }
- }
- }
-
- mode = get_irn_mode(n);
- HANDLE_BINOP_PHI((eval_func) tarval_and, a, b, c, mode);
-
- if (is_Or(a)) {
- if (is_Not(b)) {
- ir_node *op = get_Not_op(b);
- if (is_And(op)) {
- ir_node *ba = get_And_left(op);
- ir_node *bb = get_And_right(op);
-
- /* it's enough to test the following cases due to normalization! */
- if (get_Or_left(a) == ba && get_Or_right(a) == bb) {
- /* (a|b) & ~(a&b) = a^b */
- ir_node *block = get_nodes_block(n);