8190869: C2: missing strength reduction of Math.pow(x, 2.0D) to x*x
Reviewed-by: kvn
--- a/src/hotspot/cpu/x86/macroAssembler_x86_pow.cpp Wed Dec 13 07:14:18 2017 -0500
+++ b/src/hotspot/cpu/x86/macroAssembler_x86_pow.cpp Wed Dec 13 19:32:48 2017 +0300
@@ -765,6 +765,11 @@
0xfefa39efUL, 0x3fe62e42UL, 0xfefa39efUL, 0xbfe62e42UL
};
+ALIGNED_(8) juint _DOUBLE2[] =
+{
+ 0x00000000UL, 0x40000000UL
+};
+
//registers,
// input: xmm0, xmm1
// scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
@@ -803,6 +808,7 @@
address HIGHMASK_LOG_X = (address)_HIGHMASK_LOG_X;
address HALFMASK = (address)_HALFMASK;
address log2 = (address)_log2_pow;
+ address DOUBLE2 = (address)_DOUBLE2;
bind(start);
@@ -810,6 +816,13 @@
movsd(Address(rsp, 8), xmm0);
movsd(Address(rsp, 16), xmm1);
+ // Special case: pow(x, 2.0) => x * x
+ movdq(tmp1, xmm1);
+ cmp64(tmp1, ExternalAddress(DOUBLE2));
+ jccb(Assembler::notEqual, B1_2);
+ mulsd(xmm0, xmm0);
+ jmp(B1_5);
+
bind(B1_2);
pextrw(eax, xmm0, 3);
xorpd(xmm2, xmm2);
--- a/src/hotspot/share/opto/library_call.cpp Wed Dec 13 07:14:18 2017 -0500
+++ b/src/hotspot/share/opto/library_call.cpp Wed Dec 13 19:32:48 2017 +0300
@@ -1789,10 +1789,19 @@
return StubRoutines::dexp() != NULL ?
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
- case vmIntrinsics::_dpow:
- return StubRoutines::dpow() != NULL ?
- runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
+ case vmIntrinsics::_dpow: {
+ Node* exp = round_double_node(argument(2));
+ const TypeD* d = _gvn.type(exp)->isa_double_constant();
+ if (d != NULL && d->getd() == 2.0) {
+ // Special case: pow(x, 2.0) => x * x
+ Node* base = round_double_node(argument(0));
+ set_result(_gvn.transform(new MulDNode(base, base)));
+ return true;
+ }
+ return StubRoutines::dexp() != NULL ?
+ runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
+ }
#undef FN_PTR
// These intrinsics are not yet correctly implemented