summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-11-02 15:41:55 -0700
committerGitHub <noreply@github.com>2018-11-02 15:41:55 -0700
commit49bb4290ce46b0e58f4817cbb46f3dada4f41409 (patch)
tree8b38dc5046a4846fa129f4b7fac0bd855d4a4124
parent33665b6b0c33e79049c832b9a60dcfe07fa54b59 (diff)
downloadbinaryen-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.h14
-rw-r--r--test/threads.asm.js3
-rw-r--r--test/threads.fromasm14
-rw-r--r--test/threads.fromasm.clamp14
-rw-r--r--test/threads.fromasm.clamp.no-opts14
-rw-r--r--test/threads.fromasm.imprecise14
-rw-r--r--test/threads.fromasm.imprecise.no-opts14
-rw-r--r--test/threads.fromasm.no-opts14
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)
+ )
+ )
)
)