Commit 21e46b05 authored by bradnelson's avatar bradnelson Committed by Commit bot

[wasm] [asm.js] Fix various asm.js issues.

Several of the asm.js tests were disabled and wrong (mismatched number of args
on the stdlib functions).

Fixing issue around negation and float + doubles.

Renaming function for IsNegate to IsInvert (to reflect what it actually does).

Added tests for negate and invert.

BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
R=aseemgarg@chromium.org,jpp@chromium.org

Review-Url: https://codereview.chromium.org/2377903002
Cr-Commit-Position: refs/heads/master@{#39836}
parent d67aafa6
...@@ -1513,7 +1513,7 @@ AsmType* AsmTyper::ValidateCompareOperation(CompareOperation* cmp) { ...@@ -1513,7 +1513,7 @@ AsmType* AsmTyper::ValidateCompareOperation(CompareOperation* cmp) {
} }
namespace { namespace {
bool IsNegate(BinaryOperation* binop) { bool IsInvert(BinaryOperation* binop) {
if (binop->op() != Token::BIT_XOR) { if (binop->op() != Token::BIT_XOR) {
return false; return false;
} }
...@@ -1528,7 +1528,7 @@ bool IsNegate(BinaryOperation* binop) { ...@@ -1528,7 +1528,7 @@ bool IsNegate(BinaryOperation* binop) {
} }
bool IsUnaryMinus(BinaryOperation* binop) { bool IsUnaryMinus(BinaryOperation* binop) {
// *VIOLATION* The parser replaces uses of +x with x*1.0. // *VIOLATION* The parser replaces uses of -x with x*-1.
if (binop->op() != Token::MUL) { if (binop->op() != Token::MUL) {
return false; return false;
} }
...@@ -1574,7 +1574,7 @@ AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) { ...@@ -1574,7 +1574,7 @@ AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) {
} }
if (IsUnaryMinus(expr)) { if (IsUnaryMinus(expr)) {
// *VIOLATION* the parser converts -x to x * -1.0. // *VIOLATION* the parser converts -x to x * -1.
AsmType* left_type; AsmType* left_type;
RECURSE(left_type = ValidateExpression(expr->left())); RECURSE(left_type = ValidateExpression(expr->left()));
SetTypeOf(expr->right(), left_type); SetTypeOf(expr->right(), left_type);
...@@ -1599,11 +1599,11 @@ AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) { ...@@ -1599,11 +1599,11 @@ AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) {
case Token::BIT_AND: case Token::BIT_AND:
return ValidateBitwiseANDExpression(expr); return ValidateBitwiseANDExpression(expr);
case Token::BIT_XOR: case Token::BIT_XOR:
if (IsNegate(expr)) { if (IsInvert(expr)) {
auto* left = expr->left(); auto* left = expr->left();
auto* left_as_binop = left->AsBinaryOperation(); auto* left_as_binop = left->AsBinaryOperation();
if (left_as_binop != nullptr && IsNegate(left_as_binop)) { if (left_as_binop != nullptr && IsInvert(left_as_binop)) {
// This is the special ~~ operator. // This is the special ~~ operator.
AsmType* left_type; AsmType* left_type;
RECURSE(left_type = ValidateExpression(left_as_binop->left())); RECURSE(left_type = ValidateExpression(left_as_binop->left()));
......
...@@ -621,13 +621,31 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { ...@@ -621,13 +621,31 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
} else if (expr->raw_value()->IsFalse()) { } else if (expr->raw_value()->IsFalse()) {
byte code[] = {WASM_I32V(0)}; byte code[] = {WASM_I32V(0)};
current_function_builder_->EmitCode(code, sizeof(code)); current_function_builder_->EmitCode(code, sizeof(code));
} else if (expr->raw_value()->IsNumber()) {
// This can happen when -x becomes x * -1 (due to the parser).
int32_t i = 0;
if (!value->ToInt32(&i) || i != -1) {
UNREACHABLE();
}
byte code[] = {WASM_I32V(i)};
current_function_builder_->EmitCode(code, sizeof(code));
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
} else if (type->IsA(AsmType::Double())) { } else if (type->IsA(AsmType::Double())) {
// TODO(bradnelson): Pattern match the case where negation occurs and
// emit f64.neg instead.
double val = expr->raw_value()->AsNumber(); double val = expr->raw_value()->AsNumber();
byte code[] = {WASM_F64(val)}; byte code[] = {WASM_F64(val)};
current_function_builder_->EmitCode(code, sizeof(code)); current_function_builder_->EmitCode(code, sizeof(code));
} else if (type->IsA(AsmType::Float())) {
// This can happen when -fround(x) becomes fround(x) * 1.0[float]
// (due to the parser).
// TODO(bradnelson): Pattern match this and emit f32.neg instead.
double val = expr->raw_value()->AsNumber();
DCHECK_EQ(-1.0, val);
byte code[] = {WASM_F32(val)};
current_function_builder_->EmitCode(code, sizeof(code));
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -159,6 +159,11 @@ function f32_gteq(a, b) { ...@@ -159,6 +159,11 @@ function f32_gteq(a, b) {
return 0; return 0;
} }
function f32_neg(a) {
a = fround(a);
return fround(-a);
}
var inputs = [ var inputs = [
0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
...@@ -211,6 +216,7 @@ var funcs = [ ...@@ -211,6 +216,7 @@ var funcs = [
f32_lteq, f32_lteq,
f32_gt, f32_gt,
f32_gteq, f32_gteq,
f32_neg,
]; ];
(function () { (function () {
......
...@@ -205,21 +205,25 @@ function f64_tan(a) { ...@@ -205,21 +205,25 @@ function f64_tan(a) {
return +Math_tan(+a); return +Math_tan(+a);
} }
function f64_exp(a, b) { function f64_exp(a) {
a = +a; a = +a;
b = +b; return +Math_exp(+a);
return +Math_exp(+a, +b); }
function f64_log(a) {
a = +a;
return +Math_log(+a);
} }
function f64_log(a, b) { function f64_atan2(a, b) {
a = +a; a = +a;
b = +b; b = +b;
return +Math_log(+a, +b); return +Math_atan2(+a, +b);
} }
function f64_atan2(a) { function f64_neg(a) {
a = +a; a = +a;
return +Math_atan2(+a); return +(-a);
} }
...@@ -272,17 +276,18 @@ var funcs = [ ...@@ -272,17 +276,18 @@ var funcs = [
f64_floor, f64_floor,
// TODO(bradnelson) f64_sqrt, // TODO(bradnelson) f64_sqrt,
f64_abs, f64_abs,
f64_neg,
// TODO(bradnelson) f64_min is wrong for -0 // TODO(bradnelson) f64_min is wrong for -0
// TODO(bradnelson) f64_max is wrong for -0 // TODO(bradnelson) f64_max is wrong for -0
// TODO(bradnelson) f64_acos, f64_acos,
// TODO(bradnelson) f64_asin, f64_asin,
// TODO(bradnelson) f64_atan, f64_atan,
// TODO(bradnelson) f64_cos, f64_cos,
// TODO(bradnelson) f64_sin, f64_sin,
// TODO(bradnelson) f64_tan, f64_tan,
// TODO(bradnelson) f64_exp, f64_exp,
// TODO(bradnelson) f64_log, f64_log,
// TODO(bradnelson) f64_atan2, f64_atan2,
]; ];
(function () { (function () {
......
...@@ -180,6 +180,16 @@ function i32_abs(a) { ...@@ -180,6 +180,16 @@ function i32_abs(a) {
return Math_abs(a | 0) | 0; return Math_abs(a | 0) | 0;
} }
function i32_neg(a) {
a = a | 0;
return (-a) | 0;
}
function i32_invert(a) {
a = a | 0;
return (~a) | 0;
}
var inputs = [ var inputs = [
0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
10, 20, 30, 31, 32, 33, 100, 2000, 10, 20, 30, 31, 32, 33, 100, 2000,
...@@ -226,7 +236,9 @@ var funcs = [ ...@@ -226,7 +236,9 @@ var funcs = [
i32_gteq, i32_gteq,
i32_min, i32_min,
i32_max, i32_max,
i32_abs i32_abs,
i32_neg,
i32_invert,
]; ];
(function () { (function () {
......
...@@ -157,6 +157,16 @@ function u32_gteq(a, b) { ...@@ -157,6 +157,16 @@ function u32_gteq(a, b) {
return 0; return 0;
} }
function u32_neg(a) {
a = a | 0;
return (-a) | 0;
}
function u32_invert(a) {
a = a | 0;
return (~a) | 0;
}
var inputs = [ var inputs = [
0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
...@@ -202,6 +212,8 @@ var funcs = [ ...@@ -202,6 +212,8 @@ var funcs = [
u32_lteq, u32_lteq,
u32_gt, u32_gt,
u32_gteq, u32_gteq,
u32_neg,
u32_invert,
// TODO(titzer): u32_min // TODO(titzer): u32_min
// TODO(titzer): u32_max // TODO(titzer): u32_max
// TODO(titzer): u32_abs // TODO(titzer): u32_abs
......
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