diff options
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 29 | ||||
| -rw-r--r-- | test/411-checker-hdiv-hrem-pow2/src/DivTest.java | 12 |
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; |