Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 ```
- Loading branch information