Chromium Code Reviews| Index: src/compiler/effect-control-linearizer.cc |
| diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc |
| index 1304e5410439f757d7e89e45e477aaaecf902036..99ac8883743e8b05dafb7a65d5f44e9b484cd043 100644 |
| --- a/src/compiler/effect-control-linearizer.cc |
| +++ b/src/compiler/effect-control-linearizer.cc |
| @@ -449,6 +449,12 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, |
| case IrOpcode::kCheckedInt32Sub: |
| state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); |
| break; |
| + case IrOpcode::kCheckedInt32Div: |
| + state = LowerCheckedInt32Div(node, frame_state, *effect, *control); |
| + break; |
| + case IrOpcode::kCheckedInt32Mod: |
| + state = LowerCheckedInt32Mod(node, frame_state, *effect, *control); |
| + break; |
| case IrOpcode::kCheckedUint32ToInt32: |
| state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
| break; |
| @@ -925,6 +931,164 @@ EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state, |
| } |
| EffectControlLinearizer::ValueEffectControl |
| +EffectControlLinearizer::LowerCheckedInt32Div(Node* node, Node* frame_state, |
| + Node* effect, Node* control) { |
| + Node* zero = jsgraph()->Int32Constant(0); |
| + Node* minusone = jsgraph()->Int32Constant(-1); |
| + Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min()); |
| + |
| + Node* lhs = node->InputAt(0); |
| + Node* rhs = node->InputAt(1); |
| + |
| + // Check if {rhs} is positive (and not zero). |
| + Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
| + Node* branch0 = |
| + graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| + |
| + Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| + Node* etrue0 = effect; |
| + Node* vtrue0; |
| + { |
| + // Fast case, no additional checking required. |
| + vtrue0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); |
| + } |
| + |
| + Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| + Node* efalse0 = effect; |
| + Node* vfalse0; |
| + { |
| + // Check if {rhs} is zero. |
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| + if_false0 = efalse0 = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, efalse0, if_false0); |
| + |
| + // Check if {lhs} is zero, as that would produce minus zero. |
| + check = graph()->NewNode(machine()->Word32Equal(), lhs, zero); |
| + if_false0 = efalse0 = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, efalse0, if_false0); |
| + |
| + // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have |
| + // to return -0. |
|
Jarin
2016/07/11 04:47:20
-0 --> -kMinInt?
Benedikt Meurer
2016/07/11 05:03:22
Done.
|
| + Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint); |
| + Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| + check1, if_false0); |
| + |
| + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| + Node* etrue1 = efalse0; |
| + { |
| + // Check if {rhs} is -1. |
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone); |
| + if_true1 = etrue1 = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, etrue1, if_true1); |
| + } |
| + |
| + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| + Node* efalse1 = efalse0; |
| + |
| + if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| + efalse0 = |
| + graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
| + |
| + // Perform the actual integer division. |
| + vfalse0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false0); |
| + } |
| + |
| + control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| + effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| + Node* value = |
| + graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, |
| + vfalse0, control); |
| + |
| + // Check if the remainder is non-zero. |
| + Node* check = |
| + graph()->NewNode(machine()->Word32Equal(), lhs, |
| + graph()->NewNode(machine()->Int32Mul(), rhs, value)); |
| + control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, |
| + frame_state, effect, control); |
| + |
| + // Make sure the lowered node does not appear in any use lists. |
| + node->TrimInputCount(0); |
| + |
| + return ValueEffectControl(value, effect, control); |
| +} |
| + |
| +EffectControlLinearizer::ValueEffectControl |
| +EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, |
| + Node* effect, Node* control) { |
| + Node* zero = jsgraph()->Int32Constant(0); |
| + Node* minusone = jsgraph()->Int32Constant(-1); |
| + Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min()); |
| + |
| + Node* lhs = node->InputAt(0); |
| + Node* rhs = node->InputAt(1); |
| + |
| + // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. |
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| + control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, effect, control); |
| + |
| + // Check if {lhs} is positive or zero. |
| + Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), zero, lhs); |
| + Node* branch0 = |
| + graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| + |
| + Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| + Node* etrue0 = effect; |
| + Node* vtrue0; |
| + { |
| + // Fast case, no additional checking required. |
| + vtrue0 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true0); |
| + } |
| + |
| + Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| + Node* efalse0 = effect; |
| + Node* vfalse0; |
| + { |
| + // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have |
| + // to return -0. |
| + Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint); |
| + Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| + check1, if_false0); |
| + |
| + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| + Node* etrue1 = efalse0; |
| + { |
| + // Check if {rhs} is -1. |
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone); |
| + if_true1 = etrue1 = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, etrue1, if_true1); |
| + } |
| + |
| + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| + Node* efalse1 = efalse0; |
| + |
| + if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| + efalse0 = |
| + graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
| + |
| + // Perform the actual integer modulos. |
| + vfalse0 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false0); |
| + |
| + // Check if the result is zero, because in that case we'd have to return |
| + // -0 here since we always take the signe of the {lhs} which is negative. |
| + Node* check = graph()->NewNode(machine()->Word32Equal(), vfalse0, zero); |
| + if_false0 = efalse0 = graph()->NewNode(common()->DeoptimizeIf(), check, |
| + frame_state, efalse0, if_false0); |
| + } |
| + |
| + control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| + effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| + Node* value = |
| + graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, |
| + vfalse0, control); |
| + |
| + // Make sure the lowered node does not appear in any use lists. |
| + node->TrimInputCount(0); |
| + |
| + return ValueEffectControl(value, effect, control); |
| +} |
| + |
| +EffectControlLinearizer::ValueEffectControl |
| EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
| Node* frame_state, |
| Node* effect, |