Code that should be identical result on a little endian system has different assembly, depending on how you spell it.
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
These two versions of "skip_8th_bits" are equivalent on a little endian system.
```c++
template
inline T loadUnaligned(const void* p) {
T value;
std::memcpy(&value, p, sizeof(T));
return value;
}
std::uint16_t skip_8th_bits_v1(const std::uint8_t* p) {
std::uint16_t lo = p[0] & 0x7f;
std::uint16_t hi = p[1] & 0x7f;
return (hi << 7) | lo;
}
std::uint16_t skip_8th_bits_v2(const std::uint8_t* p) {
uint16_t twoBytes = loadUnaligned(p);
std::uint16_t lo = twoBytes & 0x7f;
std::uint16_t hi = twoBytes & 0x7f00;
return (hi >> 1) | lo;
}
```
However we can see that they give us different assembly
```asm
_Z16skip_8th_bits_v1PKh:
movzx eax, byte ptr [rdi + 1]
movzx ecx, byte ptr [rdi]
and eax, 127
and ecx, 127
shl eax, 7
or eax, ecx
ret
_Z16skip_8th_bits_v2PKh:
movzx eax, word ptr [rdi]
mov ecx, eax
shr eax
and ecx, 127
and eax, 16256
or eax, ecx
ret
```
godbolt: https://godbolt.org/z/sMch3hfM8
Probably should be a correct way to write this?
Contributor guide
Research direction
Reproduce the two C++ functions and their generated assembly using the linked Compiler Explorer example on a little-endian target. Compare the code-generation paths for the byte-wise and unaligned-load forms, then identify the relevant LLVM optimization or code-generation area. Done means the behavior is explained and a focused regression test or accepted resolution is identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 38/100