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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So GCC already converts the following two functions at the gimple level:
  int f1 (int x) { return x - (x & 1); }
  char *g1 (char *x) { return x - ((__UINTPTR_TYPE__) x & 1); }
----- CUT ----
Even on the RTL level too, I Noticed that because the original testcase does
the correct thing for aarch64, why it is not done for x86_64 I don't know.


Anyways what we could do is take:
  if (_2 != 0)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870913]:
  iftmp.1_5 = x_4(D) + 18446744073709551615;

  <bb 4> [local count: 1073741824]:
  # iftmp.1_3 = PHI <iftmp.1_5(3), x_4(D)(2)>

And convert that too:
iftmp.1_3 = x - (type)(_2 != 0)

So something simple as:
(simplify
 (cond @0 (plus @1 integer_all_onesp@2) @1)
 (minus @1 (convert @0)))


If you want to handle case where @2 is a power of 2 instead so you can use
shift, that is another option.

Reply via email to