JDK-8051805 : C2: MachTemp nodes not always in same block as their "use" node
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2014-07-23
  • Updated: 2022-07-01
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.
Other
tbdUnresolved
Related Reports
Relates :  
Description
In PhaseCFG::schedule_late(), there is code to keep MachTemp nodes in the same
block as their use, and in PhaseCFG::select() there is more code to keep MachTemp
nodes near their use.  However, the MachTemp can still end up in a different block
from it use (call_catch_cleanup() is one function that can cause this.)

Since a MachTemp node doesn't actually emit any code, the register allocation for
it hasn't actually been initialized until the use node.  Normally this is harmless,
but if the MachTemp is RegN, then any safepoint between the MachTemp and use
will add that RegN to the safepoint oopmap, which is fatal because the value is
uninitialized.  Even if the MachTemp is not a RegN, having the MachTemp far away
from its use unnecessarily extends the live range of the register.

A possible fix for the general case would be to make sure that MachTemp
nodes are always placed just above their use in the same block.

A workaround for just the RegN case could be to treat RegN as RegI for MachTemp nodes.

To reproduce this problem, add a RegN TEMP to a rule like LoadN, CompareAndSwapN,
or GetAndSetN.  If the safepoint is a call, then it needs to be a platform that has
"never-save" (NS) registers that can stay live across a call.  But if the safepoint is a poll,
then probably any platform would be affected.

Comments
I can still reproduce a problem with RegN temp registers. If an instruction like LoadN uses a RegN temp register, that register can end up in the oopmap of a safepoint. I'm not sure why that happens, because the value should be dead after the LoadN. Because the value is in the oopmap, it must have a valid oop value. Setting the register to a trash value triggers crashes when scanning the oopmap. The attached aarch64.patch and x86_64.patch demonstrate the problem on their respective platforms.
01-07-2022

L(non-optimal cpu registers usage, wrong live range)H(C2 generated code, common cases)H(none) = P4
11-04-2016