JDK-8234617 : C1: Incorrect result of field load due to missing narrowing conversion
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10,11,12,13,14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-11-22
  • Updated: 2020-07-29
  • Resolved: 2019-12-03
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 11 JDK 13 JDK 14 Other
11.0.7-oracleFixed 13.0.4Fixed 14 b26Fixed openjdk8u272Fixed
Description
jittester-generated test fails with
STDERR:
java.lang.RuntimeException: Actual stderr isn't equal to golden one: expected java.lang.NumberFormatException
 to equal java.lang.ArithmeticException

To reproduce the issue it is needed to download all attached files in hotspot regression tests, saying compiler/jittester and run
bash jib.sh make -- run-test JTREG_RETAIN=all TEST=compiler/jittester

Comments
Fix Request [8u] The patch fixes C1 bug which can lead to data corruption. Webrev http://cr.openjdk.java.net/~snazarki/jdk8u-dev-webrev/8234617/ Mail thread (approved by phh) http://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-June/011910.html
09-06-2020

Fix Request (13u) The reasons are the same as for 11u. The patch applies cleanly, passes tier1. New test shows regression without the patch.
28-05-2020

Fix Request (11u) This patch eliminates the C1 bug, and keeps codebases in sync (I see 11.0.7-oracle). The patch applies cleanly to 11u, passes tier1, tier2 tests. New regression test fails without the patch, passes with it. Risk is medium-low, as it introduces new (correct) conversions on frequent paths.
13-01-2020

[~dlong] Do you mean something like this (narrowing from long to int)? public Method testLong:"(J)J" stack 5 locals 4 { aload_0; lload_1; putfield Field intFld:"I"; aload_0; getfield Field intFld:"I"; lreturn; } That fails in the verifier: java.lang.VerifyError: Bad type on operand stack Exception Details: Location: compiler/conversions/Conversion.testLong(J)J @2: putfield Reason: Type long_2nd (current frame, stack[2]) is not assignable to integer Current Frame: bci: @2 flags: { } locals: { 'compiler/conversions/Conversion', long, long_2nd } stack: { 'compiler/conversions/Conversion', long, long_2nd } Bytecode: 0000000: 2a1f b500 012a b400 01ad
06-01-2020

[~thartmann] I noticed the test and patch only handle "int" fields. What happens if the field being narrowed is of type "long"?
02-01-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/90f3ea9785d5 User: thartmann Date: 2019-12-03 07:29:45 +0000
03-12-2019

Writing an (integer) value to a boolean, byte, char or short field includes an implicit narrowing conversion [1]. With -XX:+EliminateFieldAccess (default), C1 tries to omit field loads by caching and reusing the last written value. The problem is that this value is not necessarily converted to the field type and we end up using an incorrect value. For example, for the field store/load in testShort, C1 emits: [...] 0x00007f0fc582bd6c: mov %dx,0x12(%rsi) 0x00007f0fc582bd70: mov %rdx,%rax [...] The field load has been eliminated and the non-converted integer value (%rdx) is returned. The fix is to emit an explicit conversion to get the correct field value after the write: [...] 0x00007ff07982bd6c: mov %dx,0x12(%rsi) 0x00007ff07982bd70: movswl %dx,%edx 0x00007ff07982bd73: mov %rdx,%rax [...] http://cr.openjdk.java.net/~thartmann/8234617/webrev.00/ [1] https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-6.html#jvms-6.5.putfield
28-11-2019

Thanks Igor, I can reproduce and see how far I get with the bytecode version.
26-11-2019

this test doesn't have .java files (other than jtreg test description), this is a "bytecode" jittester test, meaning jittester spun test's bytecode itself. you might try to generate the equivalent java version using the same 'seed' and 'specificSeed' values and check if it fails, but I am not sure if such generation can be easily done w/o small hacking of jittester code.
26-11-2019

Where can I get the .java files from?
26-11-2019

ILW = Incorrect execution of compiled code, single generated test with -Xcomp, no workaround (but disable compilation) = HLM = P3
26-11-2019

I verified what Test_58 pass when -Xcomp is removed.
22-11-2019