llvm / llvm/llvm-project

Suboptimal/inconsistent codegen — clang doesn't realize an instruction save unless a while loop is manually transformed

Open
#160,714 0 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

Given the following simple C++ function, which counts the number of holes in the numbers in the string: (0,4,6,9 have 1 hole, 8 has two holes) (the same code as #160710):
```cpp
#include
#include
using ui = std::uint_fast32_t;
using uc = std::uint_fast8_t;
ui countholes(const char* s){
constexpr static std::array pre_table{1,0,0,0,1,0,1,0,2,1};
uc c;
ui tot = 0;
while(true){
c = uc(*s++);
if(c
#include
using ui = std::uint_fast32_t;
using uc = std::uint_fast8_t;
extern "C" ui countholes(const char* s){
constexpr static std::array pre_table{1,0,0,0,1,0,1,0,2,1};
uc c;
ui tot = 0;
c = uc(*s++);
if(c=uc('0'));
return tot;
}
```
The assembly output is:
```asm
; SNIP
.LBB0_4:
movzx ecx, cl
add rax, qword ptr [rdx + 8*rcx - 384]
movzx ecx, byte ptr [rdi]
inc rdi
cmp cl, 47
ja .LBB0_4
ret
```
Notice how the `-384` displacement is now added onto the effective address, and the add to `ecx` is gone. For some reason, the compiler doesn't realize the optimization unless the loop is inverted.

Contributor guide

Open the contributing guide

Research direction

No source file or test is named. Start by compiling the provided C++ reproducer and comparing the two Godbolt assembly outputs, then trace the relevant loop and addressing transformations in LLVM's compiler pipeline. Done means identifying the missed code-generation opportunity and adding a regression test that distinguishes the original loop form from the manually inverted form.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.