https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112900

            Bug ID: 112900
           Summary: Missing optimization: canonicalize `select c, x - 1, x
                    + 1` to `x + (select c, -1, 1)`  (or reversely)
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xxs_chy at outlook dot com
  Target Milestone: ---

GCC works much better on folding branches into select than llvm for:
https://godbolt.org/z/jWzePjqTs

But GCC seems to generate different X86 assembly for the code
below(https://godbolt.org/z/Erq56Tbjq):

int src(int x, int y, bool cond) {
    return (x > y ? x - 1 : x + 1);
}

int tgt(int x, int y, bool cond) {
    return x + (x > y ? -1 : 1);
}

For `src`, we compute both `x-1` and `x+1` and apply `cmov` to return one of
them.
For `tgt`, we fold `(x > y ? -1 : 1)` to `(x > y) * 2 - 1`.

LLVM prefers the latter, so I think it may be better to canonicalize `select c,
x - 1, x + 1` to `x + (select c, -1, 1)`. Though it's uncanonicalized in
tree-optimization stage, please let me know if there is other backend's factors
like ILP deciding that.

Reply via email to