summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2016-02-12 16:53:57 +0000
committer Vladimir Marko <vmarko@google.com> 2016-02-15 15:09:27 +0000
commit8428bd376e660df2ffceee72f797d1cfc6c66433 (patch)
tree5dc6d17eb70179b4b823d5f6034021ec6574c60b /compiler/optimizing/instruction_simplifier.cc
parentb52bbde2870e5ab5d126612961dcb3da8e5236ee (diff)
Optimizing: Remove unnecessary And before TypeConversion.
For example `(byte) (x & 0xff)` doesn't need the `& 0xff`. Bug: 23965701 Change-Id: I5fc8419491aff2cdc7074451e74e873b5f582d41
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc18
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;
+ }
+ }
}
}