Skip to content

Fix floating-point remainder soundness and add soundness documentation#4570

Merged
feliperodri merged 5 commits intomodel-checking:mainfrom
feliperodri:fix-soundness-issues
Apr 28, 2026
Merged

Fix floating-point remainder soundness and add soundness documentation#4570
feliperodri merged 5 commits intomodel-checking:mainfrom
feliperodri:fix-soundness-issues

Conversation

@feliperodri
Copy link
Copy Markdown
Contributor

Two soundness-related fixes:

  1. Fix incorrect floating-point remainder (Incorrect floating point result with remainder (%) operator #2669): The % operator on f32/f64 was silently producing wrong results because Kani emitted CBMC's integer mod operation for floating-point operands. CBMC ignores integer mod on floatbv types, leading to incorrect verification results (false negatives).

  2. Add soundness documentation (Soundness documentation #1495): New docs/src/soundness.md page documenting what Kani checks, what it does not check, and known soundness caveats.

Fix for #2669

Added FloatbvMod as a new BinaryOperator variant that maps to CBMC's floatbv_mod expression, which implements IEEE 754 fmod semantics. The Expr::rem() method now dispatches to FloatbvMod for floating-point operands and Mod for integers.

Changes:

  • cprover_bindings/src/goto_program/expr.rs — Add FloatbvMod variant, type validation, return type, and conditional dispatch in rem().
  • cprover_bindings/src/irep/irep_id.rs — Add FloatbvMod IREP ID and string mapping.
  • cprover_bindings/src/irep/to_irep.rs — Add FloatbvModIrepId::FloatbvMod conversion.
  • tests/kani/FloatingPoint/float_remainder.rs — Regression test with symbolic f32 and f64 remainder verification.

Fix for #1495

New documentation page covering:

  • What Kani checks: Arithmetic overflow, division by zero, pointer validity, array bounds, panics, shift distance, float-to-int conversion, NaN, memory leaks (always on); valid value invariants and uninitialized memory (opt-in).
  • What Kani does NOT check: Data races, aliasing violations, immutable data mutation, inline assembly, ABI violations, transmute of invalid values.
  • Soundness caveats: CBMC backend risks, bounded verification, floating-point model, object size limits, function pointer imprecision.

Resolves #2669
Resolves #1495

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@feliperodri feliperodri added this to the Soundness milestone Apr 2, 2026
@feliperodri feliperodri added the [F] Soundness Kani failed to detect an issue label Apr 2, 2026
@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Apr 2, 2026
@feliperodri feliperodri force-pushed the fix-soundness-issues branch from d8f915d to a6380e4 Compare April 2, 2026 01:11
@feliperodri feliperodri marked this pull request as ready for review April 2, 2026 01:13
@feliperodri feliperodri requested a review from a team as a code owner April 2, 2026 01:13
@feliperodri
Copy link
Copy Markdown
Contributor Author

Neither benchmark uses floating-point. Our change didn't cause this perf-benchcomp. These are solver runtime fluctuations: the SAT solver (CaDiCaL) is nondeterministic in its performance on shared CI runners. The same benchmarks that regressed on main (inet::checksum::tests::differential at 2.3x) are different from the ones regressing here, which confirms this is runner-level noise, not a code change effect.

The perf-regression.yaml threshold is solver_runtime > 1.5x with a minimum of 10 seconds. These benchmarks are in the 35-82 second range where a 1.5-1.7x fluctuation is common on shared GitHub-hosted runners due to CPU contention from other jobs on the same host.

This is not caused by the floatbv_mod change; neither benchmark involves floating-point operations. This is the same class of CI flakiness that affects the main branch (which also failed its perf benchmark with different benchmarks regressing).

Comment thread docs/src/soundness.md Outdated
Comment thread cprover_bindings/src/goto_program/expr.rs Outdated
Comment thread docs/src/soundness.md Outdated
@feliperodri feliperodri force-pushed the fix-soundness-issues branch from d121eda to 8e4096b Compare April 28, 2026 16:54
The remainder (%) operator on floating-point types was incorrectly
using CBMC's integer 'mod' operation, which CBMC silently ignores for
floatbv types, producing incorrect verification results.

Use the floatbv_mod binary operator for float/double operands, which
correctly implements IEEE 754 fmod semantics matching Rust's % on
floating-point types.

Resolves model-checking#2669

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
Document what Kani checks (always-on and opt-in), what it does not
check, and known soundness caveats (CBMC backend, bounded verification,
floating-point, object size limits, function pointers).

Resolves model-checking#1495

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
CBMC does not emit a 'division by zero' check for floatbv_mod (float
remainder), unlike integer mod. Remove the expected line since the
float remainder operator now correctly uses floatbv_mod.

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
…ixed

The float remainder bug tracked by this fixme test is resolved by the
floatbv_mod change. Remove the fixme suffix so it runs as a passing
test in the kani suite instead of an expected-failure in kani-fixme.

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
- Call out --restrict-vtable as a known soundness issue with link to model-checking#3134
- Remove duplicate doc comment line on rem()
- Clarify "Always enabled" → "Enabled by default" with note about
  --no-XXX-checks flags
@feliperodri feliperodri force-pushed the fix-soundness-issues branch from 8e4096b to 6e7bcc4 Compare April 28, 2026 16:55
@feliperodri feliperodri enabled auto-merge April 28, 2026 22:57
@feliperodri feliperodri added this pull request to the merge queue Apr 28, 2026
Merged via the queue into model-checking:main with commit 86273d7 Apr 28, 2026
34 checks passed
@feliperodri feliperodri deleted the fix-soundness-issues branch April 28, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[F] Soundness Kani failed to detect an issue Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect floating point result with remainder (%) operator Soundness documentation

4 participants