llvm / llvm/llvm-project

[InstCombine] failed to eliminate redundant fpclassify check before floor

Open
#198,547 2 comments 0 reactions 0 assignees View on GitHub
llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

found from [mujs](https://github.com/ArtifexSoftware/mujs/blob/master/jsmath.c#L12-L20)

```c
double jsM_round(double x)
{
if (isnan(x)) return x;
if (isinf(x)) return x;
if (x == 0) return x;
if (x > 0 && x < 0.5) return 0;
if (x < 0 && x >= -0.5) return -0;
return floor(x + 0.5);
}
```
```asm
.LCPI0_0:
.quad 0x3fe0000000000000
.LCPI0_1:
.quad 0xbfe0000000000000
jsM_round:
vmovq rax, xmm0
mov cl, 63
bzhi rax, rax, rcx
movabs rcx, 9218868437227405312
cmp rax, rcx
setg cl
sete dl
test rax, rax
sete al
or al, dl
or al, cl
je .LBB0_3
vmovapd xmm1, xmm0
vmovapd xmm0, xmm1
ret
.LBB0_3:
vxorpd xmm1, xmm1, xmm1
vucomisd xmm0, xmm1
jbe .LBB0_5
vmovsd xmm2, qword ptr [rip + .LCPI0_0]
vucomisd xmm2, xmm0
jbe .LBB0_5
.LBB0_2:
vmovapd xmm0, xmm1
ret
.LBB0_5:
vucomisd xmm1, xmm0
jbe .LBB0_7
vucomisd xmm0, qword ptr [rip + .LCPI0_1]
jae .LBB0_2
.LBB0_7:
vaddsd xmm0, xmm0, qword ptr [rip + .LCPI0_0]
vroundsd xmm0, xmm0, xmm0, 9
ret
```

should be:
```c
double jsM_round(double x)
{
//if (isnan(x)) return x;
//if (isinf(x)) return x;
if (x == 0) return x;
//if (x > 0 && x < 0.5) return 0;
if (x < 0 && x >= -0.5) return -0;
return floor(x + 0.5);
}
```
```asm
.LCPI0_0:
.quad 0xbfe0000000000000
.LCPI0_1:
.quad 0x3fe0000000000000
jsM_round:
vmovapd xmm1, xmm0
vxorpd xmm0, xmm0, xmm0
vucomisd xmm1, xmm0
jne .LBB0_2
jp .LBB0_2
vmovapd xmm0, xmm1
ret
.LBB0_2:
vucomisd xmm0, xmm1
jbe .LBB0_4
vucomisd xmm1, qword ptr [rip + .LCPI0_0]
jb .LBB0_4
ret
.LBB0_4:
vaddsd xmm0, xmm1, qword ptr [rip + .LCPI0_1]
vroundsd xmm0, xmm0, xmm0, 9
ret
```
if floor is native, it can be transformed into:
```c
double jsM_round(double x)
{
double r = floor(x + 0.5);
return (r == 0.0) ? copysign(0.0, x) : r;
}
```
```asm
.LCPI0_0:
.quad 0x3fe0000000000000
.LCPI0_1:
.quad 0x8000000000000000
.quad 0x8000000000000000
jsM_round:
vaddsd xmm1, xmm0, qword ptr [rip + .LCPI0_0]
vroundsd xmm1, xmm1, xmm1, 9
vandpd xmm0, xmm0, xmmword ptr [rip + .LCPI0_1]
vxorpd xmm2, xmm2, xmm2
vcmpeqsd xmm2, xmm1, xmm2
vblendvpd xmm0, xmm1, xmm0, xmm2
ret
```
https://test.godbolt.org/z/za31bTYo5

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.