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..af52b6d626b5c32c17aca8326080f438a8c7e077 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 -kMinInt, which is not representable. |
+ 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, |