Optimizing: Remove unnecessary And before TypeConversion.
For example `(byte) (x & 0xff)` doesn't need the `& 0xff`.
Bug: 23965701
Change-Id: I5fc8419491aff2cdc7074451e74e873b5f582d41
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 98f8009..a48d06f 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -830,6 +830,24 @@
return;
}
}
+ } else if (input->IsAnd() &&
+ Primitive::IsIntegralType(result_type) &&
+ input->HasOnlyOneNonEnvironmentUse()) {
+ DCHECK(Primitive::IsIntegralType(input_type));
+ HAnd* input_and = input->AsAnd();
+ HConstant* constant = input_and->GetConstantRight();
+ if (constant != nullptr) {
+ int64_t value = Int64FromConstant(constant);
+ DCHECK_NE(value, -1); // "& -1" would have been optimized away in VisitAnd().
+ size_t trailing_ones = CTZ(~static_cast<uint64_t>(value));
+ if (trailing_ones >= kBitsPerByte * Primitive::ComponentSize(result_type)) {
+ // The `HAnd` is useless, for example in `(byte) (x & 0xff)`, get rid of it.
+ input_and->ReplaceWith(input_and->GetLeastConstantLeft());
+ input_and->GetBlock()->RemoveInstruction(input_and);
+ RecordSimplification();
+ return;
+ }
+ }
}
}