@@ -9885,38 +9885,74 @@ export class Compiler extends DiagnosticEmitter {
98859885 : expr ;
98869886 }
98879887 case TypeKind . F32 : {
9888- // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
9889- // (reinterpret<u32>(x) & 0x7FFFFFFF) - 1 <= 0x7F800000 - 1
9890- //
9891- // and finally:
9892- // (reinterpret<u32>(x) << 1) - (1 << 1) <= ((0x7F800000 - 1) << 1)
9893- return module . binary ( BinaryOp . LeU32 ,
9894- module . binary ( BinaryOp . SubI32 ,
9895- module . binary ( BinaryOp . ShlI32 ,
9896- module . unary ( UnaryOp . ReinterpretF32ToI32 , expr ) ,
9897- module . i32 ( 1 )
9888+ let options = this . options ;
9889+ if (
9890+ options . shrinkLevelHint > 1 &&
9891+ options . hasFeature ( Feature . NONTRAPPING_F2I )
9892+ ) {
9893+ // Use more compact but slower 5-byte (3 bytes in best case) approach
9894+ // !!(i32.trunc_sat_f32_u(f32.ceil(f32.abs(x))))
9895+ return module . unary ( UnaryOp . EqzI32 ,
9896+ module . unary ( UnaryOp . EqzI32 ,
9897+ module . unary ( UnaryOp . TruncSatF32ToU32 ,
9898+ module . unary ( UnaryOp . CeilF32 ,
9899+ module . unary ( UnaryOp . AbsF32 , expr )
9900+ )
9901+ )
9902+ )
9903+ ) ;
9904+ } else {
9905+ // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
9906+ // (reinterpret<u32>(x) & 0x7FFFFFFF) - 1 <= 0x7F800000 - 1
9907+ //
9908+ // and finally:
9909+ // (reinterpret<u32>(x) << 1) - (1 << 1) <= ((0x7F800000 - 1) << 1)
9910+ return module . binary ( BinaryOp . LeU32 ,
9911+ module . binary ( BinaryOp . SubI32 ,
9912+ module . binary ( BinaryOp . ShlI32 ,
9913+ module . unary ( UnaryOp . ReinterpretF32ToI32 , expr ) ,
9914+ module . i32 ( 1 )
9915+ ) ,
9916+ module . i32 ( 2 ) // 1 << 1
98989917 ) ,
9899- module . i32 ( 2 ) // 1 << 1
9900- ) ,
9901- module . i32 ( 0xFEFFFFFE ) // (0x7F800000 - 1) << 1
9902- ) ;
9918+ module . i32 ( 0xFEFFFFFE ) // (0x7F800000 - 1) << 1
9919+ ) ;
9920+ }
99039921 }
99049922 case TypeKind . F64 : {
9905- // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
9906- // (reinterpret<u64>(x) & 0x7FFFFFFFFFFFFFFF) - 1 <= 0x7FF0000000000000 - 1
9907- //
9908- // and finally:
9909- // (reinterpret<u64>(x) << 1) - (1 << 1) <= ((0x7FF0000000000000 - 1) << 1)
9910- return module . binary ( BinaryOp . LeU64 ,
9911- module . binary ( BinaryOp . SubI64 ,
9912- module . binary ( BinaryOp . ShlI64 ,
9913- module . unary ( UnaryOp . ReinterpretF64ToI64 , expr ) ,
9914- module . i64 ( 1 )
9923+ let options = this . options ;
9924+ if (
9925+ options . shrinkLevelHint > 1 &&
9926+ options . hasFeature ( Feature . NONTRAPPING_F2I )
9927+ ) {
9928+ // Use more compact but slower 5-byte (3 bytes in best case) approach
9929+ // !!(i32.trunc_sat_f64_u(f64.ceil(f64.abs(x))))
9930+ return module . unary ( UnaryOp . EqzI32 ,
9931+ module . unary ( UnaryOp . EqzI32 ,
9932+ module . unary ( UnaryOp . TruncSatF64ToU32 ,
9933+ module . unary ( UnaryOp . CeilF64 ,
9934+ module . unary ( UnaryOp . AbsF64 , expr )
9935+ )
9936+ )
9937+ )
9938+ ) ;
9939+ } else {
9940+ // 0 < abs(bitCast(x)) <= bitCast(Infinity) or
9941+ // (reinterpret<u64>(x) & 0x7FFFFFFFFFFFFFFF) - 1 <= 0x7FF0000000000000 - 1
9942+ //
9943+ // and finally:
9944+ // (reinterpret<u64>(x) << 1) - (1 << 1) <= ((0x7FF0000000000000 - 1) << 1)
9945+ return module . binary ( BinaryOp . LeU64 ,
9946+ module . binary ( BinaryOp . SubI64 ,
9947+ module . binary ( BinaryOp . ShlI64 ,
9948+ module . unary ( UnaryOp . ReinterpretF64ToI64 , expr ) ,
9949+ module . i64 ( 1 )
9950+ ) ,
9951+ module . i64 ( 2 ) // 1 << 1
99159952 ) ,
9916- module . i64 ( 2 ) // 1 << 1
9917- ) ,
9918- module . i64 ( 0xFFFFFFFE , 0xFFDFFFFF ) // (0x7FF0000000000000 - 1) << 1
9919- ) ;
9953+ module . i64 ( 0xFFFFFFFE , 0xFFDFFFFF ) // (0x7FF0000000000000 - 1) << 1
9954+ ) ;
9955+ }
99209956 }
99219957 case TypeKind . V128 : {
99229958 return module . unary ( UnaryOp . AnyTrueV128 , expr ) ;
0 commit comments