JDK-8072753 : Nondeterministic wrong answer on arithmetic
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6.0,6,7,8,8u20,8u31,8u40,9
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-02-06
  • Updated: 2017-08-10
  • Resolved: 2015-02-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9 Other
7u101Fixed 8u60Fixed 9 b53Fixed openjdk7uFixed
Related Reports
Relates :  
Sub Tasks
JDK-8143556 :  
JDK-8143560 :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)


FULL OS VERSION :
Linux laptopi 3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:36:28 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Linux thinkpad 3.18.5-1-ARCH #1 SMP PREEMPT Fri Jan 30 07:31:50 CET 2015 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
A code containing only simple arithmetic (generated using deterministic pseudorandom) randomly gives different results, even though it should be deterministic.


THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

REGRESSION.  Last worked in version 7u75

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the code as code.java
2. Compile the code
    $ javac code.java
3. Run the code repeatedly, observing the changes in output, for example
    $ for i in {1..100}; do java code | sha256sum; done


EXPECTED VERSUS ACTUAL BEHAVIOR :
All the invocations of "java code" should output the same output with sha256 hash 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838.

However, actual result contains many different outputs, like
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
0f2175f5f25089d63426ccf42b4e082cb51ad760c5a8534c764f8792c0ca46f4  -
c4a0bf7126460fd6ee02999121ec9a2d90c05b9bf27070d78de9a7605b4694e6  -
dc66d58743810f6a000d1ab4694b98eac85dcb4dffd99dfd43a6260b508ab007  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
a857ae2566df12c396990cb36828d646eb34c5e548e3c7f2af91e23782c5805e  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
d3bb7a3e570e4a8d0a7ae1fd3e6fccad4fbe8495b56ff08fdfbde70e00f19622  -
a82888399f7f4544e4ec230cf1b3e7b53ecc6571422b5e17b5b685ff9e655c79  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
a857ae2566df12c396990cb36828d646eb34c5e548e3c7f2af91e23782c5805e  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
c322caa467fcdd0e70519760c123b8fcf167e6cfdf98f648316f4e729643d77b  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
a857ae2566df12c396990cb36828d646eb34c5e548e3c7f2af91e23782c5805e  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
9c6eb5a688d7c78b9260baac02adf4720f0590b442c7d4ce5be64c755d66b5b7  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
d113cb8865e399499ae18a19bfd494b461a403fa7a5ff2fb30ad59c0ee575f91  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
0f2175f5f25089d63426ccf42b4e082cb51ad760c5a8534c764f8792c0ca46f4  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838  -
...
REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.util.*;
import java.io.*;
class code {
    public static void main(String[] args) {
        Random r = new Random(42);
        int x = 0;
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < 1000000; ++i) {
            int v = Math.abs(r.nextInt());
            sb.append('+').append(v).append('\n');

            x += v;
            while(x < 0) x += 1000000000;
            sb.append('=').append(x).append('\n');
        }
        System.out.println(sb.toString());
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use -Xint.


Comments
[~mcastegr], could you guys please backport this to 6 and 7?
20-02-2015

Removing the regression label as this has happened since 6 at least
20-02-2015

Sometimes when we try to do the counter loop detection during OSRs we get a non-canonical loop shape (while-do), in which case we would try to invert it (convert it to do-while). Specifically the following transformation takes place: i = init; while(i < limit) { i+= stride; } is converted to i = init; do { i+= stride; } while(i < limit+stride); Note that the loop condition check occurs _after_ the induction variable is incremented. And, as a result, (i + stride) can overflow. There are two solutions possible: - check the type of init, which in most cases will be tight enough to make a proper decision (also the check is only require when the inversion takes place). - insert extra predicate to guard for the condition. Since the described case is rare (OSR only) and the fix needs to be backported down to 6 (which doesn���t have predicates) I decided to go the first route for now. The benchmark runs didn���t show any change in performance. Webrev: http://cr.openjdk.java.net/~iveresov/8072753/webrev.00/
19-02-2015

sqe is ok to deferr it to 8u60.
16-02-2015

Justification for 8u40 deferral: - very rare problem that has been there from the start - has a chance to occur only during OSRs - the loop has to have huge stride values and/or huge initial values - will fix in next release
16-02-2015

Yes the OSR point 62 is the guilty one. Adding x = 923301921 and new v = 873041814 gives correct result but jumps to less than zero in error. Changing: "while(x < 0) {" to: "while((x & 0x80000000)!= 0) {" Removes the bug. It looks like some transform of the loop to a series of arithmetic ops that goes wrong when OSRing.
12-02-2015

6.0 is affected too ./6.0/bin/java -version java version "1.6.0-fastdebug" Java(TM) SE Runtime Environment (build 1.6.0-fastdebug-b105) Java HotSpot(TM) Server VM (build 1.6.0-fastdebug-b105-debug, mixed mode) ./6.0/bin/java -XX:+TieredCompilation code | sha256sum 34eedbbd3b47ff442c4ed98f6cac2f1162f9bff688c03ff45a37994f11042bcf - bash-4.1$ ./6.0/bin/java -XX:+TieredCompilation code | sha256sum 76d60c9487f9221a13227bb63c43a326e7f4494c58c3799f8b890720d6184b6f -
12-02-2015

7.0 is affected as well $ java -version java version "1.7.0-fastdebug" Java(TM) SE Runtime Environment (build 1.7.0-fastdebug-b147) Java HotSpot(TM) Server VM (build 21.0-b17-fastdebug, mixed mode) $ java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | sha256sum 1f0dec0f5450c500fce23c7053b46a3396d1cf95944c9019f73d33994b393459 - $ java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | sha256sum 3fa498488000f2182a7ae1f9e03a6456bf9a128a70afa1a923619ec197b18a3e -
12-02-2015

1.7.0_80 is also affected $ java -version java version "1.7.0_80-fastdebug" Java(TM) SE Runtime Environment (build 1.7.0_80-fastdebug-b09) Java HotSpot(TM) Server VM (build 24.80-b10-fastdebug, mixed mode) $ java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | sha256sum 18e9a22eb1b012dced1b99b630fd7256b91eb9f5840ef77155f97e26eb2f9fff - $ java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | sha256sum 807a52f69d7e20df5835f8953f21380642ea389327b4324c10ee071b769a95ba -
12-02-2015

This doesn't seem to be related to tiered. It looks like C2. There are 2 possible OSR points in main(): 24 and 62. OSRing at 24 is fine and seems to yield correct result: ../hs-comp/build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle/jdk1.9.0.jdk/Contents/Home/bin/java -Xint code | gsha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - ../hs-comp/build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle/jdk1.9.0.jdk/Contents/Home/bin/java -XX:-TieredCompilation -XX:OSROnlyBCI=24 code | gsha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - OSRing at 62 produces random results each time: ../hs-comp/build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle/jdk1.9.0.jdk/Contents/Home/bin/java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | gsha256sum 830ee7b479cd51c415a0ce6c84963125ea3eb592811613d847f890619e44ffc3 - ../hs-comp/build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle/jdk1.9.0.jdk/Contents/Home/bin/java -XX:-TieredCompilation -XX:OSROnlyBCI=62 code | gsha256sum e28e2039e6a14e9a290d7bd635be2955bbf153526306fe06c3e42af2df520b3d -
12-02-2015

Workaround: -XX:-UseOnStackReplacement works in product. May cause perf regression when profiled C1 code cant be replaced by C2 code or non-profiled C1 code.
12-02-2015

For 8b132 for i in {1..100}; do $JAVA_HOME/bin/java code | sha256sum; done gives 571c71de859f9a25bc369a7453b8b5066f2520b325c2a0c75f9c9cf7f7a282b0 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - cfcb49785e61c6d265c6c97bb4c3fab021cc5e6168e4e5b6ad0d9b8c145e9bbc - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - e038229b3e30274df0b2843f42c1938fb50cbc15b381206a913f1990326acd82 - ^C for 8u20b32 e90a606b9a131056410b7577190df85742e5ac926dbe02a97825d8d12eff5d74 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 64d44a6dbf0fb7b51bde5e780a0e964d4148a792687459a4e91172dde2e62343 - e44ae66ce14ff6ccad336c2dd3126866bfb643d198c752225ad292c477f9ad92 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 0d7925ad6f7c1f149dcbe2e8a98253623326d3992457862fe22fc043969c153a - ^C 7u75b05 linux-x64 is ok. All SHA hashes are same. 8u20 on Solaris Sparcv9 gives for i in {1..100}; do ./jdk1.8.0_20/bin/java code | sha256sum; done 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 183d4b0e10c53c5231aa3da9960aa8fe86fbece8b353ada3fac218ef67066564 - 805e9c2770cc22538694035a5044e929dad32efbfead3a9fc17c39d389d5818a - 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - 15ad71877c1ad97c7cd7c88ef53f94f42b2a6982ebdff3b6bf44c4ea533e9491 - ^C 8u20 on Windows Server 2008 R2 Enterprise has same issue
11-02-2015

Can someone verify this bug on 8u20 or even 8 GA?
11-02-2015

Extracting the inner loop makes the problem go away. OSR bug? Validated that all code have been inlined so there is no c1/c2 calls.
11-02-2015

Turning off tiered seem to work. So just c1 is ok, and just c2 is ok.
11-02-2015

it's caused by string concat. optmization: java -XX:+TieredCompilation -XX:-OptimizeStringConcat code | sha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - it appears that it isn't java -XX:+TieredCompilation -XX:-OptimizeStringConcat code | sha256sum 9d8909c4a90222aede36476f1d2c4d2a8829a41945c8e78232de9d4cc8cf95a4 - java -XX:+TieredCompilation -XX:-OptimizeStringConcat code | sha256sum 952e50cc02903274727db1ae63710fc81adb798f3a491392fe396383458f8b2f - java -XX:+TieredCompilation -XX:-OptimizeStringConcat code | sha256sum 74d1ff2b29fa0a4634342515b3716941a2d42918be8d803d98d64cededa4469e -
11-02-2015

ILW=Compiler generating wrong code, reproducible but not seen widely, none known so far=HMH=P1
11-02-2015

looks like a problem somewhere in OSR w/ enabled tiered: java -XX:-TieredCompilation code | sha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - java -XX:+TieredCompilation -XX:TieredStopAtLevel=3 code | sha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - java -XX:+TieredCompilation -XX:TieredStopAtLevel=1 code | sha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - java -XX:+TieredCompilation -XX:TieredStopAtLevel=4 -XX:CIStopOSR=0 -XX:+CICountOSR code | sha256sum 629dbc538b4aa4fd16ecaefbf9cfcba1fe5910aec75740a84583dda03f044838 - java -XX:+TieredCompilation -XX:TieredStopAtLevel=4 code | sha256sum bac5b2172de01652ba080ecc80129531eb0fd6408ac461419c6143c993594115 -
11-02-2015

Looks like a compiler issue, especially since it doesn't reproduce with -Xint
10-02-2015