X86_64: Allow HSelect to generate CMOV from memory
Use the cmov with Address operand to allow CMOV from stack location.
Change-Id: Ia2f856c7b5003c413f23adaabe19be06f38c78ab
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 35603aa..9a8edb3 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1551,14 +1551,16 @@
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(select);
if (Primitive::IsFloatingPointType(select->GetType())) {
locations->SetInAt(0, Location::RequiresFpuRegister());
- // Since we can't use CMOV, there is no need to force 'true' into a register.
locations->SetInAt(1, Location::Any());
} else {
locations->SetInAt(0, Location::RequiresRegister());
if (SelectCanUseCMOV(select)) {
- locations->SetInAt(1, Location::RequiresRegister());
+ if (select->InputAt(1)->IsConstant()) {
+ locations->SetInAt(1, Location::RequiresRegister());
+ } else {
+ locations->SetInAt(1, Location::Any());
+ }
} else {
- // Since we can't use CMOV, there is no need to force 'true' into a register.
locations->SetInAt(1, Location::Any());
}
}
@@ -1574,7 +1576,7 @@
// If both the condition and the source types are integer, we can generate
// a CMOV to implement Select.
CpuRegister value_false = locations->InAt(0).AsRegister<CpuRegister>();
- CpuRegister value_true = locations->InAt(1).AsRegister<CpuRegister>();
+ Location value_true_loc = locations->InAt(1);
DCHECK(locations->InAt(0).Equals(locations->Out()));
HInstruction* select_condition = select->GetCondition();
@@ -1606,7 +1608,14 @@
// If the condition is true, overwrite the output, which already contains false.
// Generate the correct sized CMOV.
- __ cmov(cond, value_false, value_true, select->GetType() == Primitive::kPrimLong);
+ bool is_64_bit = Primitive::Is64BitType(select->GetType());
+ if (value_true_loc.IsRegister()) {
+ __ cmov(cond, value_false, value_true_loc.AsRegister<CpuRegister>(), is_64_bit);
+ } else {
+ __ cmov(cond,
+ value_false,
+ Address(CpuRegister(RSP), value_true_loc.GetStackIndex()), is_64_bit);
+ }
} else {
NearLabel false_target;
GenerateTestAndBranch<NearLabel>(select,