diff options
author | 2017-04-07 11:33:37 -0700 | |
---|---|---|
committer | 2017-04-07 23:03:42 +0000 | |
commit | fa76296bc624bc2c879167c260ad6925238efb3d (patch) | |
tree | 045c4488fec66806982a62aa4cfd7d3a2183e958 /compiler/optimizing | |
parent | 6f005931d0a0db65128db803df38d59d205dd218 (diff) |
Fixed missing context while detecting unit strides.
With regression test (found by fuzz testing).
Bug: 37033123
Test: test-art-target
Change-Id: Id738b2a3a353985c3d0bf3beeb581a31f1fcbc3f
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/induction_var_range.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range.h | 10 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_range_test.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 4 |
4 files changed, 16 insertions, 11 deletions
diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index d6513c8e34..1c8674d522 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -383,12 +383,13 @@ bool InductionVarRange::IsFinite(HLoopInformation* loop, /*out*/ int64_t* tc) co return false; } -bool InductionVarRange::IsUnitStride(HInstruction* instruction, +bool InductionVarRange::IsUnitStride(HInstruction* context, + HInstruction* instruction, /*out*/ HInstruction** offset) const { HLoopInformation* loop = nullptr; HInductionVarAnalysis::InductionInfo* info = nullptr; HInductionVarAnalysis::InductionInfo* trip = nullptr; - if (HasInductionInfo(instruction, instruction, &loop, &info, &trip)) { + if (HasInductionInfo(context, instruction, &loop, &info, &trip)) { if (info->induction_class == HInductionVarAnalysis::kLinear && info->op_b->operation == HInductionVarAnalysis::kFetch && !HInductionVarAnalysis::IsNarrowingLinear(info)) { diff --git a/compiler/optimizing/induction_var_range.h b/compiler/optimizing/induction_var_range.h index 0858d73982..a8ee829d08 100644 --- a/compiler/optimizing/induction_var_range.h +++ b/compiler/optimizing/induction_var_range.h @@ -156,10 +156,14 @@ class InductionVarRange { bool IsFinite(HLoopInformation* loop, /*out*/ int64_t* tc) const; /** - * Checks if instruction is a unit stride induction inside the closest enveloping loop. - * Returns invariant offset on success. + * Checks if the given instruction is a unit stride induction inside the closest enveloping + * loop of the context that is defined by the first parameter (e.g. pass an array reference + * as context and the index as instruction to make sure the stride is tested against the + * loop that envelops the reference the closest). Returns invariant offset on success. */ - bool IsUnitStride(HInstruction* instruction, /*out*/ HInstruction** offset) const; + bool IsUnitStride(HInstruction* context, + HInstruction* instruction, + /*out*/ HInstruction** offset) const; /** * Generates the trip count expression for the given loop. Code is generated in given block diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index fcdf8eb7dc..d01d3146fc 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -770,7 +770,7 @@ TEST_F(InductionVarRangeTest, ConstantTripCountUp) { EXPECT_TRUE(range_.IsFinite(loop_header_->GetLoopInformation(), &tc)); EXPECT_EQ(1000, tc); HInstruction* offset = nullptr; - EXPECT_TRUE(range_.IsUnitStride(phi, &offset)); + EXPECT_TRUE(range_.IsUnitStride(phi, phi, &offset)); EXPECT_TRUE(offset == nullptr); HInstruction* tce = range_.GenerateTripCount( loop_header_->GetLoopInformation(), graph_, loop_preheader_); @@ -826,7 +826,7 @@ TEST_F(InductionVarRangeTest, ConstantTripCountDown) { EXPECT_TRUE(range_.IsFinite(loop_header_->GetLoopInformation(), &tc)); EXPECT_EQ(1000, tc); HInstruction* offset = nullptr; - EXPECT_FALSE(range_.IsUnitStride(phi, &offset)); + EXPECT_FALSE(range_.IsUnitStride(phi, phi, &offset)); HInstruction* tce = range_.GenerateTripCount( loop_header_->GetLoopInformation(), graph_, loop_preheader_); ASSERT_TRUE(tce != nullptr); @@ -908,7 +908,7 @@ TEST_F(InductionVarRangeTest, SymbolicTripCountUp) { EXPECT_TRUE(range_.IsFinite(loop_header_->GetLoopInformation(), &tc)); EXPECT_EQ(0, tc); // unknown HInstruction* offset = nullptr; - EXPECT_TRUE(range_.IsUnitStride(phi, &offset)); + EXPECT_TRUE(range_.IsUnitStride(phi, phi, &offset)); EXPECT_TRUE(offset == nullptr); HInstruction* tce = range_.GenerateTripCount( loop_header_->GetLoopInformation(), graph_, loop_preheader_); @@ -994,7 +994,7 @@ TEST_F(InductionVarRangeTest, SymbolicTripCountDown) { EXPECT_TRUE(range_.IsFinite(loop_header_->GetLoopInformation(), &tc)); EXPECT_EQ(0, tc); // unknown HInstruction* offset = nullptr; - EXPECT_FALSE(range_.IsUnitStride(phi, &offset)); + EXPECT_FALSE(range_.IsUnitStride(phi, phi, &offset)); HInstruction* tce = range_.GenerateTripCount( loop_header_->GetLoopInformation(), graph_, loop_preheader_); ASSERT_TRUE(tce != nullptr); diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 1a79601a93..bf18cc9bbc 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -580,7 +580,7 @@ bool HLoopOptimization::VectorizeDef(LoopNode* node, HInstruction* offset = nullptr; if (TrySetVectorType(type, &restrictions) && node->loop_info->IsDefinedOutOfTheLoop(base) && - induction_range_.IsUnitStride(index, &offset) && + induction_range_.IsUnitStride(instruction, index, &offset) && VectorizeUse(node, value, generate_code, type, restrictions)) { if (generate_code) { GenerateVecSub(index, offset); @@ -633,7 +633,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, HInstruction* offset = nullptr; if (type == instruction->GetType() && node->loop_info->IsDefinedOutOfTheLoop(base) && - induction_range_.IsUnitStride(index, &offset)) { + induction_range_.IsUnitStride(instruction, index, &offset)) { if (generate_code) { GenerateVecSub(index, offset); GenerateVecMem(instruction, vector_map_->Get(index), nullptr, type); |