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

            Bug ID: 121591
           Summary: x86 optimization: isless doesn't reuse EFLAGS result
                    of other floating point comparisons with same operands
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

This issue seems to be architecture specific. I can reproduce it for x86-64
target but not for ARM64 target.

Test code (same as in bug 121590):

```c
#include <math.h>
#include <stdlib.h>

int float_compare(double a, double b) {
    if (isless(a, b))
        return 1;
    if (isgreater(a, b))
        return 3;
    if (isunordered(a, b))
        return 4;
    if (a == b)   
        return 2;
    // Should never reach here
    abort();
}
```

x86_64 gcc 15.1 with '-O2 -Wno-float-equal' options produces:

```assembly
float_compare:
        ucomisd %xmm0, %xmm1
        ja      .L14
        ucomisd %xmm1, %xmm0
        ja      .L15
        jp      .L8
        jne     .L13
        movl    $2, %eax
        ret
.L14:
        movl    $1, %eax
        ret
.L8:
        movl    $4, %eax
        ret
.L15:
        movl    $3, %eax
        ret
float_compare.cold:
.L13:
        pushq   %rax
        call    abort
```

(I tested this in Compiler Explorer (godbolt.org))

(The abort() function call is redundant. I've reported that part of the issue
as bug 121590.)

The point to note in this generated assembly is that isless() produces an
"ucomisd %xmm0, %xmm1" instruction on its own. Ideally only one "ucomisd"
instruction is needed, as the EFLAGS result can be reused for different jumps.

Reply via email to