AArch64 missed optimization: 32-bit narrowing prevents shifted-register EOR selection
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
It seems that premature 32-bit narrowing can prevent right shift and XOR operations from being combined into a single A64 instruction.
[Compile](https://godbolt.org/z/xhWP8s6ev) the following code with `clang -target arm64-apple-macosx15.0 -O3 -S tmp.cpp` (version `17.0.0`):
```C++
#include
using Bits = std::uint64_t;
Bits left_full(Bits bits) {
return ((bits << 30) ^ bits) & 0x100000000;
}
Bits right_full(Bits bits) {
return ((bits >> 30) ^ bits) & 0x100000000;
}
Bits left_opt(Bits bits) {
return ((bits << 30) ^ bits) & 0x10000000;
}
Bits right_opt(Bits bits) {
return ((bits >> 30) ^ bits) & 0x10000000;
}
```
The result is:
```asm
left_full(unsigned long):
eor x8, x0, x0, lsl #30
and x0, x8, #0x100000000
ret
right_full(unsigned long):
eor x8, x0, x0, lsr #30
and x0, x8, #0x100000000
ret
left_opt(unsigned long):
and x0, x0, #0x10000000
ret
right_opt(unsigned long):
lsr x8, x0, #30
eor w8, w8, w0
and x0, x8, #0x10000000
ret
```
The first two are OK; both left shift and right shift are folded into the XOR operation.
In the left-shift case, with the mask on bit 28 instead of bit 32, the compiler recognizes that the left-shifted value can’t contribute to the result, and rightly omits it.
In the right-shift case, both operands remain relevant. The compiler seems to realize that only the lower 32 bits of the XOR are needed, so it narrows the instruction to 32-bit. But that prevents it from folding the right-shift into it, because
```asm
eor w8, w0, w0, lsr #30
and x0, x8, #0x10000000
```
wouldn’t be valid: It would drop the high bits being shifted in; the narrowing can only happen after the shift. So it would have been more efficient to keep the XOR in 64-bit form:
```asm
eor x8, x0, x0, lsr #30
and x0, x8, #0x10000000
```
IR example: https://godbolt.org/z/hnzxjqszz
Contributor guide
Assessment
This issue has not been assessed yet.