[Bug tree-optimization/112628] `~a < -a` can be optimized to `a != 0` for unsigned types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112628 --- Comment #2 from Andrew Pinski --- For signed, it is just true. That is: ``` int f(int a) { return (~a) < -a; } int f0(int a) { return (a) > ~(-a); } ``` Are the same. In fact we can optimize even more: ``` int feq(int a) { return (~a) == -a; } ``` is always false for both signed and unsigned types. So we just do `~a CMP -a` -> `(a - 1) CMP a` for all types. Which is what we do for: `/* Fold ~X op ~Y as Y op X. */` So it is just ``` /* Fold ~X op -Y as (~(-Y)) op X. or `(Y-1) op X` */ (for cmp (simple_comparison) (simplify (cmp:c (bit_not @0) (negative @1)) (cmp (plus @1 { build_minus_one_cst (TREE_TYPE (@0)); }) @0))) ```
[Bug tree-optimization/112628] `~a < -a` can be optimized to `a != 0` for unsigned types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112628 Andrew Pinski changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2023-11-19 Status|UNCONFIRMED |ASSIGNED Assignee|unassigned at gcc dot gnu.org |pinskia at gcc dot gnu.org --- Comment #1 from Andrew Pinski --- Note also we should be optimize this at the gimple level too: ``` unsigned f1(unsigned a, unsigned *c) { return __builtin_add_overflow(a,-a,c); } ``` into: ``` unsigned f1(unsigned a, unsigned *c) { *c = 0; return a != 0; } ``` Or the gimple level format: ``` _1 = -a_4(D); _5 = .ADD_OVERFLOW (_1, a_4(D)); _2 = REALPART_EXPR <_5>; *c_7(D) = _2; _3 = IMAGPART_EXPR <_5>; ``` Into: ``` _tmp = a != 0; _5 = COMPLEX_EXPR<0, _tmp>; ... ``` Mine.