Skip to content

Commit

Permalink
8190869: C2: missing strength reduction of Math.pow(x, 2.0D) to x*x
Browse files Browse the repository at this point in the history
Reviewed-by: kvn
  • Loading branch information
vlivanov committed Dec 13, 2017
1 parent b10bf29 commit c7bd76c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
13 changes: 13 additions & 0 deletions src/hotspot/cpu/x86/macroAssembler_x86_pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,11 @@ ALIGNED_(8) juint _log2_pow[] =
0xfefa39efUL, 0x3fe62e42UL, 0xfefa39efUL, 0xbfe62e42UL
};

ALIGNED_(8) juint _DOUBLE2[] =
{
0x00000000UL, 0x40000000UL
};

//registers,
// input: xmm0, xmm1
// scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
Expand Down Expand Up @@ -803,13 +808,21 @@ void MacroAssembler::fast_pow(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xm
address HIGHMASK_LOG_X = (address)_HIGHMASK_LOG_X;
address HALFMASK = (address)_HALFMASK;
address log2 = (address)_log2_pow;
address DOUBLE2 = (address)_DOUBLE2;


bind(start);
subq(rsp, 40);
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);
Expand Down
15 changes: 12 additions & 3 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1789,10 +1789,19 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
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
Expand Down

0 comments on commit c7bd76c

Please sign in to comment.