Commit 7e805faa authored by bradnelson's avatar bradnelson Committed by Commit bot

Allow intish and floatish to be coerced by heap assignment.

When assigning to an integer view of the heap an intish
value does not need to be collapsed with |0.
Similarly a floatish value does not need to be collapsed with
fround when assigned to a float view of the heap.
i32[0] = i32_1 + i32_2;  // ok
f32[0] = f32_1 + f32_2;  // ok

However, floatish values cannot be safely assigned to double
arrays.
f64[0] = f32_1 + f32_2;  // not ok

BUG= https://code.google.com/p/v8/issues/detail?id=4203
TEST=mjsunit/asm-wasm,test-asm-validator
R=aseemgarg@chromium.org,titzer@chromium.org
LOG=N

Review URL: https://codereview.chromium.org/1722473002

Cr-Commit-Position: refs/heads/master@{#34206}
parent 360c761d
......@@ -683,19 +683,23 @@ void AsmTyper::VisitAssignment(Assignment* expr) {
RECURSE(VisitWithExpectation(
expr->value(), type, "assignment value expected to match surrounding"));
Type* target_type = StorageType(computed_type_);
if (intish_ != 0) {
FAIL(expr, "intish or floatish assignment");
}
if (expr->target()->IsVariableProxy()) {
if (intish_ != 0) {
FAIL(expr, "intish or floatish assignment");
}
expected_type_ = target_type;
VisitVariableProxy(expr->target()->AsVariableProxy(), true);
} else if (expr->target()->IsProperty()) {
int value_intish = intish_;
Property* property = expr->target()->AsProperty();
RECURSE(VisitWithExpectation(property->obj(), Type::Any(),
"bad propety object"));
if (!computed_type_->IsArray()) {
FAIL(property->obj(), "array expected");
}
if (value_intish != 0 && computed_type_->Is(cache_.kFloat64Array)) {
FAIL(expr, "floatish assignment to double array");
}
VisitHeapAccess(property, true, target_type);
}
IntersectResult(expr, target_type);
......
......@@ -1434,6 +1434,71 @@ TEST(StoreFloat) {
CHECK_FUNC_TYPES_END
}
TEST(StoreIntish) {
CHECK_FUNC_TYPES_BEGIN(
"function bar() { var x = 1; var y = 1; i32[0] = x + y; }\n"
"function foo() { bar(); }") {
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
CHECK_VAR(x, Bounds(cache.kAsmInt));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
}
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
CHECK_VAR(y, Bounds(cache.kAsmInt));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
}
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
CHECK_EXPR(Property, Bounds::Unbounded()) {
CHECK_VAR(i32, Bounds(cache.kInt32Array));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
}
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
CHECK_VAR(x, Bounds(cache.kAsmInt));
CHECK_VAR(y, Bounds(cache.kAsmInt));
}
}
}
CHECK_SKIP();
}
CHECK_FUNC_TYPES_END
}
TEST(StoreFloatish) {
CHECK_FUNC_TYPES_BEGIN(
"function bar() { "
"var x = fround(1.0); "
"var y = fround(1.0); f32[0] = x + y; }\n"
"function foo() { bar(); }") {
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
CHECK_VAR(x, Bounds(cache.kAsmFloat));
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
CHECK_VAR(fround, FUNC_N2F_TYPE);
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
}
}
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
CHECK_VAR(y, Bounds(cache.kAsmFloat));
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
CHECK_VAR(fround, FUNC_N2F_TYPE);
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
}
}
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
CHECK_EXPR(Property, Bounds::Unbounded()) {
CHECK_VAR(f32, Bounds(cache.kFloat32Array));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
}
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
CHECK_VAR(x, Bounds(cache.kAsmFloat));
CHECK_VAR(y, Bounds(cache.kAsmFloat));
}
}
}
CHECK_SKIP();
}
CHECK_FUNC_TYPES_END
}
TEST(Load1Constant) {
CHECK_FUNC_TYPES_BEGIN(
......@@ -1712,9 +1777,9 @@ TEST(MismatchedReturnTypeExpression) {
TEST(AssignToFloatishToF64) {
CHECK_FUNC_ERROR(
"function bar() { var v = fround(1.0); f32[0] = v + fround(1.0); }\n"
"function bar() { var v = fround(1.0); f64[0] = v + fround(1.0); }\n"
"function foo() { bar(); }",
"asm: line 39: intish or floatish assignment\n");
"asm: line 39: floatish assignment to double array\n");
}
......
......@@ -1313,3 +1313,40 @@ TestForeignVariables();
var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
assertEquals(1, m.func());
})();
(function TestIntishAssignment() {
function Module(stdlib, foreign, heap) {
"use asm";
var HEAP32 = new stdlib.Int32Array(heap);
function func() {
var a = 1;
var b = 2;
HEAP32[0] = a + b;
return HEAP32[0] | 0;
}
return {func: func};
}
var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
assertEquals(3, m.func());
})();
(function TestFloatishAssignment() {
function Module(stdlib, foreign, heap) {
"use asm";
var HEAPF32 = new stdlib.Float32Array(heap);
var fround = stdlib.Math.fround;
function func() {
var a = fround(1.0);
var b = fround(2.0);
HEAPF32[0] = a + b;
return +HEAPF32[0];
}
return {func: func};
}
var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
assertEquals(3, m.func());
}) // TODO(bradnelson): Enable when Math.fround implementation lands.
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