Fix a bug in type propagation.
If a phi requests its inputs to be of a certain type, the inputs need
to propagate that type to their users, as those users might be
phis.
Bug report and test courtesy of Serguei I Katkov.
Change-Id: I79baac271566ec4fa684c1edf11a1b3383d896a9
diff --git a/compiler/optimizing/primitive_type_propagation.cc b/compiler/optimizing/primitive_type_propagation.cc
index c20c8a1..af93438 100644
--- a/compiler/optimizing/primitive_type_propagation.cc
+++ b/compiler/optimizing/primitive_type_propagation.cc
@@ -65,6 +65,10 @@
if (equivalent->IsPhi()) {
equivalent->AsPhi()->SetLive();
AddToWorklist(equivalent->AsPhi());
+ } else if (equivalent == input) {
+ // The input has changed its type. It can be an input of other phis,
+ // so we need to put phi users in the work list.
+ AddDependentInstructionsToWorklist(equivalent);
}
}
}
@@ -117,10 +121,10 @@
worklist_.Add(instruction);
}
-void PrimitiveTypePropagation::AddDependentInstructionsToWorklist(HPhi* instruction) {
+void PrimitiveTypePropagation::AddDependentInstructionsToWorklist(HInstruction* instruction) {
for (HUseIterator<HInstruction*> it(instruction->GetUses()); !it.Done(); it.Advance()) {
HPhi* phi = it.Current()->GetUser()->AsPhi();
- if (phi != nullptr && phi->IsLive()) {
+ if (phi != nullptr && phi->IsLive() && phi->GetType() != instruction->GetType()) {
AddToWorklist(phi);
}
}
diff --git a/compiler/optimizing/primitive_type_propagation.h b/compiler/optimizing/primitive_type_propagation.h
index 1374cbb..6d370ed 100644
--- a/compiler/optimizing/primitive_type_propagation.h
+++ b/compiler/optimizing/primitive_type_propagation.h
@@ -33,7 +33,7 @@
void VisitBasicBlock(HBasicBlock* block);
void ProcessWorklist();
void AddToWorklist(HPhi* phi);
- void AddDependentInstructionsToWorklist(HPhi* phi);
+ void AddDependentInstructionsToWorklist(HInstruction* instruction);
bool UpdateType(HPhi* phi);
HGraph* const graph_;
diff --git a/test/472-type-propagation/expected.txt b/test/472-type-propagation/expected.txt
new file mode 100644
index 0000000..0b29bb1
--- /dev/null
+++ b/test/472-type-propagation/expected.txt
@@ -0,0 +1,2 @@
+4.3
+1.2
diff --git a/test/472-type-propagation/info.txt b/test/472-type-propagation/info.txt
new file mode 100644
index 0000000..b86e5a2
--- /dev/null
+++ b/test/472-type-propagation/info.txt
@@ -0,0 +1,3 @@
+Regression test for optimizing's type propagation:
+If a phi requests its inputs to be of a certain type, the inputs need
+to propagate that type to their users, as those users might be phis.
diff --git a/test/472-type-propagation/src/Main.java b/test/472-type-propagation/src/Main.java
new file mode 100644
index 0000000..f9e302f
--- /dev/null
+++ b/test/472-type-propagation/src/Main.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class Main {
+ public static void main(String[] args) {
+ ssaBuilderDouble(new double[] { 1.2, 4.3, 5.2 });
+ ssaBuilderDouble(new double[] { 1.2, 4.3, 5.2, 6.8 });
+ }
+
+ public static void ssaBuilderDouble(double[] array) {
+ double x;
+ if (array.length > 3) {
+ x = array[0];
+ } else {
+ x = array[1];
+ }
+ array[2] = x;
+ System.out.println(x);
+ }
+}