Commit 0ddddcb8 authored by ahaas's avatar ahaas Committed by Commit bot

[asmjs] Do constant folding for I32Asmjs(Div|Rem)S to avoid checks of constant divisors

This change makes the embenchen/copy benchmark a factor of 2 faster and
brings back the performance loss through graph trimming.

R=titzer@chromium.org
CC=bradnelson@chromium.org

Review-Url: https://codereview.chromium.org/2453343002
Cr-Commit-Position: refs/heads/master@{#40628}
parent 8ba4af44
......@@ -1867,6 +1867,18 @@ Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right,
Node* WasmGraphBuilder::BuildI32AsmjsDivS(Node* left, Node* right) {
MachineOperatorBuilder* m = jsgraph()->machine();
Int32Matcher mr(right);
if (mr.HasValue()) {
if (mr.Value() == 0) {
return jsgraph()->Int32Constant(0);
} else if (mr.Value() == -1) {
// The result is the negation of the left input.
return graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left);
}
return graph()->NewNode(m->Int32Div(), left, right, *control_);
}
// asm.js semantics return 0 on divide or mod by zero.
if (m->Int32DivIsSafe()) {
// The hardware instruction does the right thing (e.g. arm).
......@@ -1896,6 +1908,17 @@ Node* WasmGraphBuilder::BuildI32AsmjsDivS(Node* left, Node* right) {
Node* WasmGraphBuilder::BuildI32AsmjsRemS(Node* left, Node* right) {
MachineOperatorBuilder* m = jsgraph()->machine();
Int32Matcher mr(right);
if (mr.HasValue()) {
if (mr.Value() == 0) {
return jsgraph()->Int32Constant(0);
} else if (mr.Value() == -1) {
return jsgraph()->Int32Constant(0);
}
return graph()->NewNode(m->Int32Mod(), left, right, *control_);
}
// asm.js semantics return 0 on divide or mod by zero.
// Explicit check for x % 0.
Diamond z(
......
......@@ -494,6 +494,14 @@ class LocalDeclEncoder {
#define WASM_I32_POPCNT(x) x, kExprI32Popcnt
#define WASM_I32_EQZ(x) x, kExprI32Eqz
//------------------------------------------------------------------------------
// Asmjs Int32 operations
//------------------------------------------------------------------------------
#define WASM_I32_ASMJS_DIVS(x, y) x, y, kExprI32AsmjsDivS
#define WASM_I32_ASMJS_REMS(x, y) x, y, kExprI32AsmjsRemS
#define WASM_I32_ASMJS_DIVU(x, y) x, y, kExprI32AsmjsDivU
#define WASM_I32_ASMJS_REMU(x, y) x, y, kExprI32AsmjsRemU
//------------------------------------------------------------------------------
// Int64 operations
//------------------------------------------------------------------------------
......
......@@ -448,6 +448,42 @@ WASM_EXEC_TEST(Int32DivS_byzero_const) {
}
}
WASM_EXEC_TEST(Int32AsmjsDivS_byzero_const) {
for (int8_t denom = -2; denom < 8; ++denom) {
TestingModule module(execution_mode);
module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_I32_ASMJS_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
FOR_INT32_INPUTS(i) {
if (denom == 0) {
CHECK_EQ(0, r.Call(*i));
} else if (denom == -1 && *i == std::numeric_limits<int32_t>::min()) {
CHECK_EQ(std::numeric_limits<int32_t>::min(), r.Call(*i));
} else {
CHECK_EQ(*i / denom, r.Call(*i));
}
}
}
}
WASM_EXEC_TEST(Int32AsmjsRemS_byzero_const) {
for (int8_t denom = -2; denom < 8; ++denom) {
TestingModule module(execution_mode);
module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_I32_ASMJS_REMS(WASM_GET_LOCAL(0), WASM_I8(denom)));
FOR_INT32_INPUTS(i) {
if (denom == 0) {
CHECK_EQ(0, r.Call(*i));
} else if (denom == -1 && *i == std::numeric_limits<int32_t>::min()) {
CHECK_EQ(0, r.Call(*i));
} else {
CHECK_EQ(*i % denom, r.Call(*i));
}
}
}
}
WASM_EXEC_TEST(Int32DivU_byzero_const) {
for (uint32_t denom = 0xfffffffe; denom < 8; ++denom) {
WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32());
......
......@@ -95,6 +95,8 @@ class TestingModule : public ModuleEnv {
if (interpreter_) delete interpreter_;
}
void ChangeOriginToAsmjs() { origin = kAsmJsOrigin; }
byte* AddMemory(uint32_t size) {
CHECK_NULL(instance->mem_start);
CHECK_EQ(0, instance->mem_size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment