|
Next stable release will stabilise things like https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.algebraic_add which are akin to -ffast-math in C and C++. They're slightly stricter than ffast-math so NaN and INF won't result in UB and I think denormals are normalised to zero, but they can made the numerics weakly deterministic and allow things like reordering etc. I'm planning on switching a bunch of my code to use these where it should be safe, but now I'm wondering if I'm wrong can kani catch it? |
Replies: 2 comments 2 replies
Short answer: do not treat Kani as a check that
Kani lowers Rust to GOTO/CBMC and models ordinary float ops as bit-precise IEEE values. The feature-support notes already say that even IEEE What Kani can still catch:
What it will not catch:
I would write a five-line harness that calls For the "is this rewrite allowed" question, you want a paper proof of the algebraic identity you rely on, or a tool that checks the identity over reals with explicit reassociation. Kani's strength here is still the surrounding Rust (bounds, panics, decoder invariants), not the fast-math contract. |
|
I ran the smoke test @SebastienTardif suggested, on #![feature(float_algebraic)]
#[kani::proof]
fn check_algebraic_add() {
let a: f32 = kani::any();
let b: f32 = kani::any();
kani::assume(a.is_finite() && b.is_finite());
assert!(a.algebraic_add(b) == a + b);
}So the concrete answer to "can Kani catch it?" is: not today, and not silently. The Adding support is straightforward and we should do it. But it's worth being clear about what it would buy you, because @SebastienTardif's main point stands: the natural modeling is plain IEEE Practically: Kani is a good fit for the Rust around the arithmetic (panics, bounds, I'd appreciate if you could open a tracking issue for |
@xd009642
Short answer: do not treat Kani as a check that
algebraic_add(and friends) are safe to switch to. It can still help with IEEE-shaped bugs around the call. It will not model the extra freedom those operators give LLVM.f32::algebraic_addis not IEEE+. It is a rustc/LLVM op with algebraic flags (reassociate, contract, reciprocal, and similar). The compiler may rewrite(a + b) + cintoa + (b + c)or fuse a multiply-add. That rewrite is the point of the API, and it is also where a "this should be safe" assumption dies.Kani lowers Rust to GOTO…