summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Aart Bik <ajcbik@google.com> 2017-04-07 11:33:37 -0700
committer Aart Bik <ajcbik@google.com> 2017-04-07 23:03:42 +0000
commitfa76296bc624bc2c879167c260ad6925238efb3d (patch)
tree045c4488fec66806982a62aa4cfd7d3a2183e958 /compiler/optimizing
parent6f005931d0a0db65128db803df38d59d205dd218 (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.cc5
-rw-r--r--compiler/optimizing/induction_var_range.h10
-rw-r--r--compiler/optimizing/induction_var_range_test.cc8
-rw-r--r--compiler/optimizing/loop_optimization.cc4
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);