Skip to content

Commit 9948f41

Browse files
authored
Simplify Math.signbit (don't ignore NaN sign bits) (#1467)
1 parent 9f38cc4 commit 9948f41

File tree

7 files changed

+35
-131
lines changed

7 files changed

+35
-131
lines changed

std/assembly/math.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,9 +1435,7 @@ export namespace NativeMath {
14351435
// @ts-ignore: decorator
14361436
@inline
14371437
export function signbit(x: f64): bool {
1438-
// In ECMAScript all NaN values are indistinguishable from each other
1439-
// so we need handle NaN and negative NaN in similar way
1440-
return <bool>(<i32>(reinterpret<u64>(x) >>> 63) & i32(x == x));
1438+
return <bool>(reinterpret<u64>(x) >>> 63);
14411439
}
14421440

14431441
export function sin(x: f64): f64 { // see: musl/src/math/sin.c
@@ -2714,8 +2712,7 @@ export namespace NativeMathf {
27142712
// @ts-ignore: decorator
27152713
@inline
27162714
export function signbit(x: f32): bool {
2717-
// @ts-ignore: type
2718-
return <bool>((reinterpret<u32>(x) >>> 31) & (x == x));
2715+
return <bool>(reinterpret<u32>(x) >>> 31);
27192716
}
27202717

27212718
export function sin(x: f32): f32 { // see: musl/src/math/sinf.c

std/portable/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ Object.defineProperties(globalScope["JSMath"], {
325325
sincos_cos: { value: 0.0, writable: true },
326326
signbit: {
327327
value: function signbit(x) {
328-
F64[0] = x; return Boolean((U64[1] >>> 31) & (x == x));
328+
F64[0] = x; return Boolean(U64[1] >>> 31);
329329
}
330330
},
331331
sincos: {

tests/compiler/std/math.optimized.wat

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,22 +187,16 @@
187187
i64.reinterpret_f64
188188
i64.const 63
189189
i64.shr_u
190-
i32.wrap_i64
191-
local.get $0
192-
local.get $0
193-
f64.eq
194-
i32.and
190+
i64.const 0
191+
i64.ne
195192
i32.const 0
196193
i32.ne
197194
local.get $1
198195
i64.reinterpret_f64
199196
i64.const 63
200197
i64.shr_u
201-
i32.wrap_i64
202-
local.get $1
203-
local.get $1
204-
f64.eq
205-
i32.and
198+
i64.const 0
199+
i64.ne
206200
i32.const 0
207201
i32.ne
208202
i32.eq
@@ -382,20 +376,12 @@
382376
i32.reinterpret_f32
383377
i32.const 31
384378
i32.shr_u
385-
local.get $0
386-
local.get $0
387-
f32.eq
388-
i32.and
389379
i32.const 0
390380
i32.ne
391381
local.get $1
392382
i32.reinterpret_f32
393383
i32.const 31
394384
i32.shr_u
395-
local.get $1
396-
local.get $1
397-
f32.eq
398-
i32.and
399385
i32.const 0
400386
i32.ne
401387
i32.eq

tests/compiler/std/math.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3129,7 +3129,7 @@ assert(NativeMath.signbit(-0.0) == true);
31293129
assert(NativeMath.signbit(1.0) == false);
31303130
assert(NativeMath.signbit(-1.0) == true);
31313131
assert(NativeMath.signbit(+NaN) == false);
3132-
assert(NativeMath.signbit(-NaN) == false);
3132+
assert(NativeMath.signbit(-NaN) == true);
31333133
assert(NativeMath.signbit(+Infinity) == false);
31343134
assert(NativeMath.signbit(-Infinity) == true);
31353135

@@ -3142,7 +3142,7 @@ assert(NativeMathf.signbit(-0.0) == true);
31423142
assert(NativeMathf.signbit(1.0) == false);
31433143
assert(NativeMathf.signbit(-1.0) == true);
31443144
assert(NativeMathf.signbit(+NaN) == false);
3145-
assert(NativeMathf.signbit(-NaN) == false);
3145+
assert(NativeMathf.signbit(-NaN) == true);
31463146
assert(NativeMathf.signbit(+Infinity) == false);
31473147
assert(NativeMathf.signbit(-Infinity) == true);
31483148

@@ -4121,4 +4121,4 @@ assert(1 ** 0.5 == 1.0);
41214121
assert(0 ** 0.5 == 0.0);
41224122
assert(0 ** -1.0 == Infinity);
41234123
assert(0.0 ** 0 == 1.0);
4124-
assert(1.0 ** 1 == 1.0);
4124+
assert(1.0 ** 1 == 1.0);

tests/compiler/std/math.untouched.wat

Lines changed: 22 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,8 @@
269269
i64.reinterpret_f64
270270
i64.const 63
271271
i64.shr_u
272-
i32.wrap_i64
273-
local.get $3
274-
local.get $3
275-
f64.eq
276-
i32.and
272+
i64.const 0
273+
i64.ne
277274
i32.const 0
278275
i32.ne
279276
local.get $1
@@ -282,11 +279,8 @@
282279
i64.reinterpret_f64
283280
i64.const 63
284281
i64.shr_u
285-
i32.wrap_i64
286-
local.get $3
287-
local.get $3
288-
f64.eq
289-
i32.and
282+
i64.const 0
283+
i64.ne
290284
i32.const 0
291285
i32.ne
292286
i32.eq
@@ -503,10 +497,6 @@
503497
i32.reinterpret_f32
504498
i32.const 31
505499
i32.shr_u
506-
local.get $3
507-
local.get $3
508-
f32.eq
509-
i32.and
510500
i32.const 0
511501
i32.ne
512502
local.get $1
@@ -515,10 +505,6 @@
515505
i32.reinterpret_f32
516506
i32.const 31
517507
i32.shr_u
518-
local.get $3
519-
local.get $3
520-
f32.eq
521-
i32.and
522508
i32.const 0
523509
i32.ne
524510
i32.eq
@@ -48467,11 +48453,8 @@
4846748453
i64.reinterpret_f64
4846848454
i64.const 63
4846948455
i64.shr_u
48470-
i32.wrap_i64
48471-
local.get $0
48472-
local.get $0
48473-
f64.eq
48474-
i32.and
48456+
i64.const 0
48457+
i64.ne
4847548458
i32.const 0
4847648459
i32.ne
4847748460
i32.const 0
@@ -48483,11 +48466,8 @@
4848348466
i64.reinterpret_f64
4848448467
i64.const 63
4848548468
i64.shr_u
48486-
i32.wrap_i64
48487-
local.get $0
48488-
local.get $0
48489-
f64.eq
48490-
i32.and
48469+
i64.const 0
48470+
i64.ne
4849148471
i32.const 0
4849248472
i32.ne
4849348473
i32.const 1
@@ -48499,11 +48479,8 @@
4849948479
i64.reinterpret_f64
4850048480
i64.const 63
4850148481
i64.shr_u
48502-
i32.wrap_i64
48503-
local.get $0
48504-
local.get $0
48505-
f64.eq
48506-
i32.and
48482+
i64.const 0
48483+
i64.ne
4850748484
i32.const 0
4850848485
i32.ne
4850948486
i32.const 0
@@ -48515,11 +48492,8 @@
4851548492
i64.reinterpret_f64
4851648493
i64.const 63
4851748494
i64.shr_u
48518-
i32.wrap_i64
48519-
local.get $0
48520-
local.get $0
48521-
f64.eq
48522-
i32.and
48495+
i64.const 0
48496+
i64.ne
4852348497
i32.const 0
4852448498
i32.ne
4852548499
i32.const 1
@@ -48531,11 +48505,8 @@
4853148505
i64.reinterpret_f64
4853248506
i64.const 63
4853348507
i64.shr_u
48534-
i32.wrap_i64
48535-
local.get $0
48536-
local.get $0
48537-
f64.eq
48538-
i32.and
48508+
i64.const 0
48509+
i64.ne
4853948510
i32.const 0
4854048511
i32.ne
4854148512
i32.const 0
@@ -48548,14 +48519,11 @@
4854848519
i64.reinterpret_f64
4854948520
i64.const 63
4855048521
i64.shr_u
48551-
i32.wrap_i64
48552-
local.get $0
48553-
local.get $0
48554-
f64.eq
48555-
i32.and
48522+
i64.const 0
48523+
i64.ne
4855648524
i32.const 0
4855748525
i32.ne
48558-
i32.const 0
48526+
i32.const 1
4855948527
i32.eq
4856048528
drop
4856148529
f64.const inf
@@ -48564,11 +48532,8 @@
4856448532
i64.reinterpret_f64
4856548533
i64.const 63
4856648534
i64.shr_u
48567-
i32.wrap_i64
48568-
local.get $0
48569-
local.get $0
48570-
f64.eq
48571-
i32.and
48535+
i64.const 0
48536+
i64.ne
4857248537
i32.const 0
4857348538
i32.ne
4857448539
i32.const 0
@@ -48581,11 +48546,8 @@
4858148546
i64.reinterpret_f64
4858248547
i64.const 63
4858348548
i64.shr_u
48584-
i32.wrap_i64
48585-
local.get $0
48586-
local.get $0
48587-
f64.eq
48588-
i32.and
48549+
i64.const 0
48550+
i64.ne
4858948551
i32.const 0
4859048552
i32.ne
4859148553
i32.const 1
@@ -48597,10 +48559,6 @@
4859748559
i32.reinterpret_f32
4859848560
i32.const 31
4859948561
i32.shr_u
48600-
local.get $4
48601-
local.get $4
48602-
f32.eq
48603-
i32.and
4860448562
i32.const 0
4860548563
i32.ne
4860648564
i32.const 0
@@ -48612,10 +48570,6 @@
4861248570
i32.reinterpret_f32
4861348571
i32.const 31
4861448572
i32.shr_u
48615-
local.get $4
48616-
local.get $4
48617-
f32.eq
48618-
i32.and
4861948573
i32.const 0
4862048574
i32.ne
4862148575
i32.const 1
@@ -48627,10 +48581,6 @@
4862748581
i32.reinterpret_f32
4862848582
i32.const 31
4862948583
i32.shr_u
48630-
local.get $4
48631-
local.get $4
48632-
f32.eq
48633-
i32.and
4863448584
i32.const 0
4863548585
i32.ne
4863648586
i32.const 0
@@ -48642,10 +48592,6 @@
4864248592
i32.reinterpret_f32
4864348593
i32.const 31
4864448594
i32.shr_u
48645-
local.get $4
48646-
local.get $4
48647-
f32.eq
48648-
i32.and
4864948595
i32.const 0
4865048596
i32.ne
4865148597
i32.const 1
@@ -48657,10 +48603,6 @@
4865748603
i32.reinterpret_f32
4865848604
i32.const 31
4865948605
i32.shr_u
48660-
local.get $4
48661-
local.get $4
48662-
f32.eq
48663-
i32.and
4866448606
i32.const 0
4866548607
i32.ne
4866648608
i32.const 0
@@ -48673,13 +48615,9 @@
4867348615
i32.reinterpret_f32
4867448616
i32.const 31
4867548617
i32.shr_u
48676-
local.get $4
48677-
local.get $4
48678-
f32.eq
48679-
i32.and
4868048618
i32.const 0
4868148619
i32.ne
48682-
i32.const 0
48620+
i32.const 1
4868348621
i32.eq
4868448622
drop
4868548623
f32.const inf
@@ -48688,10 +48626,6 @@
4868848626
i32.reinterpret_f32
4868948627
i32.const 31
4869048628
i32.shr_u
48691-
local.get $4
48692-
local.get $4
48693-
f32.eq
48694-
i32.and
4869548629
i32.const 0
4869648630
i32.ne
4869748631
i32.const 0
@@ -48704,10 +48638,6 @@
4870448638
i32.reinterpret_f32
4870548639
i32.const 31
4870648640
i32.shr_u
48707-
local.get $4
48708-
local.get $4
48709-
f32.eq
48710-
i32.and
4871148641
i32.const 0
4871248642
i32.ne
4871348643
i32.const 1

tests/compiler/std/string.optimized.wat

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9243,16 +9243,10 @@
92439243
i32.const 3008
92449244
i32.const 0
92459245
call $~lib/string/parseInt
9246-
local.tee $3
92479246
i64.reinterpret_f64
92489247
i64.const 63
92499248
i64.shr_u
9250-
i32.wrap_i64
9251-
local.get $3
9252-
local.get $3
9253-
f64.eq
9254-
i32.and
9255-
i32.eqz
9249+
i64.eqz
92569250
if
92579251
i32.const 0
92589252
i32.const 1088

tests/compiler/std/string.untouched.wat

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13147,11 +13147,8 @@
1314713147
i64.reinterpret_f64
1314813148
i64.const 63
1314913149
i64.shr_u
13150-
i32.wrap_i64
13151-
local.get $32
13152-
local.get $32
13153-
f64.eq
13154-
i32.and
13150+
i64.const 0
13151+
i64.ne
1315513152
i32.const 0
1315613153
i32.ne
1315713154
i32.eqz

0 commit comments

Comments
 (0)