diff options
author | 2024-08-13 10:03:27 +0000 | |
---|---|---|
committer | 2024-08-13 10:03:27 +0000 | |
commit | 275cf7423efdb36e441b7bceb2e678944f8fa34b (patch) | |
tree | cd74101af342d0798827aa853f1f5e34cc1c01a6 /compiler/optimizing | |
parent | 7496a81f4298257a5c6ce25271873b0c12e69f96 (diff) |
Revert "Implement transform from signed to unsigned compare"
This reverts commit 7496a81f4298257a5c6ce25271873b0c12e69f96.
Reason for revert: Broke some builds because of wrong
handling of HCompare(unsigned)+{HEqual,HNotEqual}.
Change-Id: Ic233740c3997d449777207d15243c8a4786df238
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 25 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_riscv64.cc | 23 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 22 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 1 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 203 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 22 |
8 files changed, 41 insertions, 300 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 5b7f880589..d6375f8b59 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -3270,18 +3270,16 @@ void InstructionCodeGeneratorARM64::GenerateFcmp(HInstruction* instruction) { void LocationsBuilderARM64::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(compare, LocationSummary::kNoCall); - DataType::Type compare_type = compare->GetComparisonType(); + DataType::Type in_type = compare->InputAt(0)->GetType(); HInstruction* rhs = compare->InputAt(1); - switch (compare_type) { + switch (in_type) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint32: - case DataType::Type::kInt64: - case DataType::Type::kUint64: { + case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, ARM64EncodableConstantOrRegister(rhs, compare)); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); @@ -3298,22 +3296,17 @@ void LocationsBuilderARM64::VisitCompare(HCompare* compare) { break; } default: - LOG(FATAL) << "Unexpected type for compare operation " << compare_type; + LOG(FATAL) << "Unexpected type for compare operation " << in_type; } } void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) { - DataType::Type compare_type = compare->GetComparisonType(); + DataType::Type in_type = compare->InputAt(0)->GetType(); // 0 if: left == right // 1 if: left > right // -1 if: left < right - Condition less_cond = lt; - switch (compare_type) { - case DataType::Type::kUint32: - case DataType::Type::kUint64: - less_cond = lo; - FALLTHROUGH_INTENDED; + switch (in_type) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: @@ -3325,8 +3318,8 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) { Register left = InputRegisterAt(compare, 0); Operand right = InputOperandAt(compare, 1); __ Cmp(left, right); - __ Cset(result, ne); // result == +1 if NE or 0 otherwise - __ Cneg(result, result, less_cond); // result == -1 if LT or unchanged otherwise + __ Cset(result, ne); // result == +1 if NE or 0 otherwise + __ Cneg(result, result, lt); // result == -1 if LT or unchanged otherwise break; } case DataType::Type::kFloat32: @@ -3338,7 +3331,7 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) { break; } default: - LOG(FATAL) << "Unimplemented compare type " << compare_type; + LOG(FATAL) << "Unimplemented compare type " << in_type; } } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 92081ff1ac..34227a5480 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5756,16 +5756,14 @@ void InstructionCodeGeneratorARMVIXL::VisitBooleanNot(HBooleanNot* bool_not) { void LocationsBuilderARMVIXL::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->GetComparisonType()) { + switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint32: - case DataType::Type::kInt64: - case DataType::Type::kUint64: { + case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RequiresRegister()); // Output overlaps because it is written before doing the low comparison. @@ -5792,14 +5790,9 @@ void InstructionCodeGeneratorARMVIXL::VisitCompare(HCompare* compare) { vixl32::Label less, greater, done; vixl32::Label* final_label = codegen_->GetFinalLabel(compare, &done); - DataType::Type type = compare->GetComparisonType(); - vixl32::Condition less_cond = vixl32::ConditionType::lt; - vixl32::Condition greater_cond = vixl32::ConditionType::gt; + DataType::Type type = compare->InputAt(0)->GetType(); + vixl32::Condition less_cond = vixl32::Condition::None(); switch (type) { - case DataType::Type::kUint32: - less_cond = vixl32::ConditionType::lo; - // greater_cond - is not needed below - FALLTHROUGH_INTENDED; case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: @@ -5808,22 +5801,18 @@ void InstructionCodeGeneratorARMVIXL::VisitCompare(HCompare* compare) { case DataType::Type::kInt32: { // Emit move to `out` before the `Cmp`, as `Mov` might affect the status flags. __ Mov(out, 0); - __ Cmp(RegisterFrom(left), RegisterFrom(right)); + __ Cmp(RegisterFrom(left), RegisterFrom(right)); // Signed compare. + less_cond = lt; break; } - case DataType::Type::kUint64: - less_cond = vixl32::ConditionType::lo; - greater_cond = vixl32::ConditionType::hi; - FALLTHROUGH_INTENDED; case DataType::Type::kInt64: { - __ Cmp(HighRegisterFrom(left), HighRegisterFrom(right)); // High part compare. - __ B(less_cond, &less, /* is_far_target= */ false); - __ B(greater_cond, &greater, /* is_far_target= */ false); + __ Cmp(HighRegisterFrom(left), HighRegisterFrom(right)); // Signed compare. + __ B(lt, &less, /* is_far_target= */ false); + __ B(gt, &greater, /* is_far_target= */ false); // Emit move to `out` before the last `Cmp`, as `Mov` might affect the status flags. __ Mov(out, 0); __ Cmp(LowRegisterFrom(left), LowRegisterFrom(right)); // Unsigned compare. - less_cond = vixl32::ConditionType::lo; - // greater_cond - is not needed below + less_cond = lo; break; } case DataType::Type::kFloat32: diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc index bfc693f76b..f6067a5468 100644 --- a/compiler/optimizing/code_generator_riscv64.cc +++ b/compiler/optimizing/code_generator_riscv64.cc @@ -3470,20 +3470,18 @@ void InstructionCodeGeneratorRISCV64::VisitClinitCheck(HClinitCheck* instruction } void LocationsBuilderRISCV64::VisitCompare(HCompare* instruction) { - DataType::Type compare_type = instruction->GetComparisonType(); + DataType::Type in_type = instruction->InputAt(0)->GetType(); LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); - switch (compare_type) { + switch (in_type) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint32: case DataType::Type::kInt64: - case DataType::Type::kUint64: locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, RegisterOrZeroBitPatternLocation(instruction->InputAt(1))); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); @@ -3497,7 +3495,7 @@ void LocationsBuilderRISCV64::VisitCompare(HCompare* instruction) { break; default: - LOG(FATAL) << "Unexpected type for compare operation " << compare_type; + LOG(FATAL) << "Unexpected type for compare operation " << in_type; UNREACHABLE(); } } @@ -3506,12 +3504,11 @@ void InstructionCodeGeneratorRISCV64::VisitCompare(HCompare* instruction) { LocationSummary* locations = instruction->GetLocations(); XRegister result = locations->Out().AsRegister<XRegister>(); DataType::Type in_type = instruction->InputAt(0)->GetType(); - DataType::Type compare_type = instruction->GetComparisonType(); // 0 if: left == right // 1 if: left > right // -1 if: left < right - switch (compare_type) { + switch (in_type) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: @@ -3529,18 +3526,6 @@ void InstructionCodeGeneratorRISCV64::VisitCompare(HCompare* instruction) { break; } - case DataType::Type::kUint32: - case DataType::Type::kUint64: { - XRegister left = locations->InAt(0).AsRegister<XRegister>(); - XRegister right = InputXRegisterOrZero(locations->InAt(1)); - ScratchRegisterScope srs(GetAssembler()); - XRegister tmp = srs.AllocateXRegister(); - __ Sltu(tmp, left, right); - __ Sltu(result, right, left); - __ Sub(result, result, tmp); - break; - } - case DataType::Type::kFloat32: case DataType::Type::kFloat64: { FRegister left = locations->InAt(0).AsFpuRegister<FRegister>(); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 52c4b321f9..91f4a89ced 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -5288,16 +5288,14 @@ void InstructionCodeGeneratorX86::VisitBooleanNot(HBooleanNot* bool_not) { void LocationsBuilderX86::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->GetComparisonType()) { + switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint32: - case DataType::Type::kInt64: - case DataType::Type::kUint64: { + case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::Any()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); @@ -5329,13 +5327,8 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { NearLabel less, greater, done; Condition less_cond = kLess; - Condition greater_cond = kGreater; - switch (compare->GetComparisonType()) { - case DataType::Type::kUint32: - less_cond = kBelow; - // greater_cond - is not needed below - FALLTHROUGH_INTENDED; + switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: @@ -5345,10 +5338,6 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { codegen_->GenerateIntCompare(left, right); break; } - case DataType::Type::kUint64: - less_cond = kBelow; - greater_cond = kAbove; - FALLTHROUGH_INTENDED; case DataType::Type::kInt64: { Register left_low = left.AsRegisterPairLow<Register>(); Register left_high = left.AsRegisterPairHigh<Register>(); @@ -5372,8 +5361,8 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { DCHECK(right_is_const) << right; codegen_->Compare32BitValue(left_high, val_high); } - __ j(less_cond, &less); // High part compare. - __ j(greater_cond, &greater); // High part compare. + __ j(kLess, &less); // Signed compare. + __ j(kGreater, &greater); // Signed compare. if (right.IsRegisterPair()) { __ cmpl(left_low, right.AsRegisterPairLow<Register>()); } else if (right.IsDoubleStackSlot()) { @@ -5383,7 +5372,6 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { codegen_->Compare32BitValue(left_low, val_low); } less_cond = kBelow; // for CF (unsigned). - // greater_cond - is not needed below break; } case DataType::Type::kFloat32: { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 2d26fb86ad..7d2a9213fd 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -2727,16 +2727,14 @@ void InstructionCodeGeneratorX86_64::VisitAboveOrEqual(HAboveOrEqual* comp) { void LocationsBuilderX86_64::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->GetComparisonType()) { + switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint32: - case DataType::Type::kInt64: - case DataType::Type::kUint64: { + case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::Any()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); @@ -2761,13 +2759,10 @@ void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { Location right = locations->InAt(1); NearLabel less, greater, done; - DataType::Type type = compare->GetComparisonType(); + DataType::Type type = compare->InputAt(0)->GetType(); Condition less_cond = kLess; switch (type) { - case DataType::Type::kUint32: - less_cond = kBelow; - FALLTHROUGH_INTENDED; case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: @@ -2777,9 +2772,6 @@ void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { codegen_->GenerateIntCompare(left, right); break; } - case DataType::Type::kUint64: - less_cond = kBelow; - FALLTHROUGH_INTENDED; case DataType::Type::kInt64: { codegen_->GenerateLongCompare(left, right); break; diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 7de0ac1998..46db4489d6 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -488,7 +488,6 @@ class HGraphVisualizerPrinter final : public HGraphDelegateVisitor { void VisitCompare(HCompare* compare) override { StartAttributeStream("bias") << compare->GetBias(); - StartAttributeStream("comparison_type") << compare->GetComparisonType(); } void VisitCondition(HCondition* condition) override { diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index ec02c6ef66..cafa83bece 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -89,7 +89,6 @@ class InstructionSimplifierVisitor final : public HGraphDelegateVisitor { void VisitAbs(HAbs* instruction) override; void VisitAdd(HAdd* instruction) override; void VisitAnd(HAnd* instruction) override; - void VisitCompare(HCompare* instruction) override; void VisitCondition(HCondition* instruction) override; void VisitGreaterThan(HGreaterThan* condition) override; void VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) override; @@ -879,7 +878,7 @@ void InstructionSimplifierVisitor::VisitStaticFieldSet(HStaticFieldSet* instruct } } -static HCondition* CreateOppositeConditionSwapOps(ArenaAllocator* allocator, HInstruction* cond) { +static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* allocator, HInstruction* cond) { HInstruction *lhs = cond->InputAt(0); HInstruction *rhs = cond->InputAt(1); switch (cond->GetKind()) { @@ -1795,56 +1794,6 @@ static bool RecognizeAndSimplifyClassCheck(HCondition* condition) { } } -static HInstruction* CreateUnsignedConditionReplacement(ArenaAllocator* allocator, - HCondition* cond, - HCompare* compare) { - DCHECK(cond->InputAt(1)->IsIntConstant()); - DCHECK_EQ(cond->InputAt(1)->AsIntConstant()->GetValue(), 0); - DCHECK(cond->InputAt(0) == compare); - - HBasicBlock* block = cond->GetBlock(); - HInstruction* lhs = compare->InputAt(0); - HInstruction* rhs = compare->InputAt(1); - - switch (cond->GetKind()) { - case HInstruction::kLessThan: - return new (allocator) HBelow(lhs, rhs, cond->GetDexPc()); - case HInstruction::kLessThanOrEqual: - return new (allocator) HBelowOrEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kGreaterThan: - return new (allocator) HAbove(lhs, rhs, cond->GetDexPc()); - case HInstruction::kGreaterThanOrEqual: - return new (allocator) HAboveOrEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kBelow: - // Below(Compare(x, y), 0) always False since - // unsigned(-1) < 0 -> False - // 0 < 0 -> False - // 1 < 0 -> False - return block->GetGraph()->GetConstant(DataType::Type::kBool, 0, cond->GetDexPc()); - case HInstruction::kBelowOrEqual: - // BelowOrEqual(Compare(x, y), 0) transforms into Equal(x, y) - // unsigned(-1) <= 0 -> False - // 0 <= 0 -> True - // 1 <= 0 -> False - return new (allocator) HEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kAbove: - // Above(Compare(x, y), 0) transforms into NotEqual(x, y) - // unsigned(-1) > 0 -> True - // 0 > 0 -> False - // 1 > 0 -> True - return new (allocator) HNotEqual(lhs, rhs, cond->GetDexPc()); - case HInstruction::kAboveOrEqual: - // AboveOrEqual(Compare(x, y), 0) always True since - // unsigned(-1) >= 0 -> True - // 0 >= 0 -> True - // 1 >= 0 -> True - return block->GetGraph()->GetConstant(DataType::Type::kBool, 1, cond->GetDexPc()); - default: - LOG(FATAL) << "Unknown ConditionType " << cond->GetKind(); - UNREACHABLE(); - } -} - void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { if (condition->IsEqual() || condition->IsNotEqual()) { if (RecognizeAndSimplifyClassCheck(condition)) { @@ -1854,10 +1803,10 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { // Reverse condition if left is constant. Our code generators prefer constant // on the right hand side. - HBasicBlock* block = condition->GetBlock(); if (condition->GetLeft()->IsConstant() && !condition->GetRight()->IsConstant()) { + HBasicBlock* block = condition->GetBlock(); HCondition* replacement = - CreateOppositeConditionSwapOps(block->GetGraph()->GetAllocator(), condition); + GetOppositeConditionSwapOps(block->GetGraph()->GetAllocator(), condition); // If it is a fp we must set the opposite bias. if (replacement != nullptr) { if (condition->IsLtBias()) { @@ -1865,7 +1814,6 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { } else if (condition->IsGtBias()) { replacement->SetBias(ComparisonBias::kLtBias); } - block->ReplaceAndRemoveInstructionWith(condition, replacement); RecordSimplification(); @@ -1908,24 +1856,11 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { left->RemoveEnvironmentUsers(); // We have decided to fold the HCompare into the HCondition. Transfer the information. - if (DataType::IsUnsignedType(left->AsCompare()->GetComparisonType())) { - DCHECK_EQ(condition->GetBias(), ComparisonBias::kNoBias); - HInstruction* replacement = CreateUnsignedConditionReplacement( - block->GetGraph()->GetAllocator(), condition, left->AsCompare()); - - if (replacement->IsConstant()) { - condition->ReplaceWith(replacement); - block->RemoveInstruction(condition); - } else { - block->ReplaceAndRemoveInstructionWith(condition, replacement); - } - } else { - condition->SetBias(left->AsCompare()->GetBias()); + condition->SetBias(left->AsCompare()->GetBias()); - // Replace the operands of the HCondition. - condition->ReplaceInput(left->InputAt(0), 0); - condition->ReplaceInput(left->InputAt(1), 1); - } + // Replace the operands of the HCondition. + condition->ReplaceInput(left->InputAt(0), 0); + condition->ReplaceInput(left->InputAt(1), 1); // Remove the HCompare. left->GetBlock()->RemoveInstruction(left); @@ -1933,130 +1868,6 @@ void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) { RecordSimplification(); } -static HInstruction* CheckSignedToUnsignedCompareConversion(HInstruction* operand, - HCompare* compare) { - // Check if operand looks like `ADD op, MIN_INTEGRAL` - if (operand->IsConstant()) { - // CONSTANT #x -> CONSTANT #(x - MIN_INTEGRAL) - HConstant* constant = operand->AsConstant(); - if (constant->IsIntConstant()) { - HIntConstant* int_constant = constant->AsIntConstant(); - int32_t old_value = int_constant->GetValue(); - int32_t new_value = old_value - std::numeric_limits<int32_t>::min(); - return operand->GetBlock()->GetGraph()->GetIntConstant(new_value, constant->GetDexPc()); - } else if (constant->IsLongConstant()) { - HLongConstant* long_constant = constant->AsLongConstant(); - int64_t old_value = long_constant->GetValue(); - int64_t new_value = old_value - std::numeric_limits<int64_t>::min(); - return operand->GetBlock()->GetGraph()->GetLongConstant(new_value, constant->GetDexPc()); - } else { - return nullptr; - } - } - - if (!operand->IsAdd() && !operand->IsXor()) { - return nullptr; - } - - if (!operand->GetEnvUses().empty()) { - // There is a reference to the compare result in an environment. Do we really need it? - if (operand->GetBlock()->GetGraph()->IsDebuggable()) { - return nullptr; - } - - // We have to ensure that there are no deopt points in the sequence. - if (operand->HasAnyEnvironmentUseBefore(compare)) { - return nullptr; - } - } - - HBinaryOperation* additive_operand = operand->AsBinaryOperation(); - - HInstruction* left = additive_operand->GetLeft(); - HInstruction* right = additive_operand->GetRight(); - - HConstant* constant = nullptr; - HInstruction* value = nullptr; - - if (left->IsConstant() && !right->IsConstant()) { - constant = left->AsConstant(); - value = right; - } else if (!left->IsConstant() && right->IsConstant()) { - value = left; - constant = right->AsConstant(); - } else { - return nullptr; - } - - if (constant->IsIntConstant()) { - HIntConstant* int_constant = constant->AsIntConstant(); - if (int_constant->GetValue() != std::numeric_limits<int32_t>::min()) { - return nullptr; - } - } else if (constant->IsLongConstant()) { - HLongConstant* long_constant = constant->AsLongConstant(); - if (long_constant->GetValue() != std::numeric_limits<int64_t>::min()) { - return nullptr; - } - } else { - return nullptr; - } - - return value; -} - -static DataType::Type GetOpositeSignType(DataType::Type type) { - return DataType::IsUnsignedType(type) ? DataType::ToSigned(type) : DataType::ToUnsigned(type); -} - -void InstructionSimplifierVisitor::VisitCompare(HCompare* compare) { - // Transform signed compare into unsigned if possible - // Replace code looking like - // ADD normalizedLeft, left, MIN_INTEGRAL - // ADD normalizedRight, right, MIN_INTEGRAL - // COMPARE normalizedLeft, normalizedRight, sign - // with - // COMPARE left, right, !sign - - if (!DataType::IsIntegralType(compare->GetComparisonType())) { - return; - } - - HInstruction* compare_left = compare->GetLeft(); - HInstruction* compare_right = compare->GetRight(); - - if (compare_left->IsConstant() && compare_right->IsConstant()) { - // Do not simplify, let it be folded. - return; - } - - HInstruction* left = CheckSignedToUnsignedCompareConversion(compare_left, compare); - if (left == nullptr) { - return; - } - - HInstruction* right = CheckSignedToUnsignedCompareConversion(compare_right, compare); - if (right == nullptr) { - return; - } - - compare->SetComparisonType(GetOpositeSignType(compare->GetComparisonType())); - compare->ReplaceInput(left, 0); - compare->ReplaceInput(right, 1); - - RecordSimplification(); - - if (compare_left->GetUses().empty()) { - compare_left->RemoveEnvironmentUsers(); - compare_left->GetBlock()->RemoveInstruction(compare_left); - } - - if (compare_right->GetUses().empty()) { - compare_right->RemoveEnvironmentUsers(); - compare_right->GetBlock()->RemoveInstruction(compare_right); - } -} - // Return whether x / divisor == x * (1.0f / divisor), for every float x. static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) { // True, if the most significant bits of divisor are 0. diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 9d6da95f0f..99bb5f8478 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -4503,7 +4503,6 @@ class HCompare final : public HBinaryOperation { SideEffectsForArchRuntimeCalls(comparison_type), dex_pc) { SetPackedField<ComparisonBiasField>(bias); - SetPackedField<ComparisonTypeField>(comparison_type); } template <typename T> @@ -4523,16 +4522,10 @@ class HCompare final : public HBinaryOperation { // graph. However HCompare integer instructions can be synthesized // by the instruction simplifier to implement IntegerCompare and // IntegerSignum intrinsics, so we have to handle this case. - const int32_t value = DataType::IsUnsignedType(GetComparisonType()) ? - Compute(x->GetValueAsUint64(), y->GetValueAsUint64()) : - Compute(x->GetValue(), y->GetValue()); - return MakeConstantComparison(value, GetDexPc()); + return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { - const int32_t value = DataType::IsUnsignedType(GetComparisonType()) ? - Compute(x->GetValueAsUint64(), y->GetValueAsUint64()) : - Compute(x->GetValue(), y->GetValue()); - return MakeConstantComparison(value, GetDexPc()); + return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); } HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); @@ -4547,10 +4540,6 @@ class HCompare final : public HBinaryOperation { ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); } - DataType::Type GetComparisonType() const { return GetPackedField<ComparisonTypeField>(); } - - void SetComparisonType(DataType::Type newType) { SetPackedField<ComparisonTypeField>(newType); } - // Does this compare instruction have a "gt bias" (vs an "lt bias")? // Only meaningful for floating-point comparisons. bool IsGtBias() const { @@ -4569,16 +4558,11 @@ class HCompare final : public HBinaryOperation { static constexpr size_t kFieldComparisonBias = kNumberOfGenericPackedBits; static constexpr size_t kFieldComparisonBiasSize = MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast)); - static constexpr size_t kFieldComparisonType = kFieldComparisonBias + kFieldComparisonBiasSize; - static constexpr size_t kFieldComparisonTypeSize = - MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast)); static constexpr size_t kNumberOfComparePackedBits = - kFieldComparisonType + kFieldComparisonTypeSize; + kFieldComparisonBias + kFieldComparisonBiasSize; static_assert(kNumberOfComparePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); using ComparisonBiasField = BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>; - using ComparisonTypeField = - BitField<DataType::Type, kFieldComparisonType, kFieldComparisonTypeSize>; // Return an integer constant containing the result of a comparison evaluated at compile time. HIntConstant* MakeConstantComparison(int32_t value, uint32_t dex_pc) const { |