https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Here is what I have so far without the cost model:

  /* Hand bool0 CMP bool1 because bitwise operators
     are normally better than comparisons.  */
  if (INTEGRAL_TYPE_P (type)
      && ((tree_nonzero_bits (arg0) == 1 && tree_nonzero_bits (arg1) == 1)
          || (unsignedp && TYPE_PRECISION (type) == 1)))
    {
      tree b0 = arg0;
      tree b1 = arg1;
      bool not_p = false;
      bool operand1_not_p = false;
      tree_code code = ERROR_MARK;
      switch (ops->code)
        {
        case EQ_EXPR:
          not_p = true;
          code = BIT_XOR_EXPR;
          break;
        case NE_EXPR:
          code = BIT_XOR_EXPR;
          break;
        case GT_EXPR:
          std::swap (b0, b1);
          code = BIT_AND_EXPR;
          operand1_not_p = true;
          break;
        case LT_EXPR:
          code = BIT_AND_EXPR;
          operand1_not_p = true;
          break;
        case GE_EXPR:
          std::swap (b0, b1);
          code = BIT_IOR_EXPR;
          operand1_not_p = true;
          break;
        case LE_EXPR:
          code = BIT_IOR_EXPR;
          operand1_not_p = true;
          break;
        default:
          code = ERROR_MARK;
          break;
        }
      if (code != ERROR_MARK)
        {
          tree exp;
          tree one = build_int_cst (type, 1);
          if (operand1_not_p)
            b0 = build2_loc (loc, BIT_XOR_EXPR, type, b0, one);
          exp = build2_loc (loc, code, type, b0, b1);
          if (not_p)
            exp = build2_loc (loc, BIT_XOR_EXPR, type, exp, one);
          return expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
        }
    }

Reply via email to