Bug 97603 - Failure to optimize out compare into reuse of subtraction result
Summary: Failure to optimize out compare into reuse of subtraction result
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 11.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on: 3507 94798
Blocks:
  Show dependency treegraph
 
Reported: 2020-10-27 22:01 UTC by Gabriel Ravier
Modified: 2023-09-21 10:57 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-10-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gabriel Ravier 2020-10-27 22:01:48 UTC
int g();

int f(int a, int b)
{
    if (a != b)
        return a - b;
    return g();
}

This can be optimized to using the result of `a - b` to check for `a != b`. This is done by LLVM, but not by GCC. For example, on x86, LLVM generates this :

f(int, int):
  sub edi, esi
  jne .LBB0_1
  jmp g()
.LBB0_1:
  mov eax, edi
  ret

GCC generates this :

f(int, int):
  cmp edi, esi
  je .L7
  mov eax, edi
  sub eax, esi
  ret
.L7:
  jmp g()
Comment 1 Hongtao.liu 2020-10-28 04:52:00 UTC
Shouldn't it be marked as target issue for x86?
Comment 2 Hongtao.liu 2020-10-28 04:58:44 UTC
(In reply to Hongtao.liu from comment #1)
> Shouldn't it be marked as target issue for x86?

Or you means that middle-end should transform code to

int g();

int f(int a, int b)
{
  int c = a - b;
  if (c)
    return c;
  return g();
}
Comment 3 Gabriel Ravier 2020-10-28 08:05:19 UTC
Well, I don't actually know enough to be able to determine which would be optimal. Transformation to the example from the third comment would be suboptimal on some targets (say, I don't think AVR would like this for 64-bit numbers), while doing this as an x86 specific transformation would be missing on an optimization opportunity on plenty of other targets.
Comment 4 Richard Biener 2020-10-28 09:26:14 UTC
I guess it could be formulated as code-hoisting opportunity when we make
a - b (or b - a) anticipated on the edges from the a != b compare.  What's
then missing is transforming

  int tem = a - b;
  if (a != b)
     ...

into

  tem = a - b;
  if (tem != 0)

but IIRC we essentially do the reverse transform via match.pd.  Here
the main issue is that the GIMPLE IL doesn't reflect what targets
usually do, that is, flags registers are not modeled and instead we
branch on the actual compare rather than its outcome and a subtract
doesn't set flags.

Eventually this is sth for RTL if-conversion though where those details
are exposed.