diff options
-rw-r--r-- | src/asm2wasm.h | 8 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 28 | ||||
-rw-r--r-- | src/passes/PostEmscripten.cpp | 57 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 22 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 22 | ||||
-rw-r--r-- | test/memorygrowth.fromasm | 295 | ||||
-rw-r--r-- | test/memorygrowth.fromasm.imprecise | 295 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 70 | ||||
-rw-r--r-- | test/passes/post-emscripten.txt | 73 | ||||
-rw-r--r-- | test/passes/post-emscripten.wast | 101 |
10 files changed, 593 insertions, 378 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 9cf8cf75a..2a6bcd0e7 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -859,13 +859,6 @@ void Asm2WasmBuilder::processAsm(Ref ast) { if (runOptimizationPasses) { optimizingBuilder->finish(); - PassRunner passRunner(&wasm); - if (debug) { - passRunner.setDebug(true); - passRunner.setValidateGlobally(false); - } - passRunner.add("post-emscripten"); - passRunner.run(); } // second pass. first, function imports @@ -993,6 +986,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { passRunner.add("vacuum"); passRunner.add("remove-unused-brs"); passRunner.add("optimize-instructions"); + passRunner.add("post-emscripten"); } passRunner.run(); diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 37207ffc7..04216f1ee 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -436,33 +436,7 @@ private: // fold constant factors into the offset void optimizeMemoryAccess(Expression*& ptr, Address& offset) { - while (1) { - auto* add = ptr->dynCast<Binary>(); - if (!add) break; - if (add->op != AddInt32) break; - auto* left = add->left->dynCast<Const>(); - auto* right = add->right->dynCast<Const>(); - // note: in optimized code, we shouldn't see an add of two constants, so don't worry about that much - // (precompute would optimize that) - if (left) { - auto value = left->value.geti32(); - if (value >= 0) { - offset = offset + value; - ptr = add->right; - continue; - } - } - if (right) { - auto value = right->value.geti32(); - if (value >= 0) { - offset = offset + value; - ptr = add->left; - continue; - } - } - break; - } - // finally, ptr may be a const, but it isn't worth folding that in (we still have a const); in fact, + // ptr may be a const, but it isn't worth folding that in (we still have a const); in fact, // it's better to do the opposite for gzip purposes as well as for readability. auto* last = ptr->dynCast<Const>(); if (last) { diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp index e46270c50..9a28efb1c 100644 --- a/src/passes/PostEmscripten.cpp +++ b/src/passes/PostEmscripten.cpp @@ -44,36 +44,49 @@ struct PostEmscripten : public WalkerPass<PostWalker<PostEmscripten, Visitor<Pos // it's 0 or an unused section of memory that was reserved for mapped globlas). // Thus it is ok to optimize such small constants into Load offsets. - template<typename T> - void visitMemoryOp(T *curr) { - if (curr->offset) return; - Expression* ptr = curr->ptr; - auto add = ptr->dynCast<Binary>(); - if (!add || add->op != AddInt32) return; - assert(add->type == i32); - auto c = add->right->dynCast<Const>(); - if (!c) { - c = add->left->dynCast<Const>(); - if (c) { - // if one is a const, it's ok to swap - add->left = add->right; - add->right = c; + #define SAFE_MAX 1024 + + void optimizeMemoryAccess(Expression*& ptr, Address& offset) { + while (1) { + auto* add = ptr->dynCast<Binary>(); + if (!add) break; + if (add->op != AddInt32) break; + auto* left = add->left->dynCast<Const>(); + auto* right = add->right->dynCast<Const>(); + // note: in optimized code, we shouldn't see an add of two constants, so don't worry about that much + // (precompute would optimize that) + if (left) { + auto value = left->value.geti32(); + if (value >= 0 && value < SAFE_MAX) { + offset = offset + value; + ptr = add->right; + continue; + } + } + if (right) { + auto value = right->value.geti32(); + if (value >= 0 && value < SAFE_MAX) { + offset = offset + value; + ptr = add->left; + continue; + } } + break; } - if (!c) return; - auto value = c->value.geti32(); - if (value >= 0 && value < 1024) { - // foldable, by the above logic - curr->ptr = add->left; - curr->offset = value; + // finally ptr may be a const, but it isn't worth folding that in (we still have a const); in fact, + // it's better to do the opposite for gzip purposes as well as for readability. + auto* last = ptr->dynCast<Const>(); + if (last) { + last->value = Literal(int32_t(last->value.geti32() + offset)); + offset = 0; } } void visitLoad(Load* curr) { - visitMemoryOp(curr); + optimizeMemoryAccess(curr->ptr, curr->offset); } void visitStore(Store* curr) { - visitMemoryOp(curr); + optimizeMemoryAccess(curr->ptr, curr->offset); } }; diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index afb161718..06f88befe 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -4357,11 +4357,14 @@ (i32.store8 (get_local $5) (i32.or - (i32.load8_u offset=4075 - (tee_local $7 - (call $f64-to-int - (get_local $15) + (i32.load8_u + (i32.add + (tee_local $7 + (call $f64-to-int + (get_local $15) + ) ) + (i32.const 4075) ) ) (get_local $13) @@ -6596,10 +6599,13 @@ ) ) (i32.or - (i32.load8_u offset=4075 - (i32.and - (get_local $5) - (i32.const 15) + (i32.load8_u + (i32.add + (i32.and + (get_local $5) + (i32.const 15) + ) + (i32.const 4075) ) ) (get_local $9) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index adadfe086..4363dc349 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -4349,11 +4349,14 @@ (i32.store8 (get_local $5) (i32.or - (i32.load8_u offset=4075 - (tee_local $7 - (i32.trunc_s/f64 - (get_local $15) + (i32.load8_u + (i32.add + (tee_local $7 + (i32.trunc_s/f64 + (get_local $15) + ) ) + (i32.const 4075) ) ) (get_local $13) @@ -6582,10 +6585,13 @@ ) ) (i32.or - (i32.load8_u offset=4075 - (i32.and - (get_local $5) - (i32.const 15) + (i32.load8_u + (i32.add + (i32.and + (get_local $5) + (i32.const 15) + ) + (i32.const 4075) ) ) (get_local $9) diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm index f61e92441..1422a65a9 100644 --- a/test/memorygrowth.fromasm +++ b/test/memorygrowth.fromasm @@ -723,80 +723,83 @@ (i32.and (i32.load offset=4 (tee_local $14 - (i32.load offset=1512 - (i32.shl - (i32.add - (i32.or + (i32.load + (i32.add + (i32.shl + (i32.add (i32.or (i32.or (i32.or - (tee_local $8 + (i32.or + (tee_local $8 + (i32.and + (i32.shr_u + (tee_local $4 + (i32.shr_u + (get_local $8) + (get_local $12) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (get_local $12) + ) + (tee_local $4 (i32.and (i32.shr_u - (tee_local $4 + (tee_local $1 (i32.shr_u + (get_local $4) (get_local $8) - (get_local $12) ) ) - (i32.const 5) + (i32.const 2) ) - (i32.const 8) + (i32.const 4) ) ) - (get_local $12) ) - (tee_local $4 + (tee_local $1 (i32.and (i32.shr_u - (tee_local $1 + (tee_local $0 (i32.shr_u + (get_local $1) (get_local $4) - (get_local $8) ) ) - (i32.const 2) + (i32.const 1) ) - (i32.const 4) + (i32.const 2) ) ) ) - (tee_local $1 + (tee_local $0 (i32.and (i32.shr_u - (tee_local $0 + (tee_local $5 (i32.shr_u + (get_local $0) (get_local $1) - (get_local $4) ) ) (i32.const 1) ) - (i32.const 2) - ) - ) - ) - (tee_local $0 - (i32.and - (i32.shr_u - (tee_local $5 - (i32.shr_u - (get_local $0) - (get_local $1) - ) - ) (i32.const 1) ) - (i32.const 1) ) ) + (i32.shr_u + (get_local $5) + (get_local $0) + ) ) - (i32.shr_u - (get_local $5) - (get_local $0) - ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) @@ -1463,106 +1466,109 @@ (block $label$break$a (if (tee_local $12 - (i32.load offset=1512 - (i32.shl - (tee_local $27 - (if i32 - (tee_local $7 - (i32.shr_u - (get_local $1) - (i32.const 8) - ) - ) + (i32.load + (i32.add + (i32.shl + (tee_local $27 (if i32 - (i32.gt_u - (get_local $0) - (i32.const 16777215) + (tee_local $7 + (i32.shr_u + (get_local $1) + (i32.const 8) + ) ) - (i32.const 31) - (i32.or - (i32.and - (i32.shr_u - (get_local $0) - (i32.add - (tee_local $12 - (i32.add - (i32.sub - (i32.const 14) - (i32.or + (if i32 + (i32.gt_u + (get_local $0) + (i32.const 16777215) + ) + (i32.const 31) + (i32.or + (i32.and + (i32.shr_u + (get_local $0) + (i32.add + (tee_local $12 + (i32.add + (i32.sub + (i32.const 14) (i32.or - (tee_local $7 - (i32.and - (i32.shr_u - (i32.add - (tee_local $16 - (i32.shl - (get_local $7) - (tee_local $1 - (i32.and - (i32.shr_u - (i32.add - (get_local $7) - (i32.const 1048320) + (i32.or + (tee_local $7 + (i32.and + (i32.shr_u + (i32.add + (tee_local $16 + (i32.shl + (get_local $7) + (tee_local $1 + (i32.and + (i32.shr_u + (i32.add + (get_local $7) + (i32.const 1048320) + ) + (i32.const 16) ) - (i32.const 16) + (i32.const 8) ) - (i32.const 8) ) ) ) + (i32.const 520192) ) - (i32.const 520192) + (i32.const 16) ) - (i32.const 16) + (i32.const 4) ) - (i32.const 4) ) + (get_local $1) ) - (get_local $1) - ) - (tee_local $16 - (i32.and - (i32.shr_u - (i32.add - (tee_local $14 - (i32.shl - (get_local $16) - (get_local $7) + (tee_local $16 + (i32.and + (i32.shr_u + (i32.add + (tee_local $14 + (i32.shl + (get_local $16) + (get_local $7) + ) ) + (i32.const 245760) ) - (i32.const 245760) + (i32.const 16) ) - (i32.const 16) + (i32.const 2) ) - (i32.const 2) ) ) ) - ) - (i32.shr_u - (i32.shl - (get_local $14) - (get_local $16) + (i32.shr_u + (i32.shl + (get_local $14) + (get_local $16) + ) + (i32.const 15) ) - (i32.const 15) ) ) + (i32.const 7) ) - (i32.const 7) ) + (i32.const 1) + ) + (i32.shl + (get_local $12) + (i32.const 1) ) - (i32.const 1) - ) - (i32.shl - (get_local $12) - (i32.const 1) ) ) + (i32.const 0) ) - (i32.const 0) ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) @@ -1802,80 +1808,83 @@ (i32.const 16) ) ) - (i32.load offset=1512 - (i32.shl - (i32.add - (i32.or + (i32.load + (i32.add + (i32.shl + (i32.add (i32.or (i32.or (i32.or - (tee_local $12 + (i32.or + (tee_local $12 + (i32.and + (i32.shr_u + (tee_local $3 + (i32.shr_u + (get_local $12) + (get_local $4) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (get_local $4) + ) + (tee_local $3 (i32.and (i32.shr_u - (tee_local $3 + (tee_local $5 (i32.shr_u + (get_local $3) (get_local $12) - (get_local $4) ) ) - (i32.const 5) + (i32.const 2) ) - (i32.const 8) + (i32.const 4) ) ) - (get_local $4) ) - (tee_local $3 + (tee_local $5 (i32.and (i32.shr_u - (tee_local $5 + (tee_local $8 (i32.shr_u + (get_local $5) (get_local $3) - (get_local $12) ) ) - (i32.const 2) + (i32.const 1) ) - (i32.const 4) + (i32.const 2) ) ) ) - (tee_local $5 + (tee_local $8 (i32.and (i32.shr_u - (tee_local $8 + (tee_local $1 (i32.shr_u + (get_local $8) (get_local $5) - (get_local $3) ) ) (i32.const 1) ) - (i32.const 2) - ) - ) - ) - (tee_local $8 - (i32.and - (i32.shr_u - (tee_local $1 - (i32.shr_u - (get_local $8) - (get_local $5) - ) - ) (i32.const 1) ) - (i32.const 1) ) ) + (i32.shr_u + (get_local $1) + (get_local $8) + ) ) - (i32.shr_u - (get_local $1) - (get_local $8) - ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise index 3d244ccad..4301d1105 100644 --- a/test/memorygrowth.fromasm.imprecise +++ b/test/memorygrowth.fromasm.imprecise @@ -721,80 +721,83 @@ (i32.and (i32.load offset=4 (tee_local $14 - (i32.load offset=1512 - (i32.shl - (i32.add - (i32.or + (i32.load + (i32.add + (i32.shl + (i32.add (i32.or (i32.or (i32.or - (tee_local $8 + (i32.or + (tee_local $8 + (i32.and + (i32.shr_u + (tee_local $4 + (i32.shr_u + (get_local $8) + (get_local $12) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (get_local $12) + ) + (tee_local $4 (i32.and (i32.shr_u - (tee_local $4 + (tee_local $1 (i32.shr_u + (get_local $4) (get_local $8) - (get_local $12) ) ) - (i32.const 5) + (i32.const 2) ) - (i32.const 8) + (i32.const 4) ) ) - (get_local $12) ) - (tee_local $4 + (tee_local $1 (i32.and (i32.shr_u - (tee_local $1 + (tee_local $0 (i32.shr_u + (get_local $1) (get_local $4) - (get_local $8) ) ) - (i32.const 2) + (i32.const 1) ) - (i32.const 4) + (i32.const 2) ) ) ) - (tee_local $1 + (tee_local $0 (i32.and (i32.shr_u - (tee_local $0 + (tee_local $5 (i32.shr_u + (get_local $0) (get_local $1) - (get_local $4) ) ) (i32.const 1) ) - (i32.const 2) - ) - ) - ) - (tee_local $0 - (i32.and - (i32.shr_u - (tee_local $5 - (i32.shr_u - (get_local $0) - (get_local $1) - ) - ) (i32.const 1) ) - (i32.const 1) ) ) + (i32.shr_u + (get_local $5) + (get_local $0) + ) ) - (i32.shr_u - (get_local $5) - (get_local $0) - ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) @@ -1461,106 +1464,109 @@ (block $label$break$a (if (tee_local $12 - (i32.load offset=1512 - (i32.shl - (tee_local $27 - (if i32 - (tee_local $7 - (i32.shr_u - (get_local $1) - (i32.const 8) - ) - ) + (i32.load + (i32.add + (i32.shl + (tee_local $27 (if i32 - (i32.gt_u - (get_local $0) - (i32.const 16777215) + (tee_local $7 + (i32.shr_u + (get_local $1) + (i32.const 8) + ) ) - (i32.const 31) - (i32.or - (i32.and - (i32.shr_u - (get_local $0) - (i32.add - (tee_local $12 - (i32.add - (i32.sub - (i32.const 14) - (i32.or + (if i32 + (i32.gt_u + (get_local $0) + (i32.const 16777215) + ) + (i32.const 31) + (i32.or + (i32.and + (i32.shr_u + (get_local $0) + (i32.add + (tee_local $12 + (i32.add + (i32.sub + (i32.const 14) (i32.or - (tee_local $7 - (i32.and - (i32.shr_u - (i32.add - (tee_local $16 - (i32.shl - (get_local $7) - (tee_local $1 - (i32.and - (i32.shr_u - (i32.add - (get_local $7) - (i32.const 1048320) + (i32.or + (tee_local $7 + (i32.and + (i32.shr_u + (i32.add + (tee_local $16 + (i32.shl + (get_local $7) + (tee_local $1 + (i32.and + (i32.shr_u + (i32.add + (get_local $7) + (i32.const 1048320) + ) + (i32.const 16) ) - (i32.const 16) + (i32.const 8) ) - (i32.const 8) ) ) ) + (i32.const 520192) ) - (i32.const 520192) + (i32.const 16) ) - (i32.const 16) + (i32.const 4) ) - (i32.const 4) ) + (get_local $1) ) - (get_local $1) - ) - (tee_local $16 - (i32.and - (i32.shr_u - (i32.add - (tee_local $14 - (i32.shl - (get_local $16) - (get_local $7) + (tee_local $16 + (i32.and + (i32.shr_u + (i32.add + (tee_local $14 + (i32.shl + (get_local $16) + (get_local $7) + ) ) + (i32.const 245760) ) - (i32.const 245760) + (i32.const 16) ) - (i32.const 16) + (i32.const 2) ) - (i32.const 2) ) ) ) - ) - (i32.shr_u - (i32.shl - (get_local $14) - (get_local $16) + (i32.shr_u + (i32.shl + (get_local $14) + (get_local $16) + ) + (i32.const 15) ) - (i32.const 15) ) ) + (i32.const 7) ) - (i32.const 7) ) + (i32.const 1) + ) + (i32.shl + (get_local $12) + (i32.const 1) ) - (i32.const 1) - ) - (i32.shl - (get_local $12) - (i32.const 1) ) ) + (i32.const 0) ) - (i32.const 0) ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) @@ -1800,80 +1806,83 @@ (i32.const 16) ) ) - (i32.load offset=1512 - (i32.shl - (i32.add - (i32.or + (i32.load + (i32.add + (i32.shl + (i32.add (i32.or (i32.or (i32.or - (tee_local $12 + (i32.or + (tee_local $12 + (i32.and + (i32.shr_u + (tee_local $3 + (i32.shr_u + (get_local $12) + (get_local $4) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (get_local $4) + ) + (tee_local $3 (i32.and (i32.shr_u - (tee_local $3 + (tee_local $5 (i32.shr_u + (get_local $3) (get_local $12) - (get_local $4) ) ) - (i32.const 5) + (i32.const 2) ) - (i32.const 8) + (i32.const 4) ) ) - (get_local $4) ) - (tee_local $3 + (tee_local $5 (i32.and (i32.shr_u - (tee_local $5 + (tee_local $8 (i32.shr_u + (get_local $5) (get_local $3) - (get_local $12) ) ) - (i32.const 2) + (i32.const 1) ) - (i32.const 4) + (i32.const 2) ) ) ) - (tee_local $5 + (tee_local $8 (i32.and (i32.shr_u - (tee_local $8 + (tee_local $1 (i32.shr_u + (get_local $8) (get_local $5) - (get_local $3) ) ) (i32.const 1) ) - (i32.const 2) - ) - ) - ) - (tee_local $8 - (i32.and - (i32.shr_u - (tee_local $1 - (i32.shr_u - (get_local $8) - (get_local $5) - ) - ) (i32.const 1) ) - (i32.const 1) ) ) + (i32.shr_u + (get_local $1) + (get_local $8) + ) ) - (i32.shr_u - (get_local $1) - (get_local $8) - ) + (i32.const 2) ) - (i32.const 2) + (i32.const 1512) ) ) ) diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index a8cf68dbd..f959c3cd6 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -415,20 +415,32 @@ ) ) (func $load-off-2 (type $3) (param $0 i32) (result i32) - (i32.store - (i32.const 6) + (i32.store offset=2 + (i32.add + (i32.const 1) + (i32.const 3) + ) (get_local $0) ) - (i32.store - (i32.const 6) + (i32.store offset=2 + (i32.add + (i32.const 3) + (i32.const 1) + ) (get_local $0) ) - (i32.store offset=7 - (get_local $0) + (i32.store offset=2 + (i32.add + (get_local $0) + (i32.const 5) + ) (get_local $0) ) - (i32.store offset=9 - (get_local $0) + (i32.store offset=2 + (i32.add + (get_local $0) + (i32.const 7) + ) (get_local $0) ) (i32.store offset=2 @@ -445,12 +457,18 @@ ) (get_local $0) ) - (i32.store - (i32.const 4) + (i32.store offset=2 + (i32.add + (i32.const -15) + (i32.const 17) + ) (get_local $0) ) - (i32.store - (i32.const 0) + (i32.store offset=2 + (i32.add + (i32.const -21) + (i32.const 19) + ) (get_local $0) ) (i32.store @@ -462,18 +480,27 @@ (get_local $0) ) (drop - (i32.load - (i32.const 8) + (i32.load offset=2 + (i32.add + (i32.const 2) + (i32.const 4) + ) ) ) (drop - (i32.load - (i32.const 8) + (i32.load offset=2 + (i32.add + (i32.const 4) + (i32.const 2) + ) ) ) (drop - (i32.load offset=8 - (get_local $0) + (i32.load offset=2 + (i32.add + (get_local $0) + (i32.const 6) + ) ) ) (drop @@ -481,8 +508,11 @@ (i32.const 10) ) ) - (i32.load offset=12 - (get_local $0) + (i32.load offset=2 + (i32.add + (get_local $0) + (i32.const 10) + ) ) ) ) diff --git a/test/passes/post-emscripten.txt b/test/passes/post-emscripten.txt index a2acbbb28..830d4276e 100644 --- a/test/passes/post-emscripten.txt +++ b/test/passes/post-emscripten.txt @@ -1,6 +1,8 @@ (module (type $0 (func (param i32))) + (type $1 (func (param i32) (result i32))) (memory $0 256 256) + (export "load-off-2" (func $load-off-2)) (func $b0 (type $0) (param $x i32) (drop (i32.load offset=1 @@ -39,4 +41,75 @@ ) ) ) + (func $load-off-2 (type $1) (param $0 i32) (result i32) + (i32.store + (i32.const 6) + (get_local $0) + ) + (i32.store + (i32.const 6) + (get_local $0) + ) + (i32.store offset=7 + (get_local $0) + (get_local $0) + ) + (i32.store offset=9 + (get_local $0) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -11) + (get_local $0) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (get_local $0) + (i32.const -13) + ) + (get_local $0) + ) + (i32.store + (i32.const 4) + (get_local $0) + ) + (i32.store + (i32.const 0) + (get_local $0) + ) + (i32.store + (i32.const 25) + (get_local $0) + ) + (i32.store + (i32.const -23) + (get_local $0) + ) + (drop + (i32.load + (i32.const 8) + ) + ) + (drop + (i32.load + (i32.const 8) + ) + ) + (drop + (i32.load offset=8 + (get_local $0) + ) + ) + (drop + (i32.load + (i32.const 10) + ) + ) + (i32.load offset=12 + (get_local $0) + ) + ) ) diff --git a/test/passes/post-emscripten.wast b/test/passes/post-emscripten.wast index b554fea53..f262975f5 100644 --- a/test/passes/post-emscripten.wast +++ b/test/passes/post-emscripten.wast @@ -51,4 +51,105 @@ ) ) ) + (func $load-off-2 "load-off-2" (param $0 i32) (result i32) + (i32.store offset=2 + (i32.add + (i32.const 1) + (i32.const 3) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const 3) + (i32.const 1) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (get_local $0) + (i32.const 5) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const 7) + (get_local $0) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -11) ;; do not fold this! + (get_local $0) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (get_local $0) + (i32.const -13) ;; do not fold this! + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -15) + (i32.const 17) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -21) + (i32.const 19) + ) + (get_local $0) + ) + (i32.store offset=2 + (i32.const 23) + (get_local $0) + ) + (i32.store offset=2 + (i32.const -25) + (get_local $0) + ) + (drop + (i32.load offset=2 + (i32.add + (i32.const 2) + (i32.const 4) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.add + (i32.const 4) + (i32.const 2) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.add + (get_local $0) + (i32.const 6) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.const 8) + ) + ) + (i32.load offset=2 + (i32.add + (i32.const 10) + (get_local $0) + ) + ) + ) ) |