Inconsistent big-endian layout for packed boolean vectors
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
On big-endian targets, static initialization of packed boolean vectors with size less than 8 uses the low bits of a byte, while loads and stores use the high bits.
```c
typedef _Bool bool2 __attribute__((ext_vector_type(2)));
bool2 global_v = {1, 1};
void set(bool2 *p) {
*p = (bool2){1, 1};
}
_Bool first(void) {
return global_v[0];
}
```
```sh
clang --target=armv7-none-eabi -march=armv7-m -mbig-endian \
-O1 -S repro.c -o -
```
**Actual:** `global_v` is emitted as `0x03`, but `set()` stores `0xC0`.
`first()` reads bit 7, returning `0` initially and `1` after `set(&global_v)`.
**Expected:** Initialization, loads, and stores must agree; `first()` should
return `1` in both cases. The little-endian variant behaves correctly.
[Compiler Explorer example](https://godbolt.org/z/Y5ae6hjn9).
Since packed boolean vectors with size >=8 have their bits allocated to the lower bits of the bytes, I believe that the memory layout used by the static initialization is the correct one.
Contributor guide
Research direction
Start by compiling the issue's repro.c with the provided clang armv7 big-endian command and compare the emitted global initializer with set() and first(). The fix is complete when packed boolean vectors smaller than 8 use the same bit layout for static initialization, loads, and stores, with first() returning 1 before and after set().
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100