diff options
author | 2016-03-22 14:57:31 +0000 | |
---|---|---|
committer | 2016-03-22 14:57:31 +0000 | |
commit | 5b5b9319ff970979ed47d41a41283e4faeffb602 (patch) | |
tree | e7795abf120cf512627786fd6302efd34535724b /compiler/optimizing/graph_checker.cc | |
parent | 0c25da0276f5b6f6119793ae9d45d1bca8172c2b (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.cc | 26 |
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))); + } } } |