issue 0152 RESOLVED: byte-promote sub-byte (Atomic(bool)) atomic load/store
LLVM rejects a sub-byte atomic memory access (must be byte-sized), so Atomic(bool) — bool lowers to i1 — failed verification on load/store. The atomic emitters in src/backend/llvm/ops.zig now perform a sub-byte access in its byte storage type (i8) and trunc/zext the value at the boundary (new atomicByteType helper: i8 for .bool, null otherwise). rmw/cmpxchg are left as-is on purpose — a bool rmw/CAS is rejected at the sx level (integer-only), so a sub-byte element never reaches those emitters. Regression test examples/1705-atomics-bool-byte-promoted.sx. Suite green 729/0. Unblocks Future.canceled: Atomic(bool) in the B1.2 async layer.
This commit is contained in:
@@ -1,5 +1,34 @@
|
||||
# 0152 — `Atomic(bool)` emits a sub-byte (i1) atomic load/store that LLVM rejects
|
||||
|
||||
## ✅ RESOLVED (2026-06-21)
|
||||
|
||||
**Root cause** — the atomic load/store emitters in `src/backend/llvm/ops.zig`
|
||||
used `toLLVMType(ty)` directly as the atomic access type. For a `bool`
|
||||
element that is `i1`, which LLVM rejects for atomics (size must be a byte
|
||||
multiple).
|
||||
|
||||
**Fix** — `emitAtomicLoad`/`emitAtomicStore` now promote a sub-byte element
|
||||
to its byte storage type (`i8`) for the atomic access, and `trunc`/`zext`
|
||||
the value at the boundary (a new `atomicByteType` helper returns `i8` for
|
||||
`.bool`, null otherwise). rmw/cmpxchg were left unchanged on purpose: a
|
||||
`bool` rmw/CAS is rejected at the sx level (`atomic.sx` — "requires an
|
||||
integer type"), so a sub-byte element can never reach those emitters (a
|
||||
comment records this). `bool` is the only sub-byte scalar in sx.
|
||||
|
||||
**Verified** — the repro prints `yes`; regression test
|
||||
`examples/1705-atomics-bool-byte-promoted.sx` (init / store / reset round-
|
||||
trip on `Atomic(bool)`). Full suite green (729/0).
|
||||
|
||||
**Downstream (NOT this bug):** with `Atomic(bool)` fixed, the B1.2 async
|
||||
examples surfaced ANOTHER, separate bug — a generic value-failable
|
||||
`($R, !E)` fn reached through a re-export alias loses its `!` error channel
|
||||
at the call site (typed as a plain tuple), so `await(...) or { … }` builds a
|
||||
malformed PHI. `io.sx`'s `await`/`IoErr` are re-exported via `std.sx`, so the
|
||||
async surface is now blocked on THAT (filed as a new issue), not on 0152.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Symptom
|
||||
|
||||
`Atomic(bool)` lowers `bool` to LLVM `i1` and emits the atomic load/store
|
||||
|
||||
Reference in New Issue
Block a user