diff options
author | 2017-10-25 16:00:37 +0000 | |
---|---|---|
committer | 2017-10-25 16:00:37 +0000 | |
commit | 31275df5ea1b91ed668618d6ec64a76d67cee73c (patch) | |
tree | bf41e20e1242843dd413a28c79f8b53281bfdd75 /compiler/optimizing | |
parent | 06b9807dfe501f810094df301ae96461ee871cc7 (diff) | |
parent | dab690714f88c10bec913e6fd939f3899be4bee2 (diff) |
Merge "Fix type conversion bug"
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/data_type.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 12 |
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()); |