Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT ARM32: Assertion failed 'size == EA_4BYTE' during 'Generate code' #60827

Closed
jakobbotsch opened this issue Oct 25, 2021 · 6 comments · Fixed by #68540
Closed

JIT ARM32: Assertion failed 'size == EA_4BYTE' during 'Generate code' #60827

jakobbotsch opened this issue Oct 25, 2021 · 6 comments · Fixed by #68540
Assignees
Labels
arch-arm32 area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug os-linux Linux OS (any supported distro)
Milestone

Comments

@jakobbotsch
Copy link
Member

Description

The following program hits a JIT assert when compiled with optimizations on.

Reproduction Steps

// Generated by Fuzzlyn v1.5 on 2021-10-24 15:05:24
// Run on Arm Linux
// Seed: 12233313255942773337
// Reduced from 205.3 KiB to 0.5 KiB in 00:03:57
// Hits JIT assert in Release:
// Assertion failed 'size == EA_4BYTE' in 'S0:M21():ushort:this' during 'Generate code' (IL size 20)
// 
//     File: /__w/1/s/src/coreclr/jit/emitarm.cpp Line: 2912
// 
public struct S0
{
    public bool F1;
    public ushort F2;
    public sbyte F3;
    public ushort M21()
    {
        var vr2 = Program.s_6;
        Program.M25(vr2, 0, this);
        return 1;
    }
}

public class Program
{
    public static S0 s_6;
    public static S0[][] s_90 = new S0[][]{new S0[]{new S0()}};
    public static void Main()
    {
        var vr6 = s_90[0][0].M21();
    }

    public static void M25(S0 argThis, ulong arg0, S0 arg1)
    {
        var vr5 = s_6.F1;
    }
}

Expected behavior

No assert hit.

Actual behavior

We hit the assert.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

cc @dotnet/jit-contrib

@dotnet-issue-labeler dotnet-issue-labeler bot added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI untriaged New issue has not been triaged by the area owner labels Oct 25, 2021
@ghost
Copy link

ghost commented Oct 25, 2021

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

The following program hits a JIT assert when compiled with optimizations on.

Reproduction Steps

// Generated by Fuzzlyn v1.5 on 2021-10-24 15:05:24
// Run on Arm Linux
// Seed: 12233313255942773337
// Reduced from 205.3 KiB to 0.5 KiB in 00:03:57
// Hits JIT assert in Release:
// Assertion failed 'size == EA_4BYTE' in 'S0:M21():ushort:this' during 'Generate code' (IL size 20)
// 
//     File: /__w/1/s/src/coreclr/jit/emitarm.cpp Line: 2912
// 
public struct S0
{
    public bool F1;
    public ushort F2;
    public sbyte F3;
    public ushort M21()
    {
        var vr2 = Program.s_6;
        Program.M25(vr2, 0, this);
        return 1;
    }
}

public class Program
{
    public static S0 s_6;
    public static S0[][] s_90 = new S0[][]{new S0[]{new S0()}};
    public static void Main()
    {
        var vr6 = s_90[0][0].M21();
    }

    public static void M25(S0 argThis, ulong arg0, S0 arg1)
    {
        var vr5 = s_6.F1;
    }
}

Expected behavior

No assert hit.

Actual behavior

We hit the assert.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

cc @dotnet/jit-contrib

Author: jakobbotsch
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged

Milestone: -

@echesakov
Copy link
Contributor

I can take a look at this

@echesakov echesakov self-assigned this Oct 28, 2021
@echesakov echesakov added arch-arm32 os-linux Linux OS (any supported distro) labels Oct 28, 2021
@echesakov echesakov added this to the 7.0.0 milestone Oct 28, 2021
@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Nov 2, 2021
@echesakov
Copy link
Contributor

This issue could be reproduced using a simplified version of the original program

using System.Runtime.CompilerServices;

public struct S0
{
    public ushort F1;
    public ushort F2;
    public byte F3;

    public void M21()
    {
        M25(0, 1, 2, 3, this);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static void M25(int r0, int r1, int r2, int r3, S0 stkArg)
    {
    }
}

public class Program
{
    public static int Main()
    {
        new S0().M21();

        return 100;
    }
}

The assert happens when generating PUTARG_STK(OBJ) in M21 to pass 6-byte struct argument stkArg on stack

Generating: N006 (  9,  6) [000005] -c-XG--------        t5 = *  OBJ       struct<S0, 6> REG NA
                                                               /--*  t5     struct
Generating: N008 (???,???) [000014] ---XG--------             *  PUTARG_STK [+0x00] void   (2 slots), (8 stackByteSize), (0 slot), (0 byteOffset) REG NA
                                                        Byref regs: 0001 {r0} => 0000 {}
IN0002:         2B      ldr     r1, [r0]
IN0003:         2B      str     r1, [sp]

Codegen tries to generate ldrh\strh instruction pair for copying the remaining 2 bytes and ended up passing EA_2BYTE as attr to emitIns_R_R_I call. However, emitter expects (even for the small integer types byte\short) attr to be EA_4BYTE for these instructions.

I wonder why we never seen a similar situation on Arm64 - I am going try to repro this before submitting a fix.

@echesakov echesakov added the bug label Nov 2, 2021
@echesakov
Copy link
Contributor

Un-assigning myself
cc @BruceForstall

@echesakov echesakov removed their assignment Mar 15, 2022
@jakobbotsch jakobbotsch added the untriaged New issue has not been triaged by the area owner label Apr 25, 2022
@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Apr 25, 2022
@jakobbotsch
Copy link
Member Author

@JulieLeeMSFT can you assign someone for this?

@jakobbotsch
Copy link
Member Author

Actually I can take a look.

@jakobbotsch jakobbotsch self-assigned this Apr 25, 2022
jakobbotsch added a commit to jakobbotsch/runtime that referenced this issue Apr 26, 2022
On arm architectures the small load/store instructions all work larger
registers and for loads the instruction automatically normalizes the
result. Due to this we always expect to pass the normalized size for
loads/stores when generating these instructions, but in this particular
place we did not do so, resulting in asserts on arm32.

On arm64 the function ignores the size so nothing happens.

Fix dotnet#60827
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 26, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 27, 2022
jakobbotsch added a commit that referenced this issue Apr 27, 2022
…68540)

On arm architectures the small load/store instructions all work larger
registers and for loads the instruction automatically normalizes the
result. Due to this we always expect to pass the normalized size for
loads/stores when generating these instructions, but in this particular
place we did not do so, resulting in asserts on arm32.

On arm64 the function ignores the size so nothing happens.

Fix #60827
@ghost ghost locked as resolved and limited conversation to collaborators May 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-arm32 area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug os-linux Linux OS (any supported distro)
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants