Root-cause the aarch64-only D+ DOUBLE-OVERFLOW bug (FABRIC-3.md §XII.4)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

Confirmed the exact mechanism behind the aarch64-specific D+/D. divergence
found in the std79 exerciser campaign (commit cc81edf). The earlier
writeup's cell_t-width check was real but answered the wrong question --
cell_t is 64-bit everywhere, but double_word_d_plus()'s carry-detection
casts through plain `unsigned long`, and sizeof(unsigned long) is 4 (32-bit)
on this aarch64 bare-metal cross-compile target specifically (amd64 and
riscv64 both happen to have a 64-bit long). The low-cell addition silently
truncates to 32 bits, then widens back to cell_t via ordinary (non-sign-
extending) conversion, producing a wrong positive result_low whenever the
true 64-bit sum is negative -- confirmed live by splitting result_low into
hi/lo 32-bit halves: the real pushed value for `-5 S>D 3 S>D D+` is
+4294967294, not -2. D.'s overflow check is correct and is faithfully
reporting a genuinely malformed double; D+ is the actual defect.

vm.h already defines ucell_t for exactly this class of problem (same
conditional as cell_t, guaranteed width-matched on every target) --
print_number_formatted() (format_words.c) already uses it correctly, D+
doesn't. Also flagged (not exercised by the campaign, same bare-`unsigned
long` pattern, same latent risk): D-, DNEGATE, and the d_compare() helper
behind DMAX/DMIN/D</D=.

Report only, per this project's standing rule (report bugs, don't fix
without being asked) -- no source change in this commit, debug probes
added during the investigation were reverted after use.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
This commit is contained in:
Robert Allan James
2026-09-11 06:41:39 -04:00
co-authored by Claude Sonnet 5
parent cc81edf00a
commit 91f7b39d3c
9 changed files with 27104 additions and 19 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff