Does UseFPUForSpilling intend to spill a GPR to XMM?
Nils Eliasson
nils.eliasson at oracle.com
Tue Oct 19 07:52:20 UTC 2021
Hi Liu,
You had a lot of questions - I'll try to answer a few of them:
Yes, UseFPUForSpilling use XMM registers in the C2 compiler. On 64 bit
x86, SSE2 is the minimum requirement. x87 has never been used for spilling.
C2 should work fine on 32 bit x86. Have a look at
"os::is_server_class_machine()" - if the machine you are running on
doesn't meet some criteria - a quick-only-mode (c1) will be used. There
are a flag - "NeverActAsServerClassMachine" - you can use two control
this behavior.
C2 handles the spilling to XMM register as a part of normal register
allocation - so any clobbering should be handled. I don't recall the
windows 32-bit calling convention - I need to refresh my memory on that.
Can you reproduce a failure?
Regards,
Nils Eliasson
On 2021-10-19 03:04, Liu, Xin wrote:
> Hello, Experts,
>
> We recently encounter an ABI issue of XMM0. Even though it only happens
> on jdk8u windows x86(32bits) so far, it raises my concern about
> 'UseFPUForSpilling' for both x86 and x86_64. Does UseFPUForSpilling
> intend to spills GPR to XMM registers? I come from JDK-6978249, but I
> can't the original webrev.
>
> I don't think XMM registers are saved across function calls in any ABIs.
> Only XMM6-XMM15 are saved by the callee on Microsoft platforms.
> https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160#callercallee-saved-registers
>
> If nobody saves XMM0~3, how come C2 register allocation uses them as
> spilling destination? It seems possible on AMD64 as well, but it's rarer
> than x86 given the fact AMD64 has more GPRs.
> https://github.com/openjdk/jdk/blob/master/src/hotspot/cpu/x86/x86_64.ad#L1388
>
> eg. This is what I have seen on Windows x86.
> 07c B10: # B26 B11 <- B9 Freq: 0.999992
> 07c movdl XMM0, EBX # spill (xliu: EBX store an OOP)
> 080 MOV [ESP + #20],EDI
> 084 MOV EBX,[ECX + #136] ! Field:
> java/awt/Component.componentOrientation
> 08a TEST EBX,EBX
> 08c Je B26 P=0.000001 C=-1.000000
>
> ----
>
> 170 B16: # B40 B17 <- B15 B24 Freq: 0.999991
> 170 movdl EBX, XMM0 # spill
> 174 MOV EBX,[EBX + #56] ! Field: javax/swing/plaf/basic
> /BasicSliderUI.thumbRect (xliu: segment fault here EBX=0)
> 177 MOV EDI,[EBX + #16] # int ! Field: java/awt/Rectangle.width
> 17a NullCheck EBX
>
> Between BB10 and BB16, the control goes to convD2I_reg_reg, which calls
> SharedRuntime::d2l in the slow path. XMM0 is used as return value, so it
> is clobbered.
>
> So the FPU of 'UseFPUForSpilling' doesn't just refer to intel x87 but
> also include SSE/AVX units, right? If it does intend to use X/Y/ZMM
> registers as Spilling destination, is there any mechanism to protect
> them from runtime calls on x86/x86_64? In both System V and Microsoft
> ABIs, XMM0~3 could be used for both argument passing and return value,
> right?
>
> I see other runtime code stubs such as arraycopy and crc32 use XMM
> registers.
>
> Btw, there's a hidden mechanism somewhere which prevents c2 from working
> on x86_32. Even thought I has a server VM of jdk17, it only uses c1 to
> compile methods. Could you tell me what it is?
>
> Thanks,
> --lx
>
More information about the hotspot-compiler-dev
mailing list