diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-11-02 15:41:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-02 15:41:55 -0700 |
commit | 49bb4290ce46b0e58f4817cbb46f3dada4f41409 (patch) | |
tree | 8b38dc5046a4846fa129f4b7fac0bd855d4a4124 | |
parent | 33665b6b0c33e79049c832b9a60dcfe07fa54b59 (diff) | |
download | binaryen-49bb4290ce46b0e58f4817cbb46f3dada4f41409.tar.gz binaryen-49bb4290ce46b0e58f4817cbb46f3dada4f41409.tar.bz2 binaryen-49bb4290ce46b0e58f4817cbb46f3dada4f41409.zip |
Fix asm2wasm handling of HEAP8[x >> 2] (#1720)
fixes kripken/emscripten#1718
The way fastcomp emits compareExchange is a little odd, we just need to ignore the shift.
-rw-r--r-- | src/asm2wasm.h | 14 | ||||
-rw-r--r-- | test/threads.asm.js | 3 | ||||
-rw-r--r-- | test/threads.fromasm | 14 | ||||
-rw-r--r-- | test/threads.fromasm.clamp | 14 | ||||
-rw-r--r-- | test/threads.fromasm.clamp.no-opts | 14 | ||||
-rw-r--r-- | test/threads.fromasm.imprecise | 14 | ||||
-rw-r--r-- | test/threads.fromasm.imprecise.no-opts | 14 | ||||
-rw-r--r-- | test/threads.fromasm.no-opts | 14 |
8 files changed, 91 insertions, 10 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index de50eb33d..c0508f8ae 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1615,6 +1615,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { // processors std::function<Expression* (Ref, unsigned)> processStatements; std::function<Expression* (Ref, unsigned)> processUnshifted; + std::function<Expression* (Ref, unsigned)> processIgnoringShift; std::function<Expression* (Ref)> process = [&](Ref ast) -> Expression* { AstStackHelper astStackHelper(ast); // TODO: only create one when we need it? @@ -2014,7 +2015,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } else if (name == Atomics_exchange) { return builder.makeAtomicRMW(AtomicRMWOp::Xchg, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); } else if (name == Atomics_compareExchange) { - return builder.makeAtomicCmpxchg(view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), process(ast[2][3]), asmToWasmType(view.type)); + // cmpxchg is odd in fastcomp output - we must ignore the shift, a cmpxchg of a i8 will look like compareExchange(HEAP8, ptr >> 2) + return builder.makeAtomicCmpxchg(view.bytes, 0, processIgnoringShift(ast[2][1], view.bytes), process(ast[2][2]), process(ast[2][3]), asmToWasmType(view.type)); } else if (name == Atomics_add) { return builder.makeAtomicRMW(AtomicRMWOp::Add, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); } else if (name == Atomics_sub) { @@ -2742,6 +2744,16 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { return (Expression*)nullptr; // avoid warning }; + processIgnoringShift = [&](Ref ptr, unsigned bytes) { + // If there is a shift here, no matter the size look through it. + if ((ptr->isArray(BINARY) && ptr[1] == RSHIFT && ptr[3]->isNumber()) || + (bytes == 1 && ptr->isArray(BINARY) && ptr[1] == OR && ptr[3]->isNumber() && ptr[3]->getInteger() == 0)) { + return process(ptr[2]); + } + // Otherwise do the same as processUnshifted. + return processUnshifted(ptr, bytes); + }; + processStatements = [&](Ref ast, unsigned from) -> Expression* { unsigned size = ast->size() - from; if (size == 0) return allocator.alloc<Nop>(); diff --git a/test/threads.asm.js b/test/threads.asm.js index 1253e8c42..bedeb7a37 100644 --- a/test/threads.asm.js +++ b/test/threads.asm.js @@ -137,6 +137,9 @@ Module["asm"] = (function(global, env, buffer) { $temp = (Atomics_xor(HEAPU32, 1024, 0)|0); $temp = (Atomics_xor(HEAP16, 1024, 0)|0); $temp = (Atomics_xor(HEAPU8, 1024, 0)|0); + // corner cases + $temp = (Atomics_compareExchange(HEAP8, $temp | 0, 1, 2)|0); + $temp = (Atomics_compareExchange(HEAP8, $temp >> 2, 1, 2)|0); } return { test: test }; diff --git a/test/threads.fromasm b/test/threads.fromasm index 47112c8f5..25e26135c 100644 --- a/test/threads.fromasm +++ b/test/threads.fromasm @@ -56,9 +56,17 @@ ) ) (drop - (i32.atomic.rmw8_u.xor - (i32.const 1024) - (i32.const 0) + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + (i32.const 2) ) ) ) diff --git a/test/threads.fromasm.clamp b/test/threads.fromasm.clamp index 47112c8f5..25e26135c 100644 --- a/test/threads.fromasm.clamp +++ b/test/threads.fromasm.clamp @@ -56,9 +56,17 @@ ) ) (drop - (i32.atomic.rmw8_u.xor - (i32.const 1024) - (i32.const 0) + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + (i32.const 2) ) ) ) diff --git a/test/threads.fromasm.clamp.no-opts b/test/threads.fromasm.clamp.no-opts index 78538c9c9..d15b56541 100644 --- a/test/threads.fromasm.clamp.no-opts +++ b/test/threads.fromasm.clamp.no-opts @@ -118,5 +118,19 @@ (i32.const 0) ) ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) ) ) diff --git a/test/threads.fromasm.imprecise b/test/threads.fromasm.imprecise index 66c558ffe..eec93d750 100644 --- a/test/threads.fromasm.imprecise +++ b/test/threads.fromasm.imprecise @@ -54,9 +54,17 @@ ) ) (drop - (i32.atomic.rmw8_u.xor - (i32.const 1024) - (i32.const 0) + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.cmpxchg + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 1) + (i32.const 2) ) ) ) diff --git a/test/threads.fromasm.imprecise.no-opts b/test/threads.fromasm.imprecise.no-opts index 78538c9c9..d15b56541 100644 --- a/test/threads.fromasm.imprecise.no-opts +++ b/test/threads.fromasm.imprecise.no-opts @@ -118,5 +118,19 @@ (i32.const 0) ) ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) ) ) diff --git a/test/threads.fromasm.no-opts b/test/threads.fromasm.no-opts index 78538c9c9..d15b56541 100644 --- a/test/threads.fromasm.no-opts +++ b/test/threads.fromasm.no-opts @@ -118,5 +118,19 @@ (i32.const 0) ) ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) ) ) |