JDK-8213419 : C2 may hang in MulLNode::Ideal()/MulINode::Ideal() with gcc 8.2.1
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10,11,12
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-11-06
  • Updated: 2021-02-01
  • Resolved: 2018-11-21
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 12 Other
11.0.3Fixed 12 b21Fixed openjdk8u212Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Multiplications by constant Integer.MIN_VALUE or Long.MIN_VALUE cause C2 to hang in MulLNode::Ideal()/MulINode::Ideal() when hotspot is compiled with gcc 8.2.1. 

The hang itself happens in inlined function:

// Returns largest i such that 2^i <= x.
// If x < 0, the function returns 31 on a 32-bit machine and 63 on a 64-bit machine.
// If x == 0, the function returns -1.
inline int log2_intptr(intptr_t x) {
  int i = -1;
  uintptr_t p = 1;
  while (p != 0 && p <= (uintptr_t)x) {
    // p = 2^(i+1) && p <= x (i.e., 2^(i+1) <= x)
    i++; p *= 2;
  }
  // p = 2^(i+1) && x < p (i.e., 2^i <= x < 2^(i+1))
  // If p = 0, overflow has occurred and i = 31 or i = 63 (depending on the machine word size).
  return i;
}

Looking at the assembly code p != 0 is optimized out.

   0x00007f6494aae685 <+1157>:  mov    $0xffffffff,%ecx
   0x00007f6494aae68a <+1162>:  mov    (%rax),%rdi
   0x00007f6494aae68d <+1165>:  mov    $0x1,%eax
   0x00007f6494aae692 <+1170>:  nopw   0x0(%rax,%rax,1)
   0x00007f6494aae698 <+1176>:  add    %rax,%rax
   0x00007f6494aae69b <+1179>:  add    $0x1,%ecx
   0x00007f6494aae69e <+1182>:  cmp    %r14,%rax
   0x00007f6494aae6a1 <+1185>:  jbe    0x7f6494aae698 <MulINode::Ideal(PhaseGVN*, bool)+1176>

That call is preceded by:

if( con < 0 ) {
  con = -con;
}

which is undefined behavior for INT_MIN so the compiler is free to assume con != INT_MIN and then optimizing the p != 0 test is legal.
Comments
Fix Request This bug may cause a hang of c2 compiler threads when the jdk is built with a recent version of gcc. The fix (together with follow up JDK-8214206) reworks code with undefined behavior from hotspot. I verified that backport of this + JDK-8214206 builds on x86 (32 and 64 bits) and aarch64. Patch applies cleanly.
01-02-2019

This fix is also broken on 32-bit: jib > /scratch/opt/mach5/mesos/work_dir/slaves/2dd962d0-8988-479b-a804-57ab764ada59-S1332/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/04d9a174-ce03-43b6-93a6-849d86569c65/runs/3885c68c-93b9-40fc-a119-0fef0231a1fe/workspace/open/src/hotspot/share/utilities/globalDefinitions.hpp:1067:12: error: redefinition of 'int log2_intptr(int)' jib > inline int log2_intptr(int x) { jib > ^~~~~~~~~~~ jib > /scratch/opt/mach5/mesos/work_dir/slaves/2dd962d0-8988-479b-a804-57ab764ada59-S1332/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/04d9a174-ce03-43b6-93a6-849d86569c65/runs/3885c68c-93b9-40fc-a119-0fef0231a1fe/workspace/open/src/hotspot/share/utilities/globalDefinitions.hpp:1063:12: note: 'int log2_intptr(intptr_t)' previously defined here jib > inline int log2_intptr(intptr_t x) { jib > ^~~~~~~~~~~ jib > /scratch/opt/mach5/mesos/work_dir/slaves/2dd962d0-8988-479b-a804-57ab764ada59-S1332/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/04d9a174-ce03-43b6-93a6-849d86569c65/runs/3885c68c-93b9-40fc-a119-0fef0231a1fe/workspace/open/src/hotspot/share/utilities/globalDefinitions.hpp: In function 'int log2_intptr(uint)': jib > /scratch/opt/mach5/mesos/work_dir/slaves/2dd962d0-8988-479b-a804-57ab764ada59-S1332/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/04d9a174-ce03-43b6-93a6-849d86569c65/runs/3885c68c-93b9-40fc-a119-0fef0231a1fe/workspace/open/src/hotspot/share/utilities/globalDefinitions.hpp:1071:12: error: redefinition of 'int log2_intptr(uint)' jib > inline int log2_intptr(uint x) { jib > ^~~~~~~~~~~ jib > /scratch/opt/mach5/mesos/work_dir/slaves/2dd962d0-8988-479b-a804-57ab764ada59-S1332/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/04d9a174-ce03-43b6-93a6-849d86569c65/runs/3885c68c-93b9-40fc-a119-0fef0231a1fe/workspace/open/src/hotspot/share/utilities/globalDefinitions.hpp:1037:12: note: 'int log2_intptr(uintptr_t)' previously defined here jib > inline int log2_intptr(uintptr_t x) { jib > ^~~~~~~~~~~ Filed: JDK-8214206
22-11-2018

From the stacktrace: at compiler.intrinsics.mathexact.MulExactLConstantTest.main(MulExactLConstantTest.java:39) It continues to fail regularly so we will need to ProblemList it. Bug JDK-8214189 was filed for this.
22-11-2018

[~roland] compiler/intrinsics/mathexact/MulExactLConstantTest.java
21-11-2018

What test is this?
21-11-2018

Is it coincidence that after this push we see a failure on Windows: java.lang.RuntimeException: Intrinsic version [multiplyExact]didn't throw exception, NonIntrinsic version threw for: 9223372036854775807 + 1 at compiler.intrinsics.mathexact.Verify.verifyResult(Verify.java:68) at compiler.intrinsics.mathexact.Verify.verifyBinary(Verify.java:142) at compiler.intrinsics.mathexact.Verify$ConstantLongTest.verify(Verify.java:249) at compiler.intrinsics.mathexact.MulExactLConstantTest.main(MulExactLConstantTest.java:39) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at com.sun.javatest.regtest.agent.MainActionHelper$AgentVMRunnable.run(MainActionHelper.java:246) at java.base/java.lang.Thread.run(Thread.java:835)
21-11-2018

This code is very old, adding corresponding affects versions. ILW = Endless loop in C2 compiler, rare with newer/unsupported gcc versions [1], use supported gcc version = HLM = P3 [1] https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms
06-11-2018