Bug 96779 - Failure to optimize comparison of negative version of self
Summary: Failure to optimize comparison of negative version of self
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: 12.0
Assignee: Andrew Pinski
URL:
Keywords: easyhack, missed-optimization
Depends on:
Blocks: 19987
  Show dependency treegraph
 
Reported: 2020-08-25 12:03 UTC by Gabriel Ravier
Modified: 2023-08-24 21:26 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-08-25 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-08-25 12:03:58 UTC
bool f(int a)
{
    return -a == a;
}

This can be optimized to `return !a;`. This transformation is done by LLVM, but not by GCC.
Comment 1 Richard Biener 2020-08-25 12:14:55 UTC
Confirmed.
Comment 2 Andrew Pinski 2021-07-23 04:02:51 UTC
This is simple, I will take.
(for cmp (eq ne)
 (simplify
  (cmp:c @0 (negate @0))
   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)))
    (cmp:c @0 { build_zero_cst (TREE_TYPE(@0)); })))))

Should be enough.
Comment 3 Andrew Pinski 2021-07-27 20:10:05 UTC
(In reply to Andrew Pinski from comment #2)
> This is simple, I will take.
> (for cmp (eq ne)
>  (simplify
>   (cmp:c @0 (negate @0))
>    (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)))
>     (cmp:c @0 { build_zero_cst (TREE_TYPE(@0)); })))))
> 
> Should be enough.

But it is wrong for wrapping types.

For wrapping types:
-a == a -> (a << 1) == a or (a + a) == 0
But this is worse on targets which have a pattern for -a CMP a (hint aarch64).
So for wrapping types keep the -a == a is the best I think.
Comment 4 Navid Rahimi 2021-11-10 19:50:45 UTC
Hi Andrew,

I just used your code and added a check to check whether the type is wrapping type:


(for cmp (eq ne)
 (simplify
  (cmp:c @0 (negate @0))
   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
        && !TYPE_OVERFLOW_WRAPS (type))
    (cmp:c @0 { build_zero_cst (TREE_TYPE(@0)); })))))

This should work.
Comment 5 Navid Rahimi 2021-11-10 20:18:43 UTC
And this is the behavior of different compilers for this optimization:
 
https://compiler-explorer.com/z/ahdEzxxTv
Comment 6 GCC Commits 2021-11-23 00:48:16 UTC
The master branch has been updated by Jeff Law <law@gcc.gnu.org>:

https://gcc.gnu.org/g:e888bea2384a0d8d29a6545c4f57f41cb49df0a6

commit r12-5458-ge888bea2384a0d8d29a6545c4f57f41cb49df0a6
Author: Navid Rahimi <navidrahimi@microsoft.com>
Date:   Mon Nov 22 19:46:17 2021 -0500

    Re: [PATCH] PR tree-optimization/96779 Adding a missing pattern to match.pd
    
            PR tree-optimization/96779
    gcc/
            * match.pd (-x == x) -> (x == 0): New optimization.
    
    gcc/testsuite
            * gcc.dg/tree-ssa/pr96779.c: Testcase for this optimization.
            * gcc.dg/tree-ssa/pr96779-disabled.c: Testcase for this optimization
            when -fwrapv passed.
Comment 7 Jeffrey A. Law 2021-11-23 00:49:43 UTC
Should be fixed by Navid's patch on the trunk.