Commit 86282dcb authored by Georg Neis's avatar Georg Neis Committed by V8 LUCI CQ

[compiler] Avoid disconnected effectful operators in dead code

Bug: chromium:1228233
Change-Id: I7868cefd2123261f144d61e322a233ed460100ff
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3026717
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75732}
parent 8e81b819
......@@ -461,6 +461,7 @@ IfValueParameters const& IfValueParametersOf(const Operator* op) {
}
#define COMMON_CACHED_OP_LIST(V) \
V(Plug, Operator::kNoProperties, 0, 0, 0, 1, 0, 0) \
V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
V(Unreachable, Operator::kFoldable, 0, 1, 1, 1, 1, 0) \
V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
......
......@@ -469,6 +469,11 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
CommonOperatorBuilder(const CommonOperatorBuilder&) = delete;
CommonOperatorBuilder& operator=(const CommonOperatorBuilder&) = delete;
// A dummy value node temporarily used as input when the actual value doesn't
// matter. This operator is inserted only in SimplifiedLowering and is
// expected to not survive dead code elimination.
const Operator* Plug();
const Operator* Dead();
const Operator* DeadValue(MachineRepresentation rep);
const Operator* Unreachable();
......
......@@ -83,6 +83,7 @@
V(Unreachable) \
V(DeadValue) \
V(Dead) \
V(Plug) \
V(StaticAssert)
// Opcodes for JavaScript operators.
......
......@@ -939,9 +939,8 @@ class RepresentationSelector {
TRACE("disconnecting unused #%d:%s\n", node->id(),
node->op()->mnemonic());
DisconnectFromEffectAndControl(node);
node->NullAllInputs();
// We still keep the partial node connected to its uses, knowing that
// lowering these operators is going to eliminate the uses.
node->NullAllInputs(); // Node is now dead.
DeferReplacement(node, graph()->NewNode(common()->Plug()));
}
}
......@@ -3847,6 +3846,8 @@ class RepresentationSelector {
return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
case IrOpcode::kTypeGuard: {
if (truncation.IsUnused()) return VisitUnused<T>(node);
// We just get rid of the sigma here, choosing the best representation
// for the sigma's type.
Type type = TypeOf(node);
......
......@@ -1022,11 +1022,10 @@ Type Typer::Visitor::TypeTypeGuard(Node* node) {
Type Typer::Visitor::TypeFoldConstant(Node* node) { return Operand(node, 0); }
Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
Type Typer::Visitor::TypePlug(Node* node) { UNREACHABLE(); }
Type Typer::Visitor::TypeStaticAssert(Node* node) { UNREACHABLE(); }
// JS comparison operators.
......
......@@ -368,8 +368,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
case IrOpcode::kDeoptimizeIf:
case IrOpcode::kDeoptimizeUnless:
case IrOpcode::kDynamicCheckMapsWithDeoptUnless:
CheckNotTyped(node);
break;
case IrOpcode::kPlug:
case IrOpcode::kTrapIf:
case IrOpcode::kTrapUnless:
CheckNotTyped(node);
......
// Copyright 2021 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 --interrupt-budget=1024
const x = {a: 4.2};
function foo() {
const z = {a: [], b: NaN};
function bar(arg) {
const y = {a: 42};
y.a = 42;
arg.a = NaN;
for (let i = 0; i < 10; i++) {
[].toLocaleString();
}
}
const obj = {e: {}};
bar(obj);
bar(obj);
}
%PrepareFunctionForOptimization(foo);
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
foo();
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