Issue 155584
Summary (u)comiss instructions not merged together in comparison chains
Labels new issue
Assignees
Reporter purplesyringa
    https://godbolt.org/z/a1f4hrPzT

```c
enum Ordering {
    LESS = -1,
    EQUAL = 0,
    GREATER = 1,
    UNORDERED = 2
};

enum Ordering compare(float a, float b) {
    if (a < b) {
 return LESS;
    } else if (a == b) {
        return EQUAL;
    } else if (a > b) {
        return GREATER;
    } else {
        return UNORDERED;
 }
}

int another_example(float a, float b) {
    if (a < b) {
 return 1;
    } else if (a <= b) {
        return 2;
    } else {
 return 3;
    }
}
```

```x86asm
compare:
        mov     eax, -1
 ucomiss xmm1, xmm0
        ja      .LBB0_3
        xor     eax, eax
 ucomiss xmm0, xmm1
        jne     .LBB0_2
        jp .LBB0_2
.LBB0_3:
        ret
.LBB0_2:
        setbe   al
        movzx eax, al
        inc     eax
        ret

another_example:
        xor ecx, ecx
        ucomiss xmm1, xmm0
        adc     ecx, 2
 ucomiss xmm1, xmm0
        mov     eax, 1
        cmovbe  eax, ecx
 ret
```

I see no good reason why the partial ordering implementation cannot emit `ucomiss` just once, e.g.

```x86asm
compare:
        ucomiss xmm0, xmm1
        mov eax, 2
        jp .exit
        mov eax, -1
 jb .exit
        seta al
.exit:
        ret
```

`another_example` looks even more straight-forward, with operands not even swapped.

`ucomiss` is not exactly slow, but it's not fast either, so surely this is a missed optimization?
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to