You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JIT: Model GT_RETURN kills with contained operand (#111230)
When `GT_RETURN` has a contained operand (due to returning a DNER
local), it will load the ABI return registers directly from stack. This
will kill those registers. However, nothing was modelling this kill.
This was noticed while trying to ensure that GC information is correctly
marked in codegen when going into epilogs. However, this is potential
bad codegen even on its own: before this change LSRA might not properly
spill locals that are required to be live around a `GT_RETURN` node even
if they are getting killed by the `GT_RETURN`. A concrete case was seen
in `<StartupCode$FSharp-Core>.$Tasks+Using@148-5[System.__Canon]:Invoke`
under JitStressRegs=2, where the VM requests that the JIT keep "this"
alive throughout the function. Before this change we get the following
codegen:
```asm
G_M51753_IG05: ; bbWeight=0.50, gcVars=0000000000000000 {}, gcrefRegs=0002 {x1}, byrefRegs=0000 {}, gcvars, byref
; gcrRegs -[x0] +[x1]
; GC ptr vars -{V00}
stp xzr, xzr, [fp, #0x38]
ldp x0, x1, [fp, #0x38] // [V04 loc2], [V04 loc2+0x08]
; gcrRegs -[x1] +[x0]
;; size=8 bbWeight=0.50 PerfScore 2.00
```
where "this" is in `x1` going into the block, and gets overridden by
the return without being available somewhere else. After this change,
the codegen becomes
```asm
G_M51753_IG05: ; bbWeight=0.50, gcVars=0000000000000000 {}, gcrefRegs=0002 {x1}, byrefRegs=0000 {}, gcvars, byref
; gcrRegs -[x0] +[x1]
; GC ptr vars -{V00}
str x1, [fp, #0x20] // [V00 this]
; GC ptr vars +{V00}
stp xzr, xzr, [fp, #0x38]
ldp x0, x1, [fp, #0x38] // [V04 loc2], [V04 loc2+0x08]
; gcrRegs -[x1] +[x0]
;; size=12 bbWeight=0.50 PerfScore 2.50
```
0 commit comments