@@ -675,6 +675,19 @@ class Asm2WasmBuilder {
675
675
return ret;
676
676
}
677
677
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
+
678
691
// Some binary opts might trap, so emit them safely if necessary
679
692
Expression* makeTrappingI32Binary (BinaryOp op, Expression* left, Expression* right) {
680
693
if (trapMode == TrapMode::Allow) return builder.makeBinary (op, left, right);
@@ -803,14 +816,7 @@ class Asm2WasmBuilder {
803
816
}
804
817
// WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must do something
805
818
// 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);
814
820
// We can handle this in one of two ways: clamping, which is fast, or JS, which
815
821
// is precisely like JS but in order to do that we do a slow ffi
816
822
if (trapMode == TrapMode::JS) {
@@ -894,14 +900,7 @@ class Asm2WasmBuilder {
894
900
}
895
901
// WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must do something
896
902
// 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);
905
904
// There is no "JS" way to handle this, as no i64s in JS, so always clamp if we don't allow traps
906
905
Call *ret = allocator.alloc <Call>();
907
906
ret->target = F64_TO_INT64;
@@ -1795,11 +1794,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
1795
1794
conv->type = WasmType::f32;
1796
1795
ret->value = conv;
1797
1796
} 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 );
1803
1798
} else {
1804
1799
abort_on (" bad sub[] types" , ast);
1805
1800
}
@@ -1822,8 +1817,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
1822
1817
// WebAssembly does not have floating-point remainder, we have to emit a call to a special import of ours
1823
1818
CallImport *call = allocator.alloc <CallImport>();
1824
1819
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 ) );
1827
1822
call->type = f64;
1828
1823
static bool addedImport = false ;
1829
1824
if (!addedImport) {
@@ -1873,11 +1868,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
1873
1868
return conv;
1874
1869
}
1875
1870
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);
1881
1872
}
1882
1873
fixCallType (ret, f64);
1883
1874
return ret;
@@ -2485,11 +2476,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
2485
2476
conv->value = process (writtenValue);
2486
2477
conv->type = WasmType::f32;
2487
2478
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);
2493
2480
}
2494
2481
return conv;
2495
2482
} else if (writeType == ASM_FLOAT && readType == ASM_INT) {
0 commit comments