Bug 106420 - Missed optimization for comparisons
Summary: Missed optimization for comparisons
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2022-07-23 09:25 UTC by zero
Modified: 2024-01-04 16:56 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Sample code (100 bytes, text/plain)
2022-07-23 09:25 UTC, zero
Details

Note You need to log in before you can comment on or make changes to this bug.
Description zero 2022-07-23 09:25:36 UTC
Created attachment 53339 [details]
Sample code

When comparing different variables to the same constants, in some cases the compiler could first combine the variables and then do a single compare.  In the sample given, two variables are compared against 7.  In the slow path, GCC produces the following with -O2.

        cmp     edi, 7
        setg    al
        cmp     esi, 7
        setg    dl
        or      eax, edx
        movzx   eax, al
        ret

In the fast path, GCC produces this instead.

        or      edi, esi
        xor     eax, eax
        cmp     edi, 7
        setg    al
        ret

Although the expression a > 7 || b > 7 is the same as (a | b) > 7, the latter is better because it results in fewer instructions.  A quick experiment shows the latter also runs quite faster.

Verified with Godbolt for GCC trunk.  Clang, ICC, and MSVC latest versions also miss this opportunity as per Godbolt.
Comment 1 zero 2022-07-23 09:38:17 UTC
(it should be possible to massage the output further to use test and setne, which ICC prefers to e.g. cmp and seta)
Comment 2 Hongtao.liu 2022-07-25 02:12:50 UTC
> Although the expression a > 7 || b > 7 is the same as (a | b) > 7, the
Shoudn't the optimization be available for unsigned type only?
Comment 3 Andrew Pinski 2022-07-25 02:23:32 UTC
This can only be done for unsigned types as if either one was negative, then the check becames invalid.
It is already done since GCC 11 (most likely the patch which fixed PR 95731).

So this is invalid.
Comment 4 zero 2022-07-25 02:35:36 UTC
Sorry about that :/.