summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2017-10-25 16:00:37 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2017-10-25 16:00:37 +0000
commit31275df5ea1b91ed668618d6ec64a76d67cee73c (patch)
treebf41e20e1242843dd413a28c79f8b53281bfdd75 /compiler/optimizing
parent06b9807dfe501f810094df301ae96461ee871cc7 (diff)
parentdab690714f88c10bec913e6fd939f3899be4bee2 (diff)
Merge "Fix type conversion bug"
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/data_type.h2
-rw-r--r--compiler/optimizing/instruction_simplifier.cc12
2 files changed, 11 insertions, 3 deletions
diff --git a/compiler/optimizing/data_type.h b/compiler/optimizing/data_type.h
index 3b67efe100..75a7fbe6ca 100644
--- a/compiler/optimizing/data_type.h
+++ b/compiler/optimizing/data_type.h
@@ -123,7 +123,7 @@ class DataType {
}
static bool IsUnsignedType(Type type) {
- return type == Type::kUint8 || type == Type::kUint16;
+ return type == Type::kBool || type == Type::kUint8 || type == Type::kUint16;
}
// Return the general kind of `type`, fusing integer-like types as Type::kInt.
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index d81a752853..189d5aea56 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1044,12 +1044,14 @@ void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) {
}
static bool IsTypeConversionLossless(DataType::Type input_type, DataType::Type result_type) {
+ // Make sure all implicit conversions have been simplified and no new ones have been introduced.
+ DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type))
+ << input_type << "," << result_type;
// The conversion to a larger type is loss-less with the exception of two cases,
// - conversion to the unsigned type Uint16, where we may lose some bits, and
// - conversion from float to long, the only FP to integral conversion with smaller FP type.
// For integral to FP conversions this holds because the FP mantissa is large enough.
// Note: The size check excludes Uint8 as the result type.
- DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type));
return DataType::Size(result_type) > DataType::Size(input_type) &&
result_type != DataType::Type::kUint16 &&
!(result_type == DataType::Type::kInt64 && input_type == DataType::Type::kFloat32);
@@ -1253,7 +1255,10 @@ void InstructionSimplifierVisitor::VisitAnd(HAnd* instruction) {
if (input_cst != nullptr) {
int64_t value = Int64FromConstant(input_cst);
- if (value == -1) {
+ if (value == -1 ||
+ // Similar cases under zero extension.
+ (DataType::IsUnsignedType(input_other->GetType()) &&
+ ((DataType::MaxValueOfIntegralType(input_other->GetType()) & ~value) == 0))) {
// Replace code looking like
// AND dst, src, 0xFFF...FF
// with
@@ -1332,6 +1337,9 @@ void InstructionSimplifierVisitor::VisitAnd(HAnd* instruction) {
TryReplaceFieldOrArrayGetType(input_other, new_type)) {
instruction->ReplaceWith(input_other);
instruction->GetBlock()->RemoveInstruction(instruction);
+ } else if (DataType::IsTypeConversionImplicit(input_other->GetType(), new_type)) {
+ instruction->ReplaceWith(input_other);
+ instruction->GetBlock()->RemoveInstruction(instruction);
} else {
HTypeConversion* type_conversion = new (GetGraph()->GetAllocator()) HTypeConversion(
new_type, input_other, instruction->GetDexPc());