@@ -675,6 +675,19 @@ class Asm2WasmBuilder {
675675 return ret;
676676 }
677677
678+ // converts an f32 to an f64 if necessary
679+ Expression* ensureDouble (Expression* expr) {
680+ if (expr->type == f32 ) {
681+ auto conv = allocator.alloc <Unary>();
682+ conv->op = PromoteFloat32;
683+ conv->value = expr;
684+ conv->type = WasmType::f64 ;
685+ return conv;
686+ }
687+ assert (expr->type == f64 );
688+ return expr;
689+ }
690+
678691 // Some binary opts might trap, so emit them safely if necessary
679692 Expression* makeTrappingI32Binary (BinaryOp op, Expression* left, Expression* right) {
680693 if (trapMode == TrapMode::Allow) return builder.makeBinary (op, left, right);
@@ -803,14 +816,7 @@ class Asm2WasmBuilder {
803816 }
804817 // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must do something
805818 // First, normalize input to f64
806- auto input = value;
807- if (input->type == f32 ) {
808- auto conv = allocator.alloc <Unary>();
809- conv->op = PromoteFloat32;
810- conv->value = input;
811- conv->type = WasmType::f64 ;
812- input = conv;
813- }
819+ auto input = ensureDouble (value);
814820 // We can handle this in one of two ways: clamping, which is fast, or JS, which
815821 // is precisely like JS but in order to do that we do a slow ffi
816822 if (trapMode == TrapMode::JS) {
@@ -894,14 +900,7 @@ class Asm2WasmBuilder {
894900 }
895901 // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must do something
896902 // First, normalize input to f64
897- auto input = value;
898- if (input->type == f32 ) {
899- auto conv = allocator.alloc <Unary>();
900- conv->op = PromoteFloat32;
901- conv->value = input;
902- conv->type = WasmType::f64 ;
903- input = conv;
904- }
903+ auto input = ensureDouble (value);
905904 // There is no "JS" way to handle this, as no i64s in JS, so always clamp if we don't allow traps
906905 Call *ret = allocator.alloc <Call>();
907906 ret->target = F64_TO_INT64;
@@ -1795,11 +1794,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
17951794 conv->type = WasmType::f32 ;
17961795 ret->value = conv;
17971796 } else if (ret->valueType == f64 && ret->value ->type == f32 ) {
1798- auto conv = allocator.alloc <Unary>();
1799- conv->op = PromoteFloat32;
1800- conv->value = ret->value ;
1801- conv->type = WasmType::f64 ;
1802- ret->value = conv;
1797+ ret->value = ensureDouble (ret->value );
18031798 } else {
18041799 abort_on (" bad sub[] types" , ast);
18051800 }
@@ -1822,8 +1817,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
18221817 // WebAssembly does not have floating-point remainder, we have to emit a call to a special import of ours
18231818 CallImport *call = allocator.alloc <CallImport>();
18241819 call->target = F64_REM;
1825- call->operands .push_back (ret->left );
1826- call->operands .push_back (ret->right );
1820+ call->operands .push_back (ensureDouble ( ret->left ) );
1821+ call->operands .push_back (ensureDouble ( ret->right ) );
18271822 call->type = f64 ;
18281823 static bool addedImport = false ;
18291824 if (!addedImport) {
@@ -1873,11 +1868,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
18731868 return conv;
18741869 }
18751870 if (ret->type == f32 ) {
1876- auto conv = allocator.alloc <Unary>();
1877- conv->op = PromoteFloat32;
1878- conv->value = ret;
1879- conv->type = WasmType::f64 ;
1880- return conv;
1871+ return ensureDouble (ret);
18811872 }
18821873 fixCallType (ret, f64 );
18831874 return ret;
@@ -2485,11 +2476,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
24852476 conv->value = process (writtenValue);
24862477 conv->type = WasmType::f32 ;
24872478 if (readType == ASM_DOUBLE) {
2488- auto promote = allocator.alloc <Unary>();
2489- promote->op = PromoteFloat32;
2490- promote->value = conv;
2491- promote->type = WasmType::f64 ;
2492- return promote;
2479+ return ensureDouble (conv);
24932480 }
24942481 return conv;
24952482 } else if (writeType == ASM_FLOAT && readType == ASM_INT) {
0 commit comments