Fix type conversion bug
Rationale:
Not simplifying double redundant AND
crashes a DCHECK due to order in which
rewrites are done.
Test: test-art-host test-art-target
Bug: 68142795
Change-Id: Ic14340ed336e6c163f9bd7aebd96f6cf41794c7e
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index d81a752..189d5ae 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1044,12 +1044,14 @@
}
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 @@
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 @@
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());