llvm / llvm/llvm-project

[X86] failed to eliminate redundant vroundsd/vroundss before vcvttsd2si/vcvttss2si

Open
#202,316 2 comments 0 reactions 0 assignees View on GitHub
backend:X86 missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/svnqhq3jo

```c
#include

long _lroundf (float x){return (long)roundf(x);}

long _lround (double x){return (long)round(x);}

long long _llroundf (float x){return (long long)roundf(x);}

long long _llround (double x){return (long long)round(x);}
```
gcc
```asm
"_lroundf":
vmovss xmm1, DWORD PTR .LC2[rip]
vmovaps xmm2, xmm0
vmovss xmm0, DWORD PTR .LC0[rip]
vandps xmm1, xmm1, xmm2
vorps xmm0, xmm0, xmm1
vaddss xmm0, xmm0, xmm2
vcvttss2si rax, xmm0
ret
"_lround":
vmovsd xmm1, QWORD PTR .LC5[rip]
vmovapd xmm2, xmm0
vmovsd xmm0, QWORD PTR .LC3[rip]
vandpd xmm1, xmm1, xmm2
vorpd xmm0, xmm0, xmm1
vaddsd xmm0, xmm0, xmm2
vcvttsd2si rax, xmm0
ret
"_llroundf":
vmovss xmm1, DWORD PTR .LC2[rip]
vmovaps xmm2, xmm0
vmovss xmm0, DWORD PTR .LC0[rip]
vandps xmm1, xmm1, xmm2
vorps xmm0, xmm0, xmm1
vaddss xmm0, xmm0, xmm2
vcvttss2si rax, xmm0
ret
"_llround":
vmovsd xmm1, QWORD PTR .LC5[rip]
vmovapd xmm2, xmm0
vmovsd xmm0, QWORD PTR .LC3[rip]
vandpd xmm1, xmm1, xmm2
vorpd xmm0, xmm0, xmm1
vaddsd xmm0, xmm0, xmm2
vcvttsd2si rax, xmm0
ret
.LC0:
.long 1056964607
.LC3:
.long -1
.long 1071644671
.LC5:
.long 0
.long -2147483648
```
clang
```asm
.LCPI0_0:
.long 0x3effffff
.LCPI0_1:
.long 0x80000000
_lroundf:
vpbroadcastd xmm1, dword ptr [rip + .LCPI0_0]
vpternlogd xmm1, xmm0, dword ptr [rip + .LCPI0_1]{1to4}, 248
vaddss xmm0, xmm0, xmm1
vroundss xmm0, xmm0, xmm0, 11
vcvttss2si rax, xmm0
ret

.LCPI1_0:
.quad 0x3fdfffffffffffff
.LCPI1_1:
.quad 0x8000000000000000
_lround:
vpbroadcastq xmm1, qword ptr [rip + .LCPI1_0]
vpternlogq xmm1, xmm0, qword ptr [rip + .LCPI1_1]{1to2}, 248
vaddsd xmm0, xmm0, xmm1
vroundsd xmm0, xmm0, xmm0, 11
vcvttsd2si rax, xmm0
ret

.LCPI2_0:
.long 0x3effffff
.LCPI2_1:
.long 0x80000000
_llroundf:
vpbroadcastd xmm1, dword ptr [rip + .LCPI2_0]
vpternlogd xmm1, xmm0, dword ptr [rip + .LCPI2_1]{1to4}, 248
vaddss xmm0, xmm0, xmm1
vroundss xmm0, xmm0, xmm0, 11
vcvttss2si rax, xmm0
ret

.LCPI3_0:
.quad 0x3fdfffffffffffff
.LCPI3_1:
.quad 0x8000000000000000
_llround:
vpbroadcastq xmm1, qword ptr [rip + .LCPI3_0]
vpternlogq xmm1, xmm0, qword ptr [rip + .LCPI3_1]{1to2}, 248
vaddsd xmm0, xmm0, xmm1
vroundsd xmm0, xmm0, xmm0, 11
vcvttsd2si rax, xmm0
ret
```
llvm's problem is failing to realize that vround is redundant here, otherwise it is doing better than gcc.

Contributor guide

Open the contributing guide

Research direction

Start with the Godbolt reproducer and C functions in the issue, then compare the clang-generated x86 assembly with the expected instruction sequence. Trace the LLVM x86 optimization or lowering path responsible for vroundsd/vroundss before vcvttsd2si/vcvttss2si; done means the redundant vround instruction is eliminated without changing the generated conversions.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
compilers, performance
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.