ART-Optimizing: Fix the type of HDivZeroCheck
HDivZeroCheck is created during the building CFG and at this moment
its type is not known completely. So it sets the type to int or long.
However, later SSA builder can insert the type conversion and type
of input of HDivZeroCheck can become byte or short while the type
of HDivZeroCheck remains the same.
In reality the type of HDivZeroCheck should be always equal to
its input parameter.
To fix this inconsistency we return the type of HDivZeroCheck as its
input type. Code generators are updated accordingly.
Change-Id: I6a5aedc8d479cfc6328704e7ddf252bca830076b
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index b0a4ce2..e832871 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2775,6 +2775,9 @@
Location value = locations->InAt(0);
switch (instruction->GetType()) {
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
case Primitive::kPrimInt: {
if (value.IsRegister()) {
__ CompareAndBranchIfZero(value.AsRegister<Register>(), slow_path->GetEntryLabel());
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index bbde7e8..8a9669a 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1998,8 +1998,8 @@
Primitive::Type type = instruction->GetType();
- if ((type != Primitive::kPrimInt) && (type != Primitive::kPrimLong)) {
- LOG(FATAL) << "Unexpected type " << type << "for DivZeroCheck.";
+ if ((type == Primitive::kPrimBoolean) || !Primitive::IsIntegralType(type)) {
+ LOG(FATAL) << "Unexpected type " << type << " for DivZeroCheck.";
return;
}
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index a5bad65..523b236 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -1894,8 +1894,9 @@
Primitive::Type type = instruction->GetType();
- if ((type != Primitive::kPrimInt) && (type != Primitive::kPrimLong)) {
+ if ((type == Primitive::kPrimBoolean) || !Primitive::IsIntegralType(type)) {
LOG(FATAL) << "Unexpected type " << type << " for DivZeroCheck.";
+ return;
}
if (value.IsConstant()) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index fdef06b..e89ea85 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -2937,6 +2937,9 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
switch (instruction->GetType()) {
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
case Primitive::kPrimInt: {
locations->SetInAt(0, Location::Any());
break;
@@ -2964,6 +2967,9 @@
Location value = locations->InAt(0);
switch (instruction->GetType()) {
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
case Primitive::kPrimInt: {
if (value.IsRegister()) {
__ testl(value.AsRegister<Register>(), value.AsRegister<Register>());
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 4fe93f9..2c1392b 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -3141,6 +3141,9 @@
Location value = locations->InAt(0);
switch (instruction->GetType()) {
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
case Primitive::kPrimInt: {
if (value.IsRegister()) {
__ testl(value.AsRegister<CpuRegister>(), value.AsRegister<CpuRegister>());
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 814cebb..ca2c998 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3298,6 +3298,8 @@
SetRawInputAt(0, value);
}
+ Primitive::Type GetType() const OVERRIDE { return InputAt(0)->GetType(); }
+
bool CanBeMoved() const OVERRIDE { return true; }
bool InstructionDataEquals(HInstruction* other) const OVERRIDE {