Skip to content

Commit 67579de

Browse files
fix: clear garbage bits before cast short integer to float (#2813)
Co-authored-by: CountBleck <[email protected]>
1 parent dc547a8 commit 67579de

5 files changed

+206
-26
lines changed

src/compiler.ts

+12-26
Original file line numberDiff line numberDiff line change
@@ -3647,43 +3647,29 @@ export class Compiler extends DiagnosticEmitter {
36473647

36483648
// int to float
36493649
} else if (fromType.isIntegerValue && toType.isFloatValue) {
3650-
3650+
// Clear extra bits.
3651+
expr = this.ensureSmallIntegerWrap(expr, fromType);
3652+
let op: UnaryOp;
36513653
// int to f32
36523654
if (toType.kind == TypeKind.F32) {
36533655
if (fromType.isLongIntegerValue) {
3654-
expr = module.unary(
3655-
fromType.isSignedIntegerValue
3656-
? UnaryOp.ConvertI64ToF32
3657-
: UnaryOp.ConvertU64ToF32,
3658-
expr
3659-
);
3656+
if (fromType.isSignedIntegerValue) op = UnaryOp.ConvertI64ToF32;
3657+
else op = UnaryOp.ConvertU64ToF32;
36603658
} else {
3661-
expr = module.unary(
3662-
fromType.isSignedIntegerValue
3663-
? UnaryOp.ConvertI32ToF32
3664-
: UnaryOp.ConvertU32ToF32,
3665-
expr
3666-
);
3659+
if (fromType.isSignedIntegerValue) op = UnaryOp.ConvertI32ToF32;
3660+
else op = UnaryOp.ConvertU32ToF32;
36673661
}
3668-
36693662
// int to f64
36703663
} else {
36713664
if (fromType.isLongIntegerValue) {
3672-
expr = module.unary(
3673-
fromType.isSignedIntegerValue
3674-
? UnaryOp.ConvertI64ToF64
3675-
: UnaryOp.ConvertU64ToF64,
3676-
expr
3677-
);
3665+
if (fromType.isSignedIntegerValue) op = UnaryOp.ConvertI64ToF64;
3666+
else op = UnaryOp.ConvertU64ToF64;
36783667
} else {
3679-
expr = module.unary(
3680-
fromType.isSignedIntegerValue
3681-
? UnaryOp.ConvertI32ToF64
3682-
: UnaryOp.ConvertU32ToF64,
3683-
expr
3684-
);
3668+
if (fromType.isSignedIntegerValue) op = UnaryOp.ConvertI32ToF64;
3669+
else op = UnaryOp.ConvertU32ToF64;
36853670
}
36863671
}
3672+
expr = module.unary(op, expr);
36873673

36883674
// v128 to bool
36893675
} else if (fromType == Type.v128 && toType.isBooleanValue) {
+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
(module
2+
(type $0 (func))
3+
(global $~lib/memory/__data_end i32 (i32.const 8))
4+
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 32776))
5+
(global $~lib/memory/__heap_base i32 (i32.const 32776))
6+
(memory $0 0)
7+
(table $0 1 1 funcref)
8+
(elem $0 (i32.const 1))
9+
(export "memory" (memory $0))
10+
(start $~start)
11+
(func $start:number-convert
12+
i32.const 1
13+
f32.convert_i32_u
14+
f32.const 1
15+
f32.eq
16+
drop
17+
i32.const 255
18+
f32.convert_i32_u
19+
f32.const 255
20+
f32.eq
21+
drop
22+
i32.const 256
23+
i32.const 255
24+
i32.and
25+
f32.convert_i32_u
26+
f32.const 0
27+
f32.eq
28+
drop
29+
i32.const 257
30+
i32.const 255
31+
i32.and
32+
f32.convert_i32_u
33+
f32.const 1
34+
f32.eq
35+
drop
36+
i32.const 1
37+
f32.convert_i32_s
38+
f32.const 1
39+
f32.eq
40+
drop
41+
i32.const 255
42+
i32.extend8_s
43+
f32.convert_i32_s
44+
f32.const -1
45+
f32.eq
46+
drop
47+
i32.const 256
48+
i32.extend8_s
49+
f32.convert_i32_s
50+
f32.const 0
51+
f32.eq
52+
drop
53+
i32.const 257
54+
i32.extend8_s
55+
f32.convert_i32_s
56+
f32.const 1
57+
f32.eq
58+
drop
59+
i32.const 1
60+
f32.convert_i32_u
61+
f32.const 1
62+
f32.eq
63+
drop
64+
i32.const 65535
65+
f32.convert_i32_u
66+
f32.const 65535
67+
f32.eq
68+
drop
69+
i32.const 65536
70+
i32.const 65535
71+
i32.and
72+
f32.convert_i32_u
73+
f32.const 0
74+
f32.eq
75+
drop
76+
i32.const 65537
77+
i32.const 65535
78+
i32.and
79+
f32.convert_i32_u
80+
f32.const 1
81+
f32.eq
82+
drop
83+
i32.const 1
84+
f32.convert_i32_s
85+
f32.const 1
86+
f32.eq
87+
drop
88+
i32.const 65535
89+
i32.extend16_s
90+
f32.convert_i32_s
91+
f32.const -1
92+
f32.eq
93+
drop
94+
i32.const 65536
95+
i32.extend16_s
96+
f32.convert_i32_s
97+
f32.const 0
98+
f32.eq
99+
drop
100+
i32.const 65537
101+
i32.extend16_s
102+
f32.convert_i32_s
103+
f32.const 1
104+
f32.eq
105+
drop
106+
i32.const 1
107+
f64.convert_i32_u
108+
f64.const 1
109+
f64.eq
110+
drop
111+
i32.const 255
112+
f64.convert_i32_u
113+
f64.const 255
114+
f64.eq
115+
drop
116+
i32.const 256
117+
i32.const 255
118+
i32.and
119+
f64.convert_i32_u
120+
f64.const 0
121+
f64.eq
122+
drop
123+
i32.const 257
124+
i32.const 255
125+
i32.and
126+
f64.convert_i32_u
127+
f64.const 1
128+
f64.eq
129+
drop
130+
i32.const 1
131+
f64.convert_i32_s
132+
f64.const 1
133+
f64.eq
134+
drop
135+
i32.const 255
136+
i32.extend8_s
137+
f64.convert_i32_s
138+
f64.const -1
139+
f64.eq
140+
drop
141+
i32.const 256
142+
i32.extend8_s
143+
f64.convert_i32_s
144+
f64.const 0
145+
f64.eq
146+
drop
147+
i32.const 257
148+
i32.extend8_s
149+
f64.convert_i32_s
150+
f64.const 1
151+
f64.eq
152+
drop
153+
)
154+
(func $~start
155+
call $start:number-convert
156+
)
157+
)

tests/compiler/number-convert.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"asc_flags": [
3+
]
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(module
2+
(memory $0 0)
3+
(export "memory" (memory $0))
4+
)

tests/compiler/number-convert.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
assert(<f32><u8>(1) == 1);
2+
assert(<f32><u8>(255) == 255);
3+
assert(<f32><u8>(256) == 0);
4+
assert(<f32><u8>(257) == <f32>1);
5+
6+
assert(<f32><i8>(1) == <f32>1);
7+
assert(<f32><i8>(255) == <f32>-1);
8+
assert(<f32><i8>(256) == <f32>0);
9+
assert(<f32><i8>(257) == <f32>1);
10+
11+
assert(<f32><u16>(1) == <f32>1);
12+
assert(<f32><u16>(65535) == <f32>65535);
13+
assert(<f32><u16>(65536) == <f32>0);
14+
assert(<f32><u16>(65537) == <f32>1);
15+
16+
assert(<f32><i16>(1) == <f32>1);
17+
assert(<f32><i16>(65535) == <f32>-1);
18+
assert(<f32><i16>(65536) == <f32>0);
19+
assert(<f32><i16>(65537) == <f32>1);
20+
21+
assert(<f64><u8>(1) == <f64>1);
22+
assert(<f64><u8>(255) == <f64>255);
23+
assert(<f64><u8>(256) == <f64>0);
24+
assert(<f64><u8>(257) == <f64>1);
25+
26+
assert(<f64><i8>(1) == <f64>1);
27+
assert(<f64><i8>(255) == <f64>-1);
28+
assert(<f64><i8>(256) == <f64>0);
29+
assert(<f64><i8>(257) == <f64>1);

0 commit comments

Comments
 (0)