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

--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
But then

void foo (void);
void bar (void);

int
test (int a)
{
  if (a)
    foo ();
  else
    bar ();

  return -a;
}

is not optimized either (the usual argument - the user could have written it
in the way the compiler canonicalizes).

On RTL where the CCs are appearant that's a LCM / PRE problem with the
compare anticipating the zero flag here and the negate computing it.
That makes it profitable to move the negate and eliminate the CC flag
compute with it (for the testcase above).

On the original case where we have

int
test (int a)
{
  int r = -a;
  if (a)
    foo ();
  else
    bar ();

  return r;
}

that's more a local CSE opportunity (though of course for this modified
testcase we sink the -a compute to the return, re-creating the first
case in this comment).

As it is only RTL representing CC at all this is really a RTL global
optimization issue in the end.  GIMPLE can only help to a limited extent
and all missed canonicalization (like if we add a single_use check)
eventually leads to missed global CSE opportunities.

Reply via email to