Skip to content

Commit 77c896c

Browse files
committed
Fix range checking for trunc conversions, and add tests.
1 parent 5bba119 commit 77c896c

File tree

3 files changed

+94
-18
lines changed

3 files changed

+94
-18
lines changed

ml-proto/src/spec/i32_convert.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ let trunc_s_f32 x =
66
if F32.ne x x then
77
raise Numerics.InvalidConversionToInteger
88
else let xf = F32.to_float x in
9-
if xf >= (Int32.to_float Int32.max_int) +. 1. ||
10-
xf <= (Int32.to_float Int32.min_int) -. 1. then
9+
if xf >= -.(Int32.to_float Int32.min_int) ||
10+
xf < (Int32.to_float Int32.min_int) then
1111
raise Numerics.IntegerOverflow
1212
else
1313
Int32.of_float xf
@@ -16,8 +16,8 @@ let trunc_u_f32 x =
1616
if F32.ne x x then
1717
raise Numerics.InvalidConversionToInteger
1818
else let xf = F32.to_float x in
19-
if xf >= (Int32.to_float Int32.max_int) *. 2. +. 2. ||
20-
xf <= -1. then
19+
if xf >= -.(Int32.to_float Int32.min_int) *. 2. ||
20+
xf <= -1. then
2121
raise Numerics.IntegerOverflow
2222
else
2323
Int64.to_int32 (Int64.of_float xf)
@@ -26,8 +26,8 @@ let trunc_s_f64 x =
2626
if F64.ne x x then
2727
raise Numerics.InvalidConversionToInteger
2828
else let xf = F64.to_float x in
29-
if xf >= (Int32.to_float Int32.max_int) +. 1. ||
30-
xf <= (Int32.to_float Int32.min_int) -. 1. then
29+
if xf >= -.(Int32.to_float Int32.min_int) ||
30+
xf < (Int32.to_float Int32.min_int) then
3131
raise Numerics.IntegerOverflow
3232
else
3333
Int32.of_float xf
@@ -36,8 +36,8 @@ let trunc_u_f64 x =
3636
if F64.ne x x then
3737
raise Numerics.InvalidConversionToInteger
3838
else let xf = F64.to_float x in
39-
if xf >= (Int32.to_float Int32.max_int) *. 2. +. 2. ||
40-
xf <= -1. then
39+
if xf >= -.(Int32.to_float Int32.min_int) *. 2. ||
40+
xf <= -1. then
4141
raise Numerics.IntegerOverflow
4242
else
4343
Int64.to_int32 (Int64.of_float xf)

ml-proto/src/spec/i64_convert.ml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ let trunc_s_f32 x =
88
if F32.ne x x then
99
raise Numerics.InvalidConversionToInteger
1010
else let xf = F32.to_float x in
11-
if xf >= (Int64.to_float Int64.max_int) +. 1. ||
12-
xf <= (Int64.to_float Int64.min_int) -. 1. then
11+
if xf >= -.(Int64.to_float Int64.min_int) ||
12+
xf < (Int64.to_float Int64.min_int) then
1313
raise Numerics.IntegerOverflow
1414
else
1515
Int64.of_float xf
@@ -18,10 +18,10 @@ let trunc_u_f32 x =
1818
if F32.ne x x then
1919
raise Numerics.InvalidConversionToInteger
2020
else let xf = F32.to_float x in
21-
if xf >= (Int64.to_float Int64.max_int) *. 2. +. 2. ||
22-
xf <= -1. then
21+
if xf >= -.(Int64.to_float Int64.min_int) *. 2. ||
22+
xf <= -1. then
2323
raise Numerics.IntegerOverflow
24-
else if xf >= (Int64.to_float Int64.max_int) +. 1. then
24+
else if xf >= -.(Int64.to_float Int64.min_int) then
2525
Int64.logxor (Int64.of_float (xf -. 9223372036854775808.)) Int64.min_int
2626
else
2727
Int64.of_float xf
@@ -30,8 +30,8 @@ let trunc_s_f64 x =
3030
if F64.ne x x then
3131
raise Numerics.InvalidConversionToInteger
3232
else let xf = F64.to_float x in
33-
if xf >= (Int64.to_float Int64.max_int) +. 1. ||
34-
xf <= (Int64.to_float Int64.min_int) -. 1. then
33+
if xf >= -.(Int64.to_float Int64.min_int) ||
34+
xf < (Int64.to_float Int64.min_int) then
3535
raise Numerics.IntegerOverflow
3636
else
3737
Int64.of_float xf
@@ -40,10 +40,10 @@ let trunc_u_f64 x =
4040
if F64.ne x x then
4141
raise Numerics.InvalidConversionToInteger
4242
else let xf = F64.to_float x in
43-
if xf >= (Int64.to_float Int64.max_int) *. 2. +. 2. ||
44-
xf <= -1. then
43+
if xf >= -.(Int64.to_float Int64.min_int) *. 2. ||
44+
xf <= -1. then
4545
raise Numerics.IntegerOverflow
46-
else if xf >= (Int64.to_float Int64.max_int) +. 1. then
46+
else if xf >= -.(Int64.to_float Int64.min_int) then
4747
Int64.logxor (Int64.of_float (xf -. 9223372036854775808.)) Int64.min_int
4848
else
4949
Int64.of_float xf

ml-proto/test/conversions.wasm

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,24 @@
1414
(func $i32.trunc_u_f32 (param $x f32) (result i32) (i32.trunc_u/f32 (get_local $x)))
1515
(export "i32.trunc_u_f32" $i32.trunc_u_f32)
1616

17+
(func $i32.trunc_s_f64 (param $x f64) (result i32) (i32.trunc_s/f64 (get_local $x)))
18+
(export "i32.trunc_s_f64" $i32.trunc_s_f64)
19+
20+
(func $i32.trunc_u_f64 (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x)))
21+
(export "i32.trunc_u_f64" $i32.trunc_u_f64)
22+
1723
(func $i64.trunc_s_f32 (param $x f32) (result i64) (i64.trunc_s/f32 (get_local $x)))
1824
(export "i64.trunc_s_f32" $i64.trunc_s_f32)
1925

2026
(func $i64.trunc_u_f32 (param $x f32) (result i64) (i64.trunc_u/f32 (get_local $x)))
2127
(export "i64.trunc_u_f32" $i64.trunc_u_f32)
2228

29+
(func $i64.trunc_s_f64 (param $x f64) (result i64) (i64.trunc_s/f64 (get_local $x)))
30+
(export "i64.trunc_s_f64" $i64.trunc_s_f64)
31+
32+
(func $i64.trunc_u_f64 (param $x f64) (result i64) (i64.trunc_u/f64 (get_local $x)))
33+
(export "i64.trunc_u_f64" $i64.trunc_u_f64)
34+
2335
(func $f32.convert_s_i32 (param $x i32) (result f32) (f32.convert_s/i32 (get_local $x)))
2436
(export "f32.convert_s_i32" $f32.convert_s_i32)
2537

@@ -98,13 +110,45 @@
98110
(assert_eq (invoke "i32.trunc_s_f32" (f32.const -1.5)) (i32.const -1))
99111
(assert_eq (invoke "i32.trunc_s_f32" (f32.const -1.9)) (i32.const -1))
100112
(assert_eq (invoke "i32.trunc_s_f32" (f32.const -2.0)) (i32.const -2))
113+
(assert_eq (invoke "i32.trunc_s_f32" (f32.const 2147483520.0)) (i32.const 2147483520))
114+
(assert_eq (invoke "i32.trunc_s_f32" (f32.const -2147483648.0)) (i32.const -2147483648))
115+
(assert_trap (invoke "i32.trunc_s_f32" (f32.const 2147483648.0)) "runtime: integer overflow")
116+
(assert_trap (invoke "i32.trunc_s_f32" (f32.const -2147483904.0)) "runtime: integer overflow")
101117

102118
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 1.0)) (i32.const 1))
103119
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 1.1)) (i32.const 1))
104120
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 1.5)) (i32.const 1))
105121
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 1.9)) (i32.const 1))
106122
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 2.0)) (i32.const 2))
107123
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
124+
(assert_eq (invoke "i32.trunc_u_f32" (f32.const 4294967040.0)) (i32.const -256))
125+
(assert_eq (invoke "i32.trunc_u_f32" (f32.const -0.9)) (i32.const 0))
126+
(assert_trap (invoke "i32.trunc_u_f32" (f32.const 4294967296.0)) "runtime: integer overflow")
127+
(assert_trap (invoke "i32.trunc_u_f32" (f32.const -1.0)) "runtime: integer overflow")
128+
129+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const 1.0)) (i32.const 1))
130+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const 1.1)) (i32.const 1))
131+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const 1.5)) (i32.const 1))
132+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -1.0)) (i32.const -1))
133+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -1.1)) (i32.const -1))
134+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -1.5)) (i32.const -1))
135+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -1.9)) (i32.const -1))
136+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -2.0)) (i32.const -2))
137+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const 2147483647.0)) (i32.const 2147483647))
138+
(assert_eq (invoke "i32.trunc_s_f64" (f64.const -2147483648.0)) (i32.const -2147483648))
139+
(assert_trap (invoke "i32.trunc_s_f64" (f64.const 2147483648.0)) "runtime: integer overflow")
140+
(assert_trap (invoke "i32.trunc_s_f64" (f64.const -2147483649.0)) "runtime: integer overflow")
141+
142+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 1.0)) (i32.const 1))
143+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 1.1)) (i32.const 1))
144+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 1.5)) (i32.const 1))
145+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 1.9)) (i32.const 1))
146+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 2.0)) (i32.const 2))
147+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 2147483648)) (i32.const -2147483648)) ;; 0x1.00000p+31 -> 8000 0000
148+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const 4294967295.0)) (i32.const -1))
149+
(assert_eq (invoke "i32.trunc_u_f64" (f64.const -0.9)) (i32.const 0))
150+
(assert_trap (invoke "i32.trunc_u_f64" (f64.const 4294967296.0)) "runtime: integer overflow")
151+
(assert_trap (invoke "i32.trunc_u_f64" (f64.const -1.0)) "runtime: integer overflow")
108152

109153
(assert_eq (invoke "i64.trunc_s_f32" (f32.const 1.0)) (i64.const 1))
110154
(assert_eq (invoke "i64.trunc_s_f32" (f32.const 1.1)) (i64.const 1))
@@ -116,11 +160,43 @@
116160
(assert_eq (invoke "i64.trunc_s_f32" (f32.const -2.0)) (i64.const -2))
117161
(assert_eq (invoke "i64.trunc_s_f32" (f32.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
118162
(assert_eq (invoke "i64.trunc_s_f32" (f32.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
163+
(assert_eq (invoke "i64.trunc_s_f32" (f32.const 9223371487098961920.0)) (i64.const 9223371487098961920))
164+
(assert_eq (invoke "i64.trunc_s_f32" (f32.const -9223372036854775808.0)) (i64.const -9223372036854775808))
165+
(assert_trap (invoke "i64.trunc_s_f32" (f32.const 9223372036854775808.0)) "runtime: integer overflow")
166+
(assert_trap (invoke "i64.trunc_s_f32" (f32.const -9223373136366403584.0)) "runtime: integer overflow")
119167

120168
(assert_eq (invoke "i64.trunc_u_f32" (f32.const 1.0)) (i64.const 1))
121169
(assert_eq (invoke "i64.trunc_u_f32" (f32.const 1.1)) (i64.const 1))
122170
(assert_eq (invoke "i64.trunc_u_f32" (f32.const 1.5)) (i64.const 1))
123171
(assert_eq (invoke "i64.trunc_u_f32" (f32.const 4294967296)) (i64.const 4294967296))
172+
(assert_eq (invoke "i64.trunc_u_f32" (f32.const 18446742974197923840.0)) (i64.const -1099511627776))
173+
(assert_eq (invoke "i64.trunc_u_f32" (f32.const -0.9)) (i64.const 0))
174+
(assert_trap (invoke "i64.trunc_u_f32" (f32.const 18446744073709551616.0)) "runtime: integer overflow")
175+
(assert_trap (invoke "i64.trunc_u_f32" (f32.const -1.0)) "runtime: integer overflow")
176+
177+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const 1.0)) (i64.const 1))
178+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const 1.1)) (i64.const 1))
179+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const 1.5)) (i64.const 1))
180+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -1.0)) (i64.const -1))
181+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -1.1)) (i64.const -1))
182+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -1.5)) (i64.const -1))
183+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -1.9)) (i64.const -1))
184+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -2.0)) (i64.const -2))
185+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const 4294967296)) (i64.const 4294967296)) ;; 0x1.00000p+32 -> 1 0000 0000
186+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -4294967296)) (i64.const -4294967296)) ;; -0x1.00000p+32 -> ffff ffff 0000 0000
187+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const 9223372036854774784.0)) (i64.const 9223372036854774784))
188+
(assert_eq (invoke "i64.trunc_s_f64" (f64.const -9223372036854775808.0)) (i64.const -9223372036854775808))
189+
(assert_trap (invoke "i64.trunc_s_f64" (f64.const 9223372036854775808.0)) "runtime: integer overflow")
190+
(assert_trap (invoke "i64.trunc_s_f64" (f64.const -9223372036854777856.0)) "runtime: integer overflow")
191+
192+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const 1.0)) (i64.const 1))
193+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const 1.1)) (i64.const 1))
194+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const 1.5)) (i64.const 1))
195+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const 4294967296)) (i64.const 4294967296))
196+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const 18446744073709549568.0)) (i64.const -2048))
197+
(assert_eq (invoke "i64.trunc_u_f64" (f64.const -0.9)) (i64.const 0))
198+
(assert_trap (invoke "i64.trunc_u_f64" (f64.const 18446744073709551616.0)) "runtime: integer overflow")
199+
(assert_trap (invoke "i64.trunc_u_f64" (f64.const -1.0)) "runtime: integer overflow")
124200

125201
(assert_eq (invoke "f32.convert_s_i32" (i32.const 1)) (f32.const 1.0))
126202
(assert_eq (invoke "f32.convert_s_i32" (i32.const -1)) (f32.const -1.0))

0 commit comments

Comments
 (0)