diff options
author | 2024-02-29 16:09:29 +0000 | |
---|---|---|
committer | 2024-03-06 08:22:54 +0000 | |
commit | 04a110dadb8088eaac2c5ac014327c6335c2b8dd (patch) | |
tree | 0c8b8cdea2f7bdfe922fb7dc9bd979fb612cdea7 /compiler | |
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')
4 files changed, 53 insertions, 2 deletions
diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc index be4371f734..aefa27628b 100644 --- a/compiler/optimizing/instruction_simplifier_arm.cc +++ b/compiler/optimizing/instruction_simplifier_arm.cc @@ -278,9 +278,15 @@ void InstructionSimplifierArmVisitor::VisitSub(HSub* instruction) { if (IsSubRightSubLeftShl(instruction)) { HInstruction* shl = instruction->GetRight()->InputAt(0); if (shl->InputAt(1)->IsConstant() && TryReplaceSubSubWithSubAdd(instruction)) { - TryMergeIntoUsersShifterOperand(shl); + if (TryMergeIntoUsersShifterOperand(shl)) { + return; + } } } + + if (TryMergeWithAnd(instruction)) { + return; + } } void InstructionSimplifierArmVisitor::VisitTypeConversion(HTypeConversion* instruction) { diff --git a/compiler/optimizing/instruction_simplifier_arm64.cc b/compiler/optimizing/instruction_simplifier_arm64.cc index 2c191dc3f4..d0fbe1382b 100644 --- a/compiler/optimizing/instruction_simplifier_arm64.cc +++ b/compiler/optimizing/instruction_simplifier_arm64.cc @@ -249,9 +249,15 @@ void InstructionSimplifierArm64Visitor::VisitSub(HSub* instruction) { if (IsSubRightSubLeftShl(instruction)) { HInstruction* shl = instruction->GetRight()->InputAt(0); if (shl->InputAt(1)->IsConstant() && TryReplaceSubSubWithSubAdd(instruction)) { - TryMergeIntoUsersShifterOperand(shl); + if (TryMergeIntoUsersShifterOperand(shl)) { + return; + } } } + + if (TryMergeWithAnd(instruction)) { + return; + } } void InstructionSimplifierArm64Visitor::VisitTypeConversion(HTypeConversion* instruction) { 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, diff --git a/compiler/optimizing/instruction_simplifier_shared.h b/compiler/optimizing/instruction_simplifier_shared.h index 68148cff7e..ca6d5286c5 100644 --- a/compiler/optimizing/instruction_simplifier_shared.h +++ b/compiler/optimizing/instruction_simplifier_shared.h @@ -66,6 +66,15 @@ bool TryCombineMultiplyAccumulate(HMul* mul, InstructionSet isa); // a negated bitwise instruction. bool TryMergeNegatedInput(HBinaryOperation* op); +// Convert +// i1: AND a, b +// SUB a, i1 +// into: +// BIC a, a, b +// +// It also works if `i1` is AND b, a +bool TryMergeWithAnd(HSub* instruction); + bool TryExtractArrayAccessAddress(CodeGenerator* codegen, HInstruction* access, HInstruction* array, |