diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 98f8009846..a48d06f3d0 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -830,6 +830,24 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct 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; + } + } } } |