@@ -3682,7 +3682,7 @@ export class Compiler extends DiagnosticEmitter {
36823682 // f32 to int
36833683 if ( fromType . kind == TypeKind . F32 ) {
36843684 if ( toType . isBooleanValue ) {
3685- expr = module . binary ( BinaryOp . NeF32 , expr , module . f32 ( 0 ) ) ;
3685+ expr = this . makeIsTrueish ( expr , Type . f32 , reportNode ) ;
36863686 wrap = false ;
36873687 } else if ( toType . isSignedIntegerValue ) {
36883688 if ( toType . isLongIntegerValue ) {
@@ -3701,7 +3701,7 @@ export class Compiler extends DiagnosticEmitter {
37013701 // f64 to int
37023702 } else {
37033703 if ( toType . isBooleanValue ) {
3704- expr = module . binary ( BinaryOp . NeF64 , expr , module . f64 ( 0 ) ) ;
3704+ expr = this . makeIsTrueish ( expr , Type . f64 , reportNode ) ;
37053705 wrap = false ;
37063706 } else if ( toType . isSignedIntegerValue ) {
37073707 if ( toType . isLongIntegerValue ) {
@@ -10790,32 +10790,38 @@ export class Compiler extends DiagnosticEmitter {
1079010790 : expr ;
1079110791 }
1079210792 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
1080210807 ) ;
10803- flow . freeTempLocal ( temp ) ;
10804- return ret ;
1080510808 }
1080610809 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
1081610824 ) ;
10817- flow . freeTempLocal ( temp ) ;
10818- return ret ;
1081910825 }
1082010826 case TypeKind . EXTERNREF : {
1082110827 // TODO: non-null object might still be considered falseish
0 commit comments