From cf9386c7b9c287c91253c444fddd6e3249f764f0 Mon Sep 17 00:00:00 2001 From: Adam Klein Date: Tue, 12 Sep 2017 14:01:58 -0700 Subject: [PATCH] [ignition] Improve implementation of unary-minus For the HeapNumber case, use Float64Neg directly instead of a Float64Mul by -1.0. For the Smi case, logic is added to handle the boundary conditions (0 and Smi::kMinValue), and the general case is handled by a SmiSub from 0. Change-Id: I110916d9d1eb5d22d618fbf358d8d5b63cc71b3a Reviewed-on: https://chromium-review.googlesource.com/663945 Reviewed-by: Jakob Kummerow Reviewed-by: Ross McIlroy Commit-Queue: Adam Klein Cr-Commit-Position: refs/heads/master@{#47995} --- src/interpreter/interpreter-generator.cc | 33 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/interpreter/interpreter-generator.cc b/src/interpreter/interpreter-generator.cc index a0dab18162..3254a149ab 100644 --- a/src/interpreter/interpreter-generator.cc +++ b/src/interpreter/interpreter-generator.cc @@ -1254,22 +1254,33 @@ IGNITION_HANDLER(Negate, InterpreterAssembler) { BIND(&if_smi); { - // TODO(adamk): Use something more efficient than multiplication for this - // operation, being careful to maintain float behavior regarding -0. - Node* result = SmiMul(operand, SmiConstant(-1)); - var_type_feedback.Bind(SelectSmiConstant( - TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, - BinaryOperationFeedback::kNumber)); - var_result.Bind(result); + Label if_zero(this), if_min_smi(this); + // Return -0 if operand is 0. + GotoIf(SmiEqual(operand, SmiConstant(0)), &if_zero); + + // Special-case the minimum smi to avoid overflow. + GotoIf(SmiEqual(operand, SmiConstant(Smi::kMinValue)), &if_min_smi); + + // Else simply subtract operand from 0. + var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall)); + var_result.Bind(SmiSub(SmiConstant(0), operand)); + Goto(&end); + + BIND(&if_zero); + var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); + var_result.Bind(MinusZeroConstant()); + Goto(&end); + + BIND(&if_min_smi); + var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); + var_result.Bind(AllocateHeapNumberWithValue( + Float64Constant(-static_cast(Smi::kMinValue)))); Goto(&end); } BIND(&if_heapnumber); { - // TODO(adamk): Use something more efficient than multiplication for this - // operation, being careful to maintain float behavior regarding -0. - Node* result = - Float64Mul(LoadHeapNumberValue(operand), Float64Constant(-1.0)); + Node* result = Float64Neg(LoadHeapNumberValue(operand)); var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); var_result.Bind(AllocateHeapNumberWithValue(result)); Goto(&end);