diff options
author | 2024-02-29 16:09:29 +0000 | |
---|---|---|
committer | 2024-03-06 08:22:54 +0000 | |
commit | 04a110dadb8088eaac2c5ac014327c6335c2b8dd (patch) | |
tree | 0c8b8cdea2f7bdfe922fb7dc9bd979fb612cdea7 /compiler/optimizing/instruction_simplifier_shared.cc | |
parent | 9fa9678fa177ff480a1e5e509757d498bf7bf555 (diff) |
Convert And+Sub into bic if possible
Convert
i1: AND a, b
SUB a, i1
into:
BIC a, a, b
Also works if `i1` is AND b, a.
Bug: 304972513
Fixes: 304972513
Test: art/test/testrunner/testrunner.py --host --64 --target
Change-Id: I22218c263f52b58d87431186588ac166dc93246a
Diffstat (limited to 'compiler/optimizing/instruction_simplifier_shared.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.cc | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc index 50ea2b929b..deb8f93492 100644 --- a/compiler/optimizing/instruction_simplifier_shared.cc +++ b/compiler/optimizing/instruction_simplifier_shared.cc @@ -18,6 +18,7 @@ #include "code_generator.h" #include "mirror/array-inl.h" +#include "nodes.h" namespace art HIDDEN { @@ -229,6 +230,35 @@ bool TryMergeNegatedInput(HBinaryOperation* op) { return false; } +bool TryMergeWithAnd(HSub* instruction) { + HAnd* and_instr = instruction->GetRight()->AsAndOrNull(); + if (and_instr == nullptr) { + return false; + } + + HInstruction* value = instruction->GetLeft(); + + HInstruction* left = and_instr->GetLeft(); + const bool left_is_equal = left == value; + HInstruction* right = and_instr->GetRight(); + const bool right_is_equal = right == value; + if (!left_is_equal && !right_is_equal) { + return false; + } + + HBitwiseNegatedRight* bnr = new (instruction->GetBlock()->GetGraph()->GetAllocator()) + HBitwiseNegatedRight(instruction->GetType(), + HInstruction::InstructionKind::kAnd, + value, + left_is_equal ? right : left, + instruction->GetDexPc()); + instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, bnr); + // Since we don't run DCE after this phase, try to manually remove the And instruction. + if (!and_instr->HasUses()) { + and_instr->GetBlock()->RemoveInstruction(and_instr); + } + return true; +} bool TryExtractArrayAccessAddress(CodeGenerator* codegen, HInstruction* access, |