llvm / llvm/llvm-project

bswap optimization breaks when the result is added to a pointer

Open
#168,253 0 comments 0 reactions 0 assignees View on GitHub
llvm:optimizations missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

LLVM seems to detect a byteswapped load and convert it to load + bswap (x86) / load + rev (armv8). But for some reason, if you take the result and add it to a pointer, it breaks the optimization.

Example:
```cpp
uint32_t Load32BE(const uint8_t* data) {
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
}

const uint8_t* Broken(const uint8_t* data, const uint8_t* base) {
return base + Load32BE(data);
}

const uint8_t* Works(const uint8_t* data, const uint8_t* base) {
return reinterpret_cast(reinterpret_cast(base) + Load32BE(data));
}
```

[Godbolt link](https://gcc.godbolt.org/z/vsbv49jE4)

In this example, `Broken` compiles to 4 byte loads and some shifts, while `Works` compiles to one int load and a bswap/rev

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.