Closed
Description
Minimal repro for a CQ issue @stephentoub noticed in #87067: a constant doesn't succesfully propagate through a struct:
struct Awaitable
{
int Opts;
Awaitable(bool value)
{
Opts = value ? 1 : 2;
//
//if (value)
// Opts = 1;
//else
// Opts = 2;
}
}
public static int Test() => new Awaitable(false).Opts;
Codegen for Test
:
; Assembly listing for method Awaitable:Test():int
push rax
xor eax, eax
mov dword ptr [rsp], eax
mov dword ptr [rsp], 2
mov eax, dword ptr [rsp]
add rsp, 8
ret
; Total bytes of code 21
Now replace that ternary operation with if-else
(uncomment it and remove the ternary):
; Method Awaitable:Test():int
mov eax, 2
ret
; Total bytes of code: 6
JitDump diff: https://www.diffchecker.com/ld33PGnr (left - if-esle
, right - ternary
). So, apparently, we don't enregister the Opts field due to address exposure, @SingleAccretion suggested that when we spill all stack entries to locals at the end of a block, we should not spill constants and local addresses. @AndyAyersMS noted that it might be a big amount of work to do so.
@dotnet/jit-contrib @jakobbotsch