ARM: VIXL32: Merge (un)signed extensions and integer additions
Test: m test-art-target-run-test-551-checker-shifter-operand
Change-Id: I041e80e51bf0954b38ab20dfa9b14aa7f6d6c53b
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index b9d4700..430cdde 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -8269,19 +8269,41 @@
const HDataProcWithShifterOp::OpKind op_kind = instruction->GetOpKind();
if (instruction->GetType() == Primitive::kPrimInt) {
- DCHECK(!HDataProcWithShifterOp::IsExtensionOp(op_kind));
-
+ const vixl32::Register first = InputRegisterAt(instruction, 0);
+ const vixl32::Register output = OutputRegister(instruction);
const vixl32::Register second = instruction->InputAt(1)->GetType() == Primitive::kPrimLong
? LowRegisterFrom(locations->InAt(1))
: InputRegisterAt(instruction, 1);
- GenerateDataProcInstruction(kind,
- OutputRegister(instruction),
- InputRegisterAt(instruction, 0),
- Operand(second,
- ShiftFromOpKind(op_kind),
- instruction->GetShiftAmount()),
- codegen_);
+ if (HDataProcWithShifterOp::IsExtensionOp(op_kind)) {
+ DCHECK_EQ(kind, HInstruction::kAdd);
+
+ switch (op_kind) {
+ case HDataProcWithShifterOp::kUXTB:
+ __ Uxtab(output, first, second);
+ break;
+ case HDataProcWithShifterOp::kUXTH:
+ __ Uxtah(output, first, second);
+ break;
+ case HDataProcWithShifterOp::kSXTB:
+ __ Sxtab(output, first, second);
+ break;
+ case HDataProcWithShifterOp::kSXTH:
+ __ Sxtah(output, first, second);
+ break;
+ default:
+ LOG(FATAL) << "Unexpected operation kind: " << op_kind;
+ UNREACHABLE();
+ }
+ } else {
+ GenerateDataProcInstruction(kind,
+ output,
+ first,
+ Operand(second,
+ ShiftFromOpKind(op_kind),
+ instruction->GetShiftAmount()),
+ codegen_);
+ }
} else {
DCHECK_EQ(instruction->GetType(), Primitive::kPrimLong);
diff --git a/compiler/optimizing/common_arm.h b/compiler/optimizing/common_arm.h
index 01304ac..8fcceed 100644
--- a/compiler/optimizing/common_arm.h
+++ b/compiler/optimizing/common_arm.h
@@ -227,14 +227,6 @@
return Location::FpuRegisterPairLocation(low.GetCode(), high.GetCode());
}
-inline bool ShifterOperandSupportsExtension(HInstruction* instruction) {
- DCHECK(HasShifterOperand(instruction, kArm));
- // TODO: HAdd applied to the other integral types could make use of
- // the SXTAB, SXTAH, UXTAB and UXTAH instructions.
- return instruction->GetType() == Primitive::kPrimLong &&
- (instruction->IsAdd() || instruction->IsSub());
-}
-
} // namespace helpers
} // namespace arm
} // namespace art
diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc
index fe22595..a025fb1 100644
--- a/compiler/optimizing/instruction_simplifier_arm.cc
+++ b/compiler/optimizing/instruction_simplifier_arm.cc
@@ -29,8 +29,6 @@
namespace arm {
-using helpers::ShifterOperandSupportsExtension;
-
bool InstructionSimplifierArmVisitor::TryMergeIntoShifterOperand(HInstruction* use,
HInstruction* bitfield_op,
bool do_merge) {
@@ -76,7 +74,7 @@
: kMaxLongShiftDistance;
if (HDataProcWithShifterOp::IsExtensionOp(op_kind)) {
- if (!ShifterOperandSupportsExtension(use)) {
+ if (!use->IsAdd() && (!use->IsSub() || use->GetType() != Primitive::kPrimLong)) {
return false;
}
// Shift by 1 is a special case that results in the same number and type of instructions
diff --git a/compiler/optimizing/scheduler_arm.cc b/compiler/optimizing/scheduler_arm.cc
index e78cd78..627ab4e 100644
--- a/compiler/optimizing/scheduler_arm.cc
+++ b/compiler/optimizing/scheduler_arm.cc
@@ -269,7 +269,6 @@
const HDataProcWithShifterOp::OpKind op_kind = instruction->GetOpKind();
if (instruction->GetType() == Primitive::kPrimInt) {
- DCHECK(!HDataProcWithShifterOp::IsExtensionOp(op_kind));
HandleGenerateDataProcInstruction();
} else {
DCHECK_EQ(instruction->GetType(), Primitive::kPrimLong);
diff --git a/test/551-checker-shifter-operand/src/Main.java b/test/551-checker-shifter-operand/src/Main.java
index 951889a..3177ec0 100644
--- a/test/551-checker-shifter-operand/src/Main.java
+++ b/test/551-checker-shifter-operand/src/Main.java
@@ -327,6 +327,7 @@
*/
/// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after)
+ /// CHECK: DataProcWithShifterOp
/// CHECK-NOT: DataProcWithShifterOp
/// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after)
@@ -399,6 +400,8 @@
}
/// CHECK-START-ARM: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm (after)
+ /// CHECK: DataProcWithShifterOp
+ /// CHECK: DataProcWithShifterOp
/// CHECK-NOT: DataProcWithShifterOp
/// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
@@ -469,6 +472,8 @@
}
/// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after)
+ /// CHECK: DataProcWithShifterOp
+ /// CHECK: DataProcWithShifterOp
/// CHECK-NOT: DataProcWithShifterOp
/// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)