summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author VladimĂ­r Marko <vmarko@google.com> 2024-08-13 10:03:27 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2024-08-13 10:03:27 +0000
commit275cf7423efdb36e441b7bceb2e678944f8fa34b (patch)
treecd74101af342d0798827aa853f1f5e34cc1c01a6 /compiler/optimizing
parent7496a81f4298257a5c6ce25271873b0c12e69f96 (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.cc25
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc31
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc23
-rw-r--r--compiler/optimizing/code_generator_x86.cc22
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc14
-rw-r--r--compiler/optimizing/graph_visualizer.cc1
-rw-r--r--compiler/optimizing/instruction_simplifier.cc203
-rw-r--r--compiler/optimizing/nodes.h22
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 {