bool f(int a) { return -a == a; } This can be optimized to `return !a;`. This transformation is done by LLVM, but not by GCC.
Confirmed.
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.
(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.
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.
And this is the behavior of different compilers for this optimization: https://compiler-explorer.com/z/ahdEzxxTv
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.
Should be fixed by Navid's patch on the trunk.