Suboptimal/inconsistent codegen — clang doesn't realize an instruction save unless a while loop is manually transformed
- 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
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