Skip to content

Commit dcb2992

Browse files
authored
Audit for truncf* (rust-lang#1250)
1 parent d394148 commit dcb2992

File tree

5 files changed

+124
-32
lines changed

5 files changed

+124
-32
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -631,12 +631,8 @@ impl<'tcx> GotocCtx<'tcx> {
631631
"sqrtf64" => unstable_codegen!(codegen_simple_intrinsic!(Sqrt)),
632632
"sub_with_overflow" => codegen_op_with_overflow!(sub_overflow),
633633
"transmute" => self.codegen_intrinsic_transmute(fargs, ret_ty, p),
634-
"truncf32" => codegen_unimplemented_intrinsic!(
635-
"https://github.com/model-checking/kani/issues/1025"
636-
),
637-
"truncf64" => codegen_unimplemented_intrinsic!(
638-
"https://github.com/model-checking/kani/issues/1025"
639-
),
634+
"truncf32" => codegen_simple_intrinsic!(Truncf),
635+
"truncf64" => codegen_simple_intrinsic!(Trunc),
640636
"try" => {
641637
codegen_unimplemented_intrinsic!(
642638
"https://github.com/model-checking/kani/issues/267"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Checks that `truncf32` does return:
5+
// * The integral part of the argument for some concrete cases.
6+
// * A value that is closer to zero in all cases.
7+
// * A value such that the difference between it and the argument is between
8+
// zero and one.
9+
#![feature(core_intrinsics)]
10+
use std::intrinsics::truncf32;
11+
12+
#[kani::proof]
13+
fn test_one() {
14+
let one = 1.0;
15+
let trunc_res = unsafe { truncf32(one) };
16+
assert!(trunc_res == 1.0);
17+
}
18+
19+
#[kani::proof]
20+
fn test_one_frac() {
21+
let one_frac = 1.9;
22+
let trunc_res = unsafe { truncf32(one_frac) };
23+
assert!(trunc_res == 1.0);
24+
}
25+
26+
#[kani::proof]
27+
fn test_conc() {
28+
let conc = -42.6;
29+
let trunc_res = unsafe { truncf32(conc) };
30+
assert!(trunc_res == -42.0);
31+
}
32+
33+
#[kani::proof]
34+
fn test_conc_sci() {
35+
let conc = 5.4e-2;
36+
let trunc_res = unsafe { truncf32(conc) };
37+
assert!(trunc_res == 0.0);
38+
}
39+
40+
#[kani::proof]
41+
fn test_towards_zero() {
42+
let x: f32 = kani::any();
43+
kani::assume(!x.is_nan());
44+
let trunc_res = unsafe { truncf32(x) };
45+
if x.is_sign_positive() {
46+
assert!(trunc_res <= x);
47+
} else {
48+
assert!(trunc_res >= x);
49+
}
50+
}
51+
52+
#[kani::proof]
53+
fn test_diff_one() {
54+
let x: f32 = kani::any();
55+
kani::assume(!x.is_nan());
56+
kani::assume(!x.is_infinite());
57+
let trunc_res = unsafe { truncf32(x) };
58+
let diff = (x - trunc_res).abs();
59+
assert!(diff < 1.0);
60+
assert!(diff >= 0.0);
61+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Checks that `truncf64` does return:
5+
// * The integral part of the argument for some concrete cases.
6+
// * A value that is closer to zero in all cases.
7+
// * A value such that the difference between it and the argument is between
8+
// zero and one.
9+
#![feature(core_intrinsics)]
10+
use std::intrinsics::truncf64;
11+
12+
#[kani::proof]
13+
fn test_one() {
14+
let one = 1.0;
15+
let trunc_res = unsafe { truncf64(one) };
16+
assert!(trunc_res == 1.0);
17+
}
18+
19+
#[kani::proof]
20+
fn test_one_frac() {
21+
let one_frac = 1.9;
22+
let trunc_res = unsafe { truncf64(one_frac) };
23+
assert!(trunc_res == 1.0);
24+
}
25+
26+
#[kani::proof]
27+
fn test_conc() {
28+
let conc = -42.6;
29+
let trunc_res = unsafe { truncf64(conc) };
30+
assert!(trunc_res == -42.0);
31+
}
32+
33+
#[kani::proof]
34+
fn test_conc_sci() {
35+
let conc = 5.4e-2;
36+
let trunc_res = unsafe { truncf64(conc) };
37+
assert!(trunc_res == 0.0);
38+
}
39+
40+
#[kani::proof]
41+
fn test_towards_zero() {
42+
let x: f64 = kani::any();
43+
kani::assume(!x.is_nan());
44+
let trunc_res = unsafe { truncf64(x) };
45+
if x.is_sign_positive() {
46+
assert!(trunc_res <= x);
47+
} else {
48+
assert!(trunc_res >= x);
49+
}
50+
}
51+
52+
#[kani::proof]
53+
fn test_diff_one() {
54+
let x: f64 = kani::any();
55+
kani::assume(!x.is_nan());
56+
kani::assume(!x.is_infinite());
57+
let trunc_res = unsafe { truncf64(x) };
58+
let diff = (x - trunc_res).abs();
59+
assert!(diff < 1.0);
60+
assert!(diff >= 0.0);
61+
}

tests/kani/Intrinsics/Math/Rounding/truncf32.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/kani/Intrinsics/Math/Rounding/truncf64.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)