llvm / llvm/llvm-project

LLVM emits late return-value initialization instead of hoisting it before branch conditions

Open
#171,870 3 comments 0 reactions 0 assignees View on GitHub
llvm:optimizations
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.