Commit 14409abc authored by Benedikt Meurer's avatar Benedikt Meurer

[turbofan] Quickfix for invalid number truncation of typed array loads.

TEST=mjsunit/compiler/regress-int32array-outofbounds-nan
R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#25793}
parent 71bb00e2
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/compiler/simplified-lowering.h" #include "src/compiler/simplified-lowering.h"
#include <limits>
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
...@@ -764,8 +766,20 @@ class RepresentationSelector { ...@@ -764,8 +766,20 @@ class RepresentationSelector {
ProcessRemainingInputs(node, 3); ProcessRemainingInputs(node, 3);
// Tagged overrides everything if we have to do a typed array bounds // Tagged overrides everything if we have to do a typed array bounds
// check, because we may need to return undefined then. // check, because we may need to return undefined then.
MachineType output_type = MachineType output_type;
(use & kRepTagged) ? kMachAnyTagged : access.machine_type(); if (use & kRepTagged) {
output_type = kMachAnyTagged;
} else if (use & kRepFloat64) {
if (access.machine_type() & kRepFloat32) {
output_type = access.machine_type();
} else {
output_type = kMachFloat64;
}
} else if (use & kRepFloat32) {
output_type = kMachFloat32;
} else {
output_type = access.machine_type();
}
SetOutput(node, output_type); SetOutput(node, output_type);
if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); if (lower()) lowering->DoLoadBuffer(node, output_type, changer_);
break; break;
...@@ -1130,7 +1144,7 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, ...@@ -1130,7 +1144,7 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
DCHECK_NE(kMachNone, RepresentationOf(output_type)); DCHECK_NE(kMachNone, RepresentationOf(output_type));
MachineType const type = BufferAccessOf(node->op()).machine_type(); MachineType const type = BufferAccessOf(node->op()).machine_type();
if (output_type & kRepTagged) { if (output_type != type) {
Node* const buffer = node->InputAt(0); Node* const buffer = node->InputAt(0);
Node* const offset = node->InputAt(1); Node* const offset = node->InputAt(1);
Node* const length = node->InputAt(2); Node* const length = node->InputAt(2);
...@@ -1144,11 +1158,22 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, ...@@ -1144,11 +1158,22 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
Node* if_true = graph()->NewNode(common()->IfTrue(), branch); Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* etrue = graph()->NewNode(machine()->Load(type), buffer, offset, Node* etrue = graph()->NewNode(machine()->Load(type), buffer, offset,
effect, if_true); effect, if_true);
Node* vtrue = changer->GetTaggedRepresentationFor(etrue, type); Node* vtrue = changer->GetRepresentationFor(etrue, type, output_type);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* vfalse = jsgraph()->UndefinedConstant();
Node* efalse = effect; Node* efalse = effect;
Node* vfalse;
if (output_type & kRepTagged) {
vfalse = jsgraph()->UndefinedConstant();
} else if (output_type & kRepFloat64) {
vfalse =
jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
} else if (output_type & kRepFloat32) {
vfalse =
jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
} else {
vfalse = jsgraph()->Int32Constant(0);
}
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
...@@ -1157,7 +1182,7 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, ...@@ -1157,7 +1182,7 @@ void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
NodeProperties::ReplaceWithValue(node, node, ephi); NodeProperties::ReplaceWithValue(node, node, ephi);
// Turn the {node} into a Phi. // Turn the {node} into a Phi.
node->set_op(common()->Phi(kMachAnyTagged, 2)); node->set_op(common()->Phi(output_type, 2));
node->ReplaceInput(0, vtrue); node->ReplaceInput(0, vtrue);
node->ReplaceInput(1, vfalse); node->ReplaceInput(1, vfalse);
node->ReplaceInput(2, merge); node->ReplaceInput(2, merge);
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function Module(stdlib, foreign, heap) {
"use asm";
var MEM32 = new stdlib.Int32Array(heap);
function foo(i) {
i = i|0;
return +MEM32[i >> 2];
}
return {foo: foo};
}
var foo = Module(this, {}, new ArrayBuffer(4)).foo;
assertEquals(NaN, foo(-4));
assertEquals(NaN, foo(4));
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