JDK-8189172 : Math.pow(base, 2.0) still broken.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u144
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2017-10-11
  • Updated: 2018-01-26
Related Reports
Relates :  
Relates :  
Relates :  
Description
The following program demonstrates that the x * x optimization when exp == 2 is still broken for jdk-8 (it is fixed on jdk-9):

public class PowTest { 

    public static void main(final String[] args) { 
        double b = 1.0 / 3.0;
        double e = 2.0;
        double r = Math.pow(b, e);
        double n = b * b;
        // Find a base where pow(b, 2) != b * b
        while (r == n) {
                b += 1.0 / 3.0;
                n = Math.pow(b, e);
                r = b * b;
        }
        System.out.println("found b=" + b + " n=" + n + " r=" + r);
        r = n = Math.pow(b, e);
        // Wait until pow gets compiled into x * x
        while (r == n) {
                n = Math.pow(b, e);
        }
        System.out.println("bad b=" + b + " n=" + n + " r=" + r);
    } 
}

Please fix it (it is causing us a lot of pain to have to deal with the same code producing different numeric results on each run). It would be nice at some point to require in the language that intrinsic math functions produce the same exact results when interpreted and compiled.
Comments
Through JDK-8063086 added corresponding special case (exp == 2.0) for interpreter & c1 (see MacroAssembler::pow_or_exp), the machine code is still different (x87 vs SSE/AVX): 0x00007fc8dd237104: fmul %st(0),%st vs 0x00007fc35916742c: mulsd %xmm0,%xmm0 # SSE or 0x00007fe4fd19606c: vmulsd %xmm0,%xmm0,%xmm0 # AVX
18-10-2017

Special case for exp == 2.0 was added by JDK-8029302 to fix a performance regression.
18-10-2017

Math.pow intrinsic implementation was rewritten in 9 (see JDK-8145688).
18-10-2017