Skip to content

JIT: Incorrect last use propagation for implicit byrefs when undoing promotion #80488

@jakobbotsch

Description

@jakobbotsch

The propagation done at

GenTreeFlags lastUse = lclNode->gtFlags & GTF_VAR_DEATH;
lclNode->ChangeType(TYP_BYREF);
lclNode->ChangeOper(GT_LCL_VAR);
lclNode->SetLclNum(newLclNum);
lclNode->SetAllEffectsFlags(GTF_EMPTY); // Implicit by-ref parameters cannot be address-exposed.
lclNode->gtFlags |= lastUse;
is not quite correct. Liveness sets GTF_VAR_DEATH on a promoted struct local if any of its fields are dying, but we can only know that the implicit byref local is dying if all of its fields are. Noticed this while trying to revive #78818.

using System;
using System.Runtime.CompilerServices;

class EarlyLiveness_ImplicitByRefPropagation
{
    static int Main(string[] args)
    {
        int code = Foo(new S16 { F1 = 100 });
        if (code != 100)
        {
            Console.WriteLine("FAIL: Returned {0}", code);
        }

        return code;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static int Foo(S16 s)
    {
        Bar(s);
        return (int)s.F1;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Bar(S16 s)
    {
        s.F1 = 12345;
        Consume(s);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Consume(S16 s) { }

    private struct S16
    {
        public long F0, F1;
    }
}

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions