LLVM emits late return-value initialization instead of hoisting it before branch conditions
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
For the following code, one can get a quite nice ASM output both for x86-64 and Arm v8 (`-O3`). See the code here: https://godbolt.org/z/3xjhKf79T. RISC-V have similar ASM.
```cpp
#include
int sum(const std::vector vec) {
int total = 0;
for(std::size_t index = 0; index != vec.size(); index++) {
total += vec[index];
}
return total;
}
```
However, in both cases, at the entering to function, I see the following pattern:
```asm
sum(std::vector>):
mov rcx, qword ptr [rdi]
mov rdx, qword ptr [rdi + 8]
sub rdx, rcx
je .LBB0_1
sar rdx, 2
cmp rdx, 8
jae .LBB0_6
xor esi, esi
xor eax, eax <- set return register to 0
jmp .LBB0_5
.LBB0_1:
xor eax, eax <- set return register to 0
jmp .LBB0_2
.LBB0_6:
```
Later, this register is used only for keeping `total`. So, then, instruction can be resorted as follows:
```asm
sum(std::vector>):
mov rcx, qword ptr [rdi]
mov rdx, qword ptr [rdi + 8]
xor eax, eax <- set return register to 0
sub rdx, rcx
je .LBB0_1
sar rdx, 2
cmp rdx, 8
jae .LBB0_6
xor esi, esi
jmp .LBB0_5
.LBB0_1:
jmp .LBB0_2
.LBB0_6:
```
And with optimized jumps:
```asm
sum(std::vector>):
mov rcx, qword ptr [rdi]
mov rdx, qword ptr [rdi + 8]
xor eax, eax <- set return register to 0
sub rdx, rcx
je .LBB0_2
sar rdx, 2
cmp rdx, 8
jae .LBB0_6
xor esi, esi
jmp .LBB0_5
.LBB0_6:
```
The same approach can be used also for Arm v8 and RISC-V.
Contributor guide
Research direction
Start with the Godbolt reproducer linked in the issue and compile it at -O3 for x86-64, Armv8, and RISC-V. Compare the generated assembly around the loop-entry branches; done means the return-value initialization is hoisted before those conditions and redundant jumps are eliminated where applicable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100