diff options
author | 2024-02-29 17:11:18 +0000 | |
---|---|---|
committer | 2024-03-04 13:17:55 +0000 | |
commit | 31d96b5c37624e4c4c69477c6a1340cd272df7f6 (patch) | |
tree | 49a76d829fefe774459c386272d4afb4d9d04cf6 /compiler/optimizing/constant_folding.cc | |
parent | 114ac9ae5791818840ac25f38c224956dba073ad (diff) |
Fold opposite values for OR and XOR into -1
We can fold operations like `a | ~a` and `a ^ ~a` into 0xFF...FF.
These operations only exist for int/long.
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I765e294ca2938710576a94de5978994ab1227a6b
Diffstat (limited to 'compiler/optimizing/constant_folding.cc')
-rw-r--r-- | compiler/optimizing/constant_folding.cc | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc index f57d8ade16..52cbfe8322 100644 --- a/compiler/optimizing/constant_folding.cc +++ b/compiler/optimizing/constant_folding.cc @@ -876,18 +876,35 @@ void InstructionWithAbsorbingInputSimplifier::VisitMul(HMul* instruction) { void InstructionWithAbsorbingInputSimplifier::VisitOr(HOr* instruction) { HConstant* input_cst = instruction->GetConstantRight(); - - if (input_cst == nullptr) { - return; - } - - if (Int64FromConstant(input_cst) == -1) { + if (input_cst != nullptr && Int64FromConstant(input_cst) == -1) { // Replace code looking like // OR dst, src, 0xFFF...FF // with // CONSTANT 0xFFF...FF instruction->ReplaceWith(input_cst); instruction->GetBlock()->RemoveInstruction(instruction); + return; + } + + HInstruction* left = instruction->GetLeft(); + HInstruction* right = instruction->GetRight(); + if (left->IsNot() ^ right->IsNot()) { + // Replace code looking like + // NOT notsrc, src + // OR dst, notsrc, src + // with + // CONSTANT 0xFFF...FF + HInstruction* hnot = (left->IsNot() ? left : right); + HInstruction* hother = (left->IsNot() ? right : left); + HInstruction* src = hnot->AsNot()->GetInput(); + + if (src == hother) { + DCHECK(instruction->GetType() == DataType::Type::kInt32 || + instruction->GetType() == DataType::Type::kInt64); + instruction->ReplaceWith(GetGraph()->GetConstant(instruction->GetType(), -1)); + instruction->GetBlock()->RemoveInstruction(instruction); + return; + } } } @@ -974,6 +991,28 @@ void InstructionWithAbsorbingInputSimplifier::VisitXor(HXor* instruction) { HBasicBlock* block = instruction->GetBlock(); instruction->ReplaceWith(GetGraph()->GetConstant(type, 0)); block->RemoveInstruction(instruction); + return; + } + + HInstruction* left = instruction->GetLeft(); + HInstruction* right = instruction->GetRight(); + if (left->IsNot() ^ right->IsNot()) { + // Replace code looking like + // NOT notsrc, src + // XOR dst, notsrc, src + // with + // CONSTANT 0xFFF...FF + HInstruction* hnot = (left->IsNot() ? left : right); + HInstruction* hother = (left->IsNot() ? right : left); + HInstruction* src = hnot->AsNot()->GetInput(); + + if (src == hother) { + DCHECK(instruction->GetType() == DataType::Type::kInt32 || + instruction->GetType() == DataType::Type::kInt64); + instruction->ReplaceWith(GetGraph()->GetConstant(instruction->GetType(), -1)); + instruction->GetBlock()->RemoveInstruction(instruction); + return; + } } } |