[X86] failed to eliminate redundant vroundsd/vroundss before vcvttsd2si/vcvttss2si
- 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
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