summaryrefslogtreecommitdiff
path: root/compiler/optimizing/graph_checker.cc
diff options
context:
space:
mode:
author Roland Levillain <rpl@google.com> 2016-03-22 14:57:31 +0000
committer Roland Levillain <rpl@google.com> 2016-03-22 14:57:31 +0000
commit5b5b9319ff970979ed47d41a41283e4faeffb602 (patch)
treee7795abf120cf512627786fd6302efd34535724b /compiler/optimizing/graph_checker.cc
parent0c25da0276f5b6f6119793ae9d45d1bca8172c2b (diff)
Fix and improve shift and rotate operations.
- Define maximum int and long shift & rotate distances as int32_t constants, as shift & rotate distances are 32-bit integer values. - Consider the (long, long) inputs case as invalid for static evaluation of shift & rotate rotations. - Add more checks in shift & rotate operations constructors as well as in art::GraphChecker. Change-Id: I754b326c3a341c9cc567d1720b327dad6fcbf9d6
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r--compiler/optimizing/graph_checker.cc26
1 files changed, 23 insertions, 3 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 9491ef6119..055061de67 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -925,9 +925,12 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
Primitive::Type lhs_type = op->InputAt(0)->GetType();
Primitive::Type rhs_type = op->InputAt(1)->GetType();
Primitive::Type result_type = op->GetType();
+
+ // Type consistency between inputs.
if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) {
if (Primitive::PrimitiveKind(rhs_type) != Primitive::kPrimInt) {
- AddError(StringPrintf("Shift operation %s %d has a non-int kind second input: %s of type %s.",
+ AddError(StringPrintf("Shift/rotate operation %s %d has a non-int kind second input: "
+ "%s of type %s.",
op->DebugName(), op->GetId(),
op->InputAt(1)->DebugName(),
Primitive::PrettyDescriptor(rhs_type)));
@@ -941,21 +944,38 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
}
}
+ // Type consistency between result and input(s).
if (op->IsCompare()) {
if (result_type != Primitive::kPrimInt) {
AddError(StringPrintf("Compare operation %d has a non-int result type: %s.",
op->GetId(),
Primitive::PrettyDescriptor(result_type)));
}
+ } else if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) {
+ // Only check the first input (value), as the second one (distance)
+ // must invariably be of kind `int`.
+ if (result_type != Primitive::PrimitiveKind(lhs_type)) {
+ AddError(StringPrintf("Shift/rotate operation %s %d has a result type different "
+ "from its left-hand side (value) input kind: %s vs %s.",
+ op->DebugName(), op->GetId(),
+ Primitive::PrettyDescriptor(result_type),
+ Primitive::PrettyDescriptor(lhs_type)));
+ }
} else {
- // Use the first input, so that we can also make this check for shift and rotate operations.
if (Primitive::PrimitiveKind(result_type) != Primitive::PrimitiveKind(lhs_type)) {
AddError(StringPrintf("Binary operation %s %d has a result kind different "
- "from its input kind: %s vs %s.",
+ "from its left-hand side input kind: %s vs %s.",
op->DebugName(), op->GetId(),
Primitive::PrettyDescriptor(result_type),
Primitive::PrettyDescriptor(lhs_type)));
}
+ if (Primitive::PrimitiveKind(result_type) != Primitive::PrimitiveKind(rhs_type)) {
+ AddError(StringPrintf("Binary operation %s %d has a result kind different "
+ "from its right-hand side input kind: %s vs %s.",
+ op->DebugName(), op->GetId(),
+ Primitive::PrettyDescriptor(result_type),
+ Primitive::PrettyDescriptor(rhs_type)));
+ }
}
}