[Missed Optimization] Idiom recognition for C23 `memalignment` pointer alignment loops
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
### Description
LLVM misses an idiom recognition opportunity to optimize a pointer-alignment loop into a simple bitwise AND operation.
With C23 introducing the `memalignment` function, it is now possible to write strictly standard-conforming pointer alignment functions without relying on implementation-defined pointer-to-integer casts or toolchain-specific extensions. The loop iteratively adds or subtracts the pointer's current alignment from itself, effectively clearing the lowest set bit until the target power-of-two alignment is met.
Unfortunately, LLVM fails to recognize this loop idiom and emits a literal loop instead of a mathematical shortcut.
### Reproducer
A minimal reproducible example can be found on Compiler Explorer: https://godbolt.org/z/EPbs8v35c
A more extensive example suite containing up-alignment and `std::align` equivalents as well as alternative implementation approaches is available here: https://godbolt.org/z/qv1MMs6eT
```c
void *align_down(void *ptr, size_t alignment) {
if (!stdc_has_single_bit(alignment)) {
unreachable();
}
while (memalignment(ptr) < alignment) {
ptr = (unsigned char *)ptr - memalignment(ptr);
}
return ptr;
}
```
### Observed Assembler (Clang -Os)
The loop survives scalar optimization passes intact:
```asm
align_down:
mov rax, rdi
mov rcx, rdi
neg rcx
and rcx, rdi
.LBB0_2:
cmp rcx, rsi
jae .LBB0_3
sub rax, rcx
mov rcx, rax
neg rcx
and rcx, rax
jmp .LBB0_2
.LBB0_3:
ret
```
### Expected Output
The loop should be lowered to a simple bitmask, matching the code generated by `__builtin_align_down`:
```asm
align_down:
mov rax, rsi
neg rax
and rax, rdi
ret
```
### Additional Context
- This behavior is consistent across all Clang versions and target architectures available on compiler explorer.
- Compiler explorer does not yet expose `memalignment` to its Clang targets, so the examples use a manually written fallback implementation. I have verified locally that using a native C23 standard library implementation of `memalignment` yields the exact same loop output as using the fallback.
- Since this pattern represents the only strictly standard-compliant way to dynamically align pointers in modern C, optimizing this idiom would significantly benefit safety-conscious, standard-conforming codebases.
Contributor guide
Research direction
Start with the Clang reproducer on Compiler Explorer and compare the loop output with the __builtin_align_down output. Read the scalar optimization passes involved in the loop and pointer-alignment handling, then verify that the C23 memalignment form is lowered to the expected bitmask without changing other alignment cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100