diff options
Diffstat (limited to 'deps/v8/src/compiler/simplified-operator-reducer.cc')
-rw-r--r-- | deps/v8/src/compiler/simplified-operator-reducer.cc | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/deps/v8/src/compiler/simplified-operator-reducer.cc b/deps/v8/src/compiler/simplified-operator-reducer.cc index e2f87b674e..3a5b3c6ec6 100644 --- a/deps/v8/src/compiler/simplified-operator-reducer.cc +++ b/deps/v8/src/compiler/simplified-operator-reducer.cc @@ -220,6 +220,41 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { if (m.left().node() == m.right().node()) return ReplaceBoolean(true); break; } + case IrOpcode::kCheckedInt32Add: { + // (x + a) + b => x + (a + b) where a and b are constants and have the + // same sign. + Int32BinopMatcher m(node); + if (m.right().HasValue()) { + Node* checked_int32_add = m.left().node(); + if (checked_int32_add->opcode() == IrOpcode::kCheckedInt32Add) { + Int32BinopMatcher n(checked_int32_add); + if (n.right().HasValue() && + (n.right().Value() >= 0) == (m.right().Value() >= 0)) { + int32_t val; + bool overflow = base::bits::SignedAddOverflow32( + n.right().Value(), m.right().Value(), &val); + if (!overflow) { + bool has_no_other_value_uses = true; + for (Edge edge : checked_int32_add->use_edges()) { + if (!edge.from()->IsDead() && + !NodeProperties::IsEffectEdge(edge) && + edge.from() != node) { + has_no_other_value_uses = false; + break; + } + } + if (has_no_other_value_uses) { + node->ReplaceInput(0, n.left().node()); + node->ReplaceInput(1, jsgraph()->Int32Constant(val)); + RelaxEffectsAndControls(checked_int32_add); + return Changed(node); + } + } + } + } + } + break; + } default: break; } |