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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
This should do it I think:

(for neeq (ne eq)
 (simplify
  (neeq (plus zero_one_valued_p@0 zero_one_valued_p@1) INTEGER_CST@2)
  (with {
    tree_code newcode = ERROR_MARK;
    bool notatend = false;
    tree cst1 = build_one_cst (type);
    wide_int cst = wi::to_wide (@2);
    // a + b == 2 -> a & b
    // a + b != 2 -> ~(a & b)
    if (cst == 2)
      newcode = BIT_AND_EXPR, notatend = neeq == NE_EXPR;
    // a + b == 1 -> a ^ b
    // a + b != 1 -> ~(a ^ b) -> a == b
    else if (cst == 1)
      newcode = BIT_XOR_EXPR, notatend = neeq == NE_EXPR;
    // a + b == 0 -> ~(a | b)
    // a + b != 0 -> a | b
    else if (cst == 0)
      newcode = BIT_IOR_EXPR, notatend = neeq == EQ_EXPR;
   }
  (if (notatend)
   (switch
    (if (newcode == BIT_IOR_EXPR)
     (bit_xor (bit_ior @0 @1) { cst1; }))
    (if (newcode == BIT_AND_EXPR)
     (bit_xor (bit_and @0 @1) { cst1; }))
    (if (newcode == BIT_XOR_EXPR)
     (eq @0 @1)))
   (switch
    (if (newcode == BIT_IOR_EXPR)
     (bit_ior @0 @1))
    (if (newcode == BIT_AND_EXPR)
     (bit_and @0 @1))
    (if (newcode == BIT_XOR_EXPR)
     (bit_xor @0 @1)))
  )
 )
)

Reply via email to