Commit cfa6ce32 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Do not reduce Return nodes with multiple value inputs.

The existing implementation assumes that return nodes have exactly one
real value input. This assumption does not hold for WebAssembly. To
avoid incorrect behavior, this CL turns of the reduction of returns
with a value input count != 1.

R=titzer@chromium.org, mstarzinger@chromium.org

Review-Url: https://codereview.chromium.org/2638053002
Cr-Commit-Position: refs/heads/master@{#42425}
parent 5e31df23
......@@ -287,7 +287,6 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) {
Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
DCHECK_EQ(IrOpcode::kReturn, node->opcode());
Node* const value = node->InputAt(1);
Node* effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
bool changed = false;
......@@ -298,6 +297,11 @@ Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
NodeProperties::ReplaceEffectInput(node, effect);
changed = true;
}
// TODO(ahaas): Extend the reduction below to multiple return values.
if (ValueInputCountOfReturn(node->op()) != 1) {
return NoChange();
}
Node* const value = node->InputAt(1);
if (value->opcode() == IrOpcode::kPhi &&
NodeProperties::GetControlInput(value) == control &&
effect->opcode() == IrOpcode::kEffectPhi &&
......
......@@ -43,6 +43,13 @@ DeoptimizeReason DeoptimizeReasonOf(Operator const* const op) {
return OpParameter<DeoptimizeReason>(op);
}
int ValueInputCountOfReturn(Operator const* const op) {
DCHECK(op->opcode() == IrOpcode::kReturn);
// Return nodes have a hidden input at index 0 which we ignore in the value
// input count.
return op->ValueInputCount() - 1;
}
size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
......
......@@ -49,6 +49,9 @@ V8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const);
// Deoptimize reason for Deoptimize, DeoptimizeIf and DeoptimizeUnless.
DeoptimizeReason DeoptimizeReasonOf(Operator const* const);
// Helper function for return nodes, because returns have a hidden value input.
int ValueInputCountOfReturn(Operator const* const op);
// Deoptimize bailout kind.
enum class DeoptimizeKind : uint8_t { kEager, kSoft };
......
......@@ -374,6 +374,33 @@ TEST_F(CommonOperatorReducerTest, ReturnWithPhiAndEffectPhiAndMerge) {
IsReturn(vfalse, efalse, if_false)));
}
TEST_F(CommonOperatorReducerTest, MultiReturnWithPhiAndEffectPhiAndMerge) {
Node* cond = Parameter(2);
Node* branch = graph()->NewNode(common()->Branch(), cond, graph()->start());
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* etrue = graph()->start();
Node* vtrue1 = Parameter(0);
Node* vtrue2 = Parameter(1);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* efalse = graph()->start();
Node* vfalse1 = Parameter(1);
Node* vfalse2 = Parameter(0);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
Node* phi1 = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 2), vtrue1, vfalse1, merge);
Node* phi2 = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 2), vtrue2, vfalse2, merge);
Node* zero = graph()->NewNode(common()->Int32Constant(0));
Node* ret =
graph()->NewNode(common()->Return(2), zero, phi1, phi2, ephi, merge);
graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
StrictMock<MockAdvancedReducerEditor> editor;
Reduction const r = Reduce(&editor, ret);
// For now a return with multiple return values should not be reduced.
ASSERT_TRUE(!r.Changed());
}
// -----------------------------------------------------------------------------
// Select
......
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