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

            Bug ID: 122286
           Summary: fold (a < b) ? -1 : (a > b ? 1 : 0) into (a < b) - (a
                    > b) or the other way around
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: manu at gcc dot gnu.org
  Target Milestone: ---

These 3 functions generate completely different assembler:
__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math"))) int cmp_double_asc(double a, double b) {      return (a
< b) ? -1 : (a > b ? 1 : 0); }  int cmp_double_asc_2(double a, double b) {    
return (a < b) ? -1 : (a > b
__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math")))
int cmp_double_asc(double a, double b) {
     return (a < b) ? -1 : (a > b ? 1 : 0);
}

int cmp_double_asc_2(double a, double b) {
    return (a < b) ? -1 : (a > b ? 1 : 0);
}

__attribute__((optimize("-ffinite-math-only","-fno-signaling-nans",
"-fno-trapping-math")))
int cmp_double_asc_branchless(double a, double b) {
    return (a < b) - (a > b);
}

with gcc -O3 -march=x86-64-v4

"cmp_double_asc":
        xor     eax, eax
        vcomisd xmm0, xmm1
        mov     edx, -1
        seta    al
        cmovb   eax, edx
        ret
"cmp_double_asc_2":
        vcomisd xmm1, xmm0
        mov     eax, -1
        ja      .L7
        xor     eax, eax
        vcomisd xmm0, xmm1
        seta    al
.L7:
        ret
"cmp_double_asc_branchless":
        xor     eax, eax
        vcomisd xmm1, xmm0
        seta    al
        xor     edx, edx
        vcomisd xmm0, xmm1
        seta    dl
        sub     eax, edx
        ret


I can understand why the second function without extra optimize options may be
different, but the first and third functions should generate the same code, no?

https://godbolt.org/z/oT7jc7Thd

Reply via email to