summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2018-11-20 13:24:26 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-11-20 13:24:26 +0000
commite48746be5dbb523a9623f64c39a1922b326b45e8 (patch)
tree1cce4d29c507359d80b91bbc1aead91c305ef169
parentfe96083dbf14f4c8465694e0144af0e13c2bc171 (diff)
parent1cc73291d4039283fa622ec3e1fb681a9faa3499 (diff)
Merge "On x86 modified the generated instructions for case "divide by 2". As we can use fewer instructions to represent HDiv when divide by2."
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc29
-rw-r--r--test/411-checker-hdiv-hrem-pow2/src/DivTest.java12
2 files changed, 33 insertions, 8 deletions
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 14cff05f58..e7212cd479 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -3608,9 +3608,17 @@ void InstructionCodeGeneratorX86_64::DivByPowerOfTwo(HDiv* instruction) {
CpuRegister tmp = locations->GetTemp(0).AsRegister<CpuRegister>();
if (instruction->GetResultType() == DataType::Type::kInt32) {
- __ leal(tmp, Address(numerator, abs_imm - 1));
- __ testl(numerator, numerator);
- __ cmov(kGreaterEqual, tmp, numerator);
+ // When denominator is equal to 2, we can add signed bit and numerator to tmp.
+ // Below we are using addl instruction instead of cmov which give us 1 cycle benefit.
+ if (abs_imm == 2) {
+ __ leal(tmp, Address(numerator, 0));
+ __ shrl(tmp, Immediate(31));
+ __ addl(tmp, numerator);
+ } else {
+ __ leal(tmp, Address(numerator, abs_imm - 1));
+ __ testl(numerator, numerator);
+ __ cmov(kGreaterEqual, tmp, numerator);
+ }
int shift = CTZ(imm);
__ sarl(tmp, Immediate(shift));
@@ -3622,11 +3630,16 @@ void InstructionCodeGeneratorX86_64::DivByPowerOfTwo(HDiv* instruction) {
} else {
DCHECK_EQ(instruction->GetResultType(), DataType::Type::kInt64);
CpuRegister rdx = locations->GetTemp(0).AsRegister<CpuRegister>();
-
- codegen_->Load64BitValue(rdx, abs_imm - 1);
- __ addq(rdx, numerator);
- __ testq(numerator, numerator);
- __ cmov(kGreaterEqual, rdx, numerator);
+ if (abs_imm == 2) {
+ __ movq(rdx, numerator);
+ __ shrq(rdx, Immediate(63));
+ __ addq(rdx, numerator);
+ } else {
+ codegen_->Load64BitValue(rdx, abs_imm - 1);
+ __ addq(rdx, numerator);
+ __ testq(numerator, numerator);
+ __ cmov(kGreaterEqual, rdx, numerator);
+ }
int shift = CTZ(imm);
__ sarq(rdx, Immediate(shift));
diff --git a/test/411-checker-hdiv-hrem-pow2/src/DivTest.java b/test/411-checker-hdiv-hrem-pow2/src/DivTest.java
index a3882e7c15..1a086ef04d 100644
--- a/test/411-checker-hdiv-hrem-pow2/src/DivTest.java
+++ b/test/411-checker-hdiv-hrem-pow2/src/DivTest.java
@@ -94,6 +94,9 @@ public class DivTest {
/// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivBy2(int) disassembly (after)
/// CHECK: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31
/// CHECK: asr w{{\d+}}, w{{\d+}}, #1
+ /// CHECK-START-X86_64: java.lang.Integer DivTest.$noinline$IntDivBy2(int) disassembly (after)
+ /// CHECK-NOT: cmovnl/geq
+ /// CHECK: add
private static Integer $noinline$IntDivBy2(int v) {
int r = v / 2;
return r;
@@ -102,6 +105,9 @@ public class DivTest {
/// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivByMinus2(int) disassembly (after)
/// CHECK: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31
/// CHECK: neg w{{\d+}}, w{{\d+}}, asr #1
+ /// CHECK-START-X86_64: java.lang.Integer DivTest.$noinline$IntDivByMinus2(int) disassembly (after)
+ /// CHECK-NOT: cmovnl/geq
+ /// CHECK: add
private static Integer $noinline$IntDivByMinus2(int v) {
int r = v / -2;
return r;
@@ -205,6 +211,9 @@ public class DivTest {
/// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivBy2(long) disassembly (after)
/// CHECK: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63
/// CHECK: asr x{{\d+}}, x{{\d+}}, #1
+ /// CHECK-START-X86_64: java.lang.Long DivTest.$noinline$LongDivBy2(long) disassembly (after)
+ /// CHECK-NOT: cmovnl/geq
+ /// CHECK: addq
private static Long $noinline$LongDivBy2(long v) {
long r = v / 2;
return r;
@@ -213,6 +222,9 @@ public class DivTest {
/// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivByMinus2(long) disassembly (after)
/// CHECK: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63
/// CHECK: neg x{{\d+}}, x{{\d+}}, asr #1
+ /// CHECK-START-X86_64: java.lang.Long DivTest.$noinline$LongDivByMinus2(long) disassembly (after)
+ /// CHECK-NOT: cmovnl/geq
+ /// CHECK: addq
private static Long $noinline$LongDivByMinus2(long v) {
long r = v / -2;
return r;