Skip to content

Commit

Permalink
deps: V8: backport f27ac28
Browse files Browse the repository at this point in the history
Original commit message:

    [turbofan] Pin pure unreachable values to effect chain (in rep selection)

    Currently, if we lower to a pure computation that is unreachable because
    of some runtime check, we just rename it with DeadValue. This is
    problematic if the pure computation gets later eliminated - that allows
    the DeadValue node float above the check that makes it dead. As we
    conservatively lower DeadValues to debug-break (i.e., crash), we
    might induce crash where we should not.

    With this CL, whenever we lower an impossible effectful node (i.e., with
    Type::None) to a pure node in simplified lowering, we insert an
    Unreachable node there (pinned to the effect chain) and mark the
    impossible node dead (and make it depend on the Unreachable node).

    Bug: chromium:910838
    Change-Id: I218991c79b9e283a9dd5beb4d3f0c4664be76cb2
    Reviewed-on: https://chromium-review.googlesource.com/c/1365274
    Reviewed-by: Benedikt Meurer <[email protected]>
    Commit-Queue: Jaroslav Sevcik <[email protected]>
    Cr-Commit-Position: refs/heads/master@{#58066}

Refs: v8/v8@f27ac28

PR-URL: #28061
Fixes: #27107
Reviewed-By: Gireesh Punathil <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
targos authored and BethGriggs committed Jun 6, 2019
1 parent 8f780e8 commit 609d2b9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 36 deletions.
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.53',
'v8_embedder_string': '-node.54',

# Enable disassembler for `--print-code` v8 options
'v8_enable_disassembler': 1,
Expand Down
86 changes: 52 additions & 34 deletions deps/v8/src/compiler/simplified-lowering.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,6 @@ void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
}
}

void ChangeToPureOp(Node* node, const Operator* new_op) {
DCHECK(new_op->HasProperty(Operator::kPure));
if (node->op()->EffectInputCount() > 0) {
DCHECK_LT(0, node->op()->ControlInputCount());
// Disconnect the node from effect and control chains.
Node* control = NodeProperties::GetControlInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
ReplaceEffectControlUses(node, effect, control);
node->TrimInputCount(new_op->ValueInputCount());
} else {
DCHECK_EQ(0, node->op()->ControlInputCount());
}
NodeProperties::ChangeOp(node, new_op);
}

#ifdef DEBUG
// Helpers for monotonicity checking.
class InputUseInfos {
Expand Down Expand Up @@ -750,6 +735,31 @@ class RepresentationSelector {
!GetUpperBound(node->InputAt(1)).Maybe(type);
}

void ChangeToPureOp(Node* node, const Operator* new_op) {
DCHECK(new_op->HasProperty(Operator::kPure));
if (node->op()->EffectInputCount() > 0) {
DCHECK_LT(0, node->op()->ControlInputCount());
Node* control = NodeProperties::GetControlInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
if (TypeOf(node).IsNone()) {
// If the node is unreachable, insert an Unreachable node and mark the
// value dead.
// TODO(jarin,tebbi) Find a way to unify/merge this insertion with
// InsertUnreachableIfNecessary.
Node* unreachable = effect = graph()->NewNode(
jsgraph_->common()->Unreachable(), effect, control);
new_op = jsgraph_->common()->DeadValue(GetInfo(node)->representation());
node->ReplaceInput(0, unreachable);
}
// Rewire the effect and control chains.
node->TrimInputCount(new_op->ValueInputCount());
ReplaceEffectControlUses(node, effect, control);
} else {
DCHECK_EQ(0, node->op()->ControlInputCount());
}
NodeProperties::ChangeOp(node, new_op);
}

// Converts input {index} of {node} according to given UseInfo {use},
// assuming the type of the input is {input_type}. If {input_type} is null,
// it takes the input from the input node {TypeOf(node->InputAt(index))}.
Expand Down Expand Up @@ -1052,6 +1062,15 @@ class RepresentationSelector {
}
}

void MaskShiftOperand(Node* node, Type rhs_type) {
if (!rhs_type.Is(type_cache_.kZeroToThirtyOne)) {
Node* const rhs = NodeProperties::GetValueInput(node, 1);
node->ReplaceInput(1,
graph()->NewNode(jsgraph_->machine()->Word32And(), rhs,
jsgraph_->Int32Constant(0x1F)));
}
}

static MachineSemantic DeoptValueSemanticOf(Type type) {
// We only need signedness to do deopt correctly.
if (type.Is(Type::Signed32())) {
Expand Down Expand Up @@ -1996,7 +2015,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
Expand All @@ -2007,7 +2027,8 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
Expand All @@ -2016,7 +2037,8 @@ class RepresentationSelector {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32());
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
Expand All @@ -2025,7 +2047,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
Expand All @@ -2036,7 +2059,8 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
Expand All @@ -2045,7 +2069,8 @@ class RepresentationSelector {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32());
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
Expand All @@ -2054,7 +2079,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
Expand Down Expand Up @@ -2083,14 +2109,16 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Unsigned32());
if (lower()) {
lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
MaskShiftOperand(node, rhs_type);
ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
Expand Down Expand Up @@ -3787,16 +3815,6 @@ void SimplifiedLowering::DoMin(Node* node, Operator const* op,
NodeProperties::ChangeOp(node, common()->Select(rep));
}

void SimplifiedLowering::DoShift(Node* node, Operator const* op,
Type rhs_type) {
if (!rhs_type.Is(type_cache_.kZeroToThirtyOne)) {
Node* const rhs = NodeProperties::GetValueInput(node, 1);
node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
jsgraph()->Int32Constant(0x1F)));
}
ChangeToPureOp(node, op);
}

void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
Node* const input = node->InputAt(0);
Node* const zero = jsgraph()->Int32Constant(0);
Expand Down
1 change: 0 additions & 1 deletion deps/v8/src/compiler/simplified-lowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class V8_EXPORT_PRIVATE SimplifiedLowering final {
Node* node, RepresentationSelector* selector);
void DoJSToNumberOrNumericTruncatesToWord32(Node* node,
RepresentationSelector* selector);
void DoShift(Node* node, Operator const* op, Type rhs_type);
void DoIntegral32ToBit(Node* node);
void DoOrderedNumberToBit(Node* node);
void DoNumberToBit(Node* node);
Expand Down
20 changes: 20 additions & 0 deletions deps/v8/test/mjsunit/compiler/regress-910838.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2018 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.

// Flags: --allow-natives-syntax

function f(b, s, x) {
if (!b) {
return (x ? b : s * undefined) ? 1 : 42;
}
}

function g(b, x) {
return f(b, 'abc', x);
}

f(false, 0, 0);
g(true, 0);
%OptimizeFunctionOnNextCall(g);
assertEquals(42, g(false, 0));

0 comments on commit 609d2b9

Please sign in to comment.