Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8265940: Enable C2's optimization for Math.pow(x, 0.5) on all platforms #3755

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
@@ -2516,6 +2516,8 @@ ATTRIBUTE_ALIGNED(16) juint _static_const_table_pow[] =
};

ATTRIBUTE_ALIGNED(8) double _DOUBLE2 = 2.0;
ATTRIBUTE_ALIGNED(8) double _DOUBLE0 = 0.0;
ATTRIBUTE_ALIGNED(8) double _DOUBLE0DOT5 = 0.5;

//registers,
// input: xmm0, xmm1
@@ -2540,12 +2542,14 @@ void MacroAssembler::fast_pow(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xm
Label L_2TAG_PACKET_48_0_2, L_2TAG_PACKET_49_0_2, L_2TAG_PACKET_50_0_2, L_2TAG_PACKET_51_0_2;
Label L_2TAG_PACKET_52_0_2, L_2TAG_PACKET_53_0_2, L_2TAG_PACKET_54_0_2, L_2TAG_PACKET_55_0_2;
Label L_2TAG_PACKET_56_0_2, L_2TAG_PACKET_57_0_2, L_2TAG_PACKET_58_0_2, start;
Label L_NOT_DOUBLE2;
Label L_NOT_DOUBLE2, L_NOT_DOUBLE0DOT5;

assert_different_registers(tmp, eax, ecx, edx);

address static_const_table_pow = (address)_static_const_table_pow;
address DOUBLE2 = (address) &_DOUBLE2;
address DOUBLE0 = (address) &_DOUBLE0;
address DOUBLE0DOT5 = (address) &_DOUBLE0DOT5;

bind(start);
subl(rsp, 120);
@@ -2562,6 +2566,19 @@ void MacroAssembler::fast_pow(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xm
jmp(L_2TAG_PACKET_21_0_2);

bind(L_NOT_DOUBLE2);
// Special case: pow(x, 0.5) => sqrt(x)
ucomisd(xmm1, ExternalAddress(DOUBLE0DOT5)); // For pow(x, y), check whether y == 0.5
jccb(Assembler::notEqual, L_NOT_DOUBLE0DOT5);
jccb(Assembler::parity, L_NOT_DOUBLE0DOT5);
ucomisd(xmm0, ExternalAddress(DOUBLE0));
// According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
// So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
// -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
jccb(Assembler::belowEqual, L_NOT_DOUBLE0DOT5); // pow(x, 0.5) => sqrt(x) only for x > 0.0

This comment has been minimized.

Loading
@vnkozlov

vnkozlov Apr 28, 2021
Contributor

Add comment about why 0. case is skipped: -0.0 case.

This comment has been minimized.

Loading
@DamonFool

DamonFool Apr 28, 2021
Author Member

Add comment about why 0. case is skipped: -0.0 case.

Thanks @vnkozlov for your review.

Comments have been added.
Thanks.

sqrtsd(xmm0, xmm0);
jmp(L_2TAG_PACKET_21_0_2);

bind(L_NOT_DOUBLE0DOT5);
xorpd(xmm2, xmm2);
movl(eax, 16368);
pinsrw(xmm2, eax, 3);
@@ -1643,9 +1643,7 @@ bool LibraryCallKit::inline_math_pow() {
Node* base = round_double_node(argument(0));
set_result(_gvn.transform(new MulDNode(base, base)));
return true;
}
#if defined(X86) && defined(_LP64)
else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
} else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {

This comment has been minimized.

Loading
@vnkozlov

vnkozlov Apr 28, 2021
Contributor

Add the same comment at line #1654 explaining why 0. is excluded.

// Special case: pow(x, 0.5) => sqrt(x)
Node* base = round_double_node(argument(0));
Node* zero = _gvn.zerocon(T_DOUBLE);
@@ -1654,6 +1652,9 @@ bool LibraryCallKit::inline_math_pow() {
Node* phi = new PhiNode(region, Type::DOUBLE);

Node* cmp = _gvn.transform(new CmpDNode(base, zero));
// According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
// So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
// -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
Node* test = _gvn.transform(new BoolNode(cmp, BoolTest::le));

Node* if_pow = generate_slow_guard(test, NULL);
@@ -1684,7 +1685,6 @@ bool LibraryCallKit::inline_math_pow() {

return true;
}
#endif // defined(X86) && defined(_LP64)
}

return StubRoutines::dpow() != NULL ?
@@ -23,9 +23,8 @@

/*
* @test
* @bug 8265325
* @bug 8265325 8265940
* @summary test the optimization of pow(x, 0.5)
* @requires os.arch=="amd64" | os.arch=="x86_64"
* @run main/othervm TestPow0Dot5Opt
* @run main/othervm -Xint TestPow0Dot5Opt
* @run main/othervm -Xbatch -XX:TieredStopAtLevel=1 TestPow0Dot5Opt