Account for CORINFO_HELP_VIRTUAL_FUNC_PTR in GT_LABEL; avoid double resolving (#87395)
authorJakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Mon, 12 Jun 2023 21:25:19 +0000 (23:25 +0200)
committerGitHub <noreply@github.com>
Mon, 12 Jun 2023 21:25:19 +0000 (23:25 +0200)
commit98926e2b4922e752292fea4387bda49153069f54
tree2a18256acf5ea9bfcdc4f808405f8d347a9aff85
parent4315b52bf6b866ad56631ee3a252b3327d8a174c
Account for CORINFO_HELP_VIRTUAL_FUNC_PTR in GT_LABEL; avoid double resolving (#87395)

In the helper-based tailcall mechanism it is possible that we expand the
target call into two actual calls: first, a call to
CORINFO_HELP_VIRTUAL_FUNC_PTR to compute the target, and second a call
to that target. We were not taking into account that the return address
needed for the tailcall mechanism needs to be from the second call.

In this particular case the runtime does not request the JIT to pass the
target; that means we end up resolving the target from both the caller
and from the CallTailCallTarget stub. Ideally the JIT would be able to
eliminate the CORINFO_HELP_VIRTUAL_FUNC_PTR call in the caller since it
turns out to be unused, but that requires changes in DCE (and is
somewhat non-trivial, as we have to preserve a null-check).

A simpler way to improve the case is to just change the runtime to
always request the target from the JIT for GVMs, which means the
CallTailCallTarget stub no longer needs to resolve it. That also has the
effect of fixing the original issue, but I have left the original fix in
as well.

Fix #87393
src/coreclr/jit/codegen.h
src/coreclr/jit/codegenarmarch.cpp
src/coreclr/jit/codegencommon.cpp
src/coreclr/jit/codegenloongarch64.cpp
src/coreclr/jit/codegenriscv64.cpp
src/coreclr/jit/codegenxarch.cpp
src/coreclr/vm/tailcallhelp.cpp
src/tests/JIT/Regression/JitBlue/Runtime_87393/Runtime_87393.fs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_87393/Runtime_87393.fsproj [new file with mode: 0644]
src/tests/issues.targets