From 8e9090bd6e3ad7ebde47db9d01701733bbfeb89e Mon Sep 17 00:00:00 2001 From: Aart Bik Date: Fri, 8 Sep 2017 16:46:50 -0700 Subject: Generalize range analysis. Rationale: obvious case x+-1 vs x-1 was missing Test: test-art-host Bug: 63631713 Change-Id: I0a97548a509239bee34a099b1ce9856bac311dba --- compiler/optimizing/induction_var_range.cc | 9 +++++++++ compiler/optimizing/induction_var_range_test.cc | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index 089340e715..191d3d128c 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -670,6 +670,15 @@ InductionVarRange::Value InductionVarRange::GetFetch(HInstruction* instruction, return AddValue(GetFetch(instruction->InputAt(0), trip, in_body, is_min), Value(static_cast(value))); } + } else if (instruction->IsSub()) { + // Incorporate suitable constants in the chased value. + if (IsInt64AndGet(instruction->InputAt(0), &value) && CanLongValueFitIntoInt(value)) { + return SubValue(Value(static_cast(value)), + GetFetch(instruction->InputAt(1), trip, in_body, !is_min)); + } else if (IsInt64AndGet(instruction->InputAt(1), &value) && CanLongValueFitIntoInt(value)) { + return SubValue(GetFetch(instruction->InputAt(0), trip, in_body, is_min), + Value(static_cast(value))); + } } else if (instruction->IsArrayLength()) { // Exploit length properties when chasing constants or chase into a new array declaration. if (chase_hint_ == nullptr) { diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index 2b82b336d7..9437014407 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -723,6 +723,29 @@ TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { ExpectEqual(Value(x_, 1, 0), GetMax(CreateFetch(array_length), nullptr)); } +TEST_F(InductionVarRangeTest, AddOrSubAndConstant) { + HInstruction* add = new (&allocator_) + HAdd(Primitive::kPrimInt, x_, graph_->GetIntConstant(-1)); + HInstruction* alt = new (&allocator_) + HAdd(Primitive::kPrimInt, graph_->GetIntConstant(-1), x_); + HInstruction* sub = new (&allocator_) + HSub(Primitive::kPrimInt, x_, graph_->GetIntConstant(1)); + HInstruction* rev = new (&allocator_) + HSub(Primitive::kPrimInt, graph_->GetIntConstant(1), x_); + entry_block_->AddInstruction(add); + entry_block_->AddInstruction(alt); + entry_block_->AddInstruction(sub); + entry_block_->AddInstruction(rev); + ExpectEqual(Value(x_, 1, -1), GetMin(CreateFetch(add), nullptr)); + ExpectEqual(Value(x_, 1, -1), GetMax(CreateFetch(add), nullptr)); + ExpectEqual(Value(x_, 1, -1), GetMin(CreateFetch(alt), nullptr)); + ExpectEqual(Value(x_, 1, -1), GetMax(CreateFetch(alt), nullptr)); + ExpectEqual(Value(x_, 1, -1), GetMin(CreateFetch(sub), nullptr)); + ExpectEqual(Value(x_, 1, -1), GetMax(CreateFetch(sub), nullptr)); + ExpectEqual(Value(x_, -1, 1), GetMin(CreateFetch(rev), nullptr)); + ExpectEqual(Value(x_, -1, 1), GetMax(CreateFetch(rev), nullptr)); +} + // // Tests on public methods. // -- cgit v1.2.3-59-g8ed1b