R on Debian's riscv64 port
Summary
R has the concept of missing values in the statistical sense (NA). It encodes missing numeric values (NA_real_) as an IEEE-754 NaN with a distinctive payload; many fast paths rely on hardware arithmetic to “carry” that payload through computations. IEEE-754 does not require payload propagation (although it recommends it), and also does not fully specify payload propagation in all cases (especially binary operations with multiple NaN operands), so payload behavior can legitimately differ by platform.
On RISC-V hardware, and thus in our riscv64 port, floating-point implementations commonly canonicalize NaNs (dropping payload information), so arithmetic involving NA_real_ may yield an ordinary NaN rather than NA. This is a RISC-V design decision, the R developers are aware of it and decided that the issue won't be fixed on R's end.
This is within documented R behavior, which warns that the NA vs NaN distinction after computation is not guaranteed and may depend on the platform, compiler optimizations, or dynamic translation/instrumentation. Similar issues have been dealt with on ARM in the past by adjusting FPU mode at startup and general guidance is given to porters in the R admin guide appendix C7.
Debian context
We run R and R package test suites on more architectures than CRAN, including riscv64. Regressions that only trigger on riscv64 can block migration to testing and cascade to many reverse-dependencies.
A concrete example is r-cran-data.table (GitHub issue #7695): two tests expected NA but observed NaN on riscv64; the diagnosis was loss of the NA payload through arithmetic / conversions. In this case upstream chose to fix the issue by skipping tests when NA payload does not propagate.
When reporting regressions upstream, do not assume that “riscv64 implies payload loss” is the only relevant condition; similar behavior can appear on other architectures, or in other situations such as under Valgrind. It is up to Upstream to decide whether to add safeguards and extra handling for NA propagation in their packages, or to ignore the failures as corner cases. In that case you can suggest them to gate fragile tests (or optional strictness) on observable R behavior like in data.table PR #7702, which tests for identical(NA_real_ + 0, NA_real_).
Suggestions for R packages developers
This issue is particularly visible on riscv64 due to NaN canonicalization, but it is not specific to that platform. Similar behavior can occur on other architectures, compilers, or execution environments.
As a package developer, you are best placed to decide whether preservation of NA (as distinct from NaN) after arithmetic is essential for the correctness of your package, and whether it is worth the effort to support platforms where this property does not hold.
If you choose not to enforce strict NA propagation, you can make your tests more portable by adapting them to observable behavior:
Detect whether NA payload is preserved: identical(NA_real_ + 0, NA_real_) to skip tests that rely on strict NA propagation when this is not the case (as done in data.table).
Alternatively, prefer semantic checks such as is.na(x) which returns TRUE for both NA and NaN.
If strict NA propagation is required for your package, but you cannot support platforms where it does not hold, you can make this explicit by failing tests early: if (!identical(NA_real_ + 0, NA_real_)) stop("This package requires NA payload propagation (NA_real_ must be preserved by arithmetic).")
This makes the limitation explicit to downstream users and distributions.
Links
R Language Definition: NA handling — user-level semantics and conventions.
R base documentation: NA — warnings that NA/NaN outcomes after computation are platform-dependent; mentions dynamic translation/Valgrind.
R-devel (2014): “Question re: NA, NaNs in R” — explains NA_real_ as a signaling NaN payload; hardware quieting; payload propagation not fully specified.
R-devel (2023): `NA` propagation failure on RISC-V64 — reports NA+1 → NaN and downstream test failures.
R-core blog (2020): Apple Silicon `NA/NaN` payload propagation — illustrates payload loss in practice; emphasizes explicit checks for portability; shows one platform-specific mitigation.
RISC-V ISA reference: NaN generation/propagation — describes canonical NaN behavior in the floating-point extension docs.
data.table issue #7695 — Debian riscv64 test failures (NA vs NaN) motivating behavior-based gating.
Debconf warning in LibreOffice: The same issue affects LibreOffice, which in Debian displays a warning to the users installing it on riscv64.
Local page tracking riscv64 issues with r-cran-* and r-bioc-* packages in Debian.
