@@ -3682,7 +3682,7 @@ export class Compiler extends DiagnosticEmitter {
3682
3682
// f32 to int
3683
3683
if ( fromType . kind == TypeKind . F32 ) {
3684
3684
if ( toType . isBooleanValue ) {
3685
- expr = module . binary ( BinaryOp . NeF32 , expr , module . f32 ( 0 ) ) ;
3685
+ expr = this . makeIsTrueish ( expr , Type . f32 , reportNode ) ;
3686
3686
wrap = false ;
3687
3687
} else if ( toType . isSignedIntegerValue ) {
3688
3688
if ( toType . isLongIntegerValue ) {
@@ -3701,7 +3701,7 @@ export class Compiler extends DiagnosticEmitter {
3701
3701
// f64 to int
3702
3702
} else {
3703
3703
if ( toType . isBooleanValue ) {
3704
- expr = module . binary ( BinaryOp . NeF64 , expr , module . f64 ( 0 ) ) ;
3704
+ expr = this . makeIsTrueish ( expr , Type . f64 , reportNode ) ;
3705
3705
wrap = false ;
3706
3706
} else if ( toType . isSignedIntegerValue ) {
3707
3707
if ( toType . isLongIntegerValue ) {
@@ -10790,32 +10790,38 @@ export class Compiler extends DiagnosticEmitter {
10790
10790
: expr ;
10791
10791
}
10792
10792
case TypeKind . F32 : {
10793
- // (x != 0.0) & (x == x)
10794
- let flow = this . currentFlow ;
10795
- let temp = flow . getTempLocal ( Type . f32 ) ;
10796
- let ret = module . binary ( BinaryOp . AndI32 ,
10797
- module . binary ( BinaryOp . NeF32 , module . local_tee ( temp . index , expr ) , module . f32 ( 0 ) ) ,
10798
- module . binary ( BinaryOp . EqF32 ,
10799
- module . local_get ( temp . index , NativeType . F32 ) ,
10800
- module . local_get ( temp . index , NativeType . F32 )
10801
- )
10793
+ // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
10794
+ // (reinterpret<u32>(x) & 0x7FFFFFFF) - 1 <= 0x7F800000 - 1
10795
+ //
10796
+ // and finally:
10797
+ // (reinterpret<u32>(x) << 1) - (1 << 1) <= ((0x7F800000 - 1) << 1)
10798
+ return module . binary ( BinaryOp . LeU32 ,
10799
+ module . binary ( BinaryOp . SubI32 ,
10800
+ module . binary ( BinaryOp . ShlI32 ,
10801
+ module . unary ( UnaryOp . ReinterpretF32 , expr ) ,
10802
+ module . i32 ( 1 )
10803
+ ) ,
10804
+ module . i32 ( 2 ) // 1 << 1
10805
+ ) ,
10806
+ module . i32 ( 0xFEFFFFFE ) // (0x7F800000 - 1) << 1
10802
10807
) ;
10803
- flow . freeTempLocal ( temp ) ;
10804
- return ret ;
10805
10808
}
10806
10809
case TypeKind . F64 : {
10807
- // (x != 0.0) & (x == x)
10808
- let flow = this . currentFlow ;
10809
- let temp = flow . getTempLocal ( Type . f64 ) ;
10810
- let ret = module . binary ( BinaryOp . AndI32 ,
10811
- module . binary ( BinaryOp . NeF64 , module . local_tee ( temp . index , expr ) , module . f64 ( 0 ) ) ,
10812
- module . binary ( BinaryOp . EqF64 ,
10813
- module . local_get ( temp . index , NativeType . F64 ) ,
10814
- module . local_get ( temp . index , NativeType . F64 )
10815
- )
10810
+ // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
10811
+ // (reinterpret<u64>(x) & 0x7FFFFFFFFFFFFFFF) - 1 <= 0x7FF0000000000000 - 1
10812
+ //
10813
+ // and finally:
10814
+ // (reinterpret<u64>(x) << 1) - (1 << 1) <= ((0x7FF0000000000000 - 1) << 1)
10815
+ return module . binary ( BinaryOp . LeU64 ,
10816
+ module . binary ( BinaryOp . SubI64 ,
10817
+ module . binary ( BinaryOp . ShlI64 ,
10818
+ module . unary ( UnaryOp . ReinterpretF64 , expr ) ,
10819
+ module . i64 ( 1 )
10820
+ ) ,
10821
+ module . i64 ( 2 ) // 1 << 1
10822
+ ) ,
10823
+ module . i64 ( 0xFFFFFFFE , 0xFFDFFFFF ) // (0x7FF0000000000000 - 1) << 1
10816
10824
) ;
10817
- flow . freeTempLocal ( temp ) ;
10818
- return ret ;
10819
10825
}
10820
10826
case TypeKind . EXTERNREF : {
10821
10827
// TODO: non-null object might still be considered falseish
0 commit comments