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

Work around a Linux arm32 unaligned data issue in SuperPMI #56517

Conversation

BruceForstall
Copy link
Member

impImportStaticReadOnlyField reads the data at the address returned by
getFieldAddress. SuperPMI saves and replays this data, but it doesn't
store it at a naturally aligned address. For int64/double (at least),
this is a problem on Linux arm32, which raises a SIGBUS exception on
such unaligned access.

This works around the problem by copying the potentially unaligned data
to a known aligned spot before reading it. This is only done under DEBUG
and when we know we are replaying under SuperPMI.

A proper fix would be to teach SuperPMI about alignment, but that would be
a large and risky change, compared to this small and isolated workaround.

The fixes the non-determinism of #56156.

impImportStaticReadOnlyField reads the data at the address returned by
getFieldAddress. SuperPMI saves and replays this data, but it doesn't
store it at a naturally aligned address. For int64/double (at least),
this is a problem on Linux arm32, which raises a SIGBUS exception on
such unaligned access.

This works around the problem by copying the potentially unaligned data
to a known aligned spot before reading it. This is only done under DEBUG
and when we know we are replaying under SuperPMI.

A proper fix would be to teach SuperPMI about alignment, but that would be
a large and risky change, compared to this small and isolated workaround.

The fixes the non-determinism of dotnet#56156.
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jul 29, 2021
@BruceForstall
Copy link
Member Author

@kunalspathak @dotnet/jit-contrib PTAL

static_assert_no_msg(sizeof(unsigned __int8) == sizeof(signed char));
static_assert_no_msg(sizeof(unsigned __int8) == sizeof(unsigned char));
*(unsigned __int8*)p_aligned_data = *((unsigned __int8*)fldAddr);
break;
Copy link
Contributor

@briansull briansull Jul 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing should need to be copied for the Byte case.
This looks like it makes an unnecessary copy

p_aligned_data = fldAddr; should work.

case TYP_USHORT:
static_assert_no_msg(sizeof(unsigned __int16) == sizeof(short));
static_assert_no_msg(sizeof(unsigned __int16) == sizeof(unsigned short));
*(unsigned __int16*)p_aligned_data = GET_UNALIGNED_16(fldAddr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In these cases, you could check the current alignment of fldAddr and just use it if it meets the alignment requirement of 2,4 or 8

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BruceForstall - Help me understand, but don't we want the workaround only in cases when fldAddr is unaligned?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need the workaround for unaligned fldAddr, but it doesn't hurt (except some miniscule perf -- in SuperPMI replay only) to do it. I went ahead and did it only when necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean you will move about chance only if flAddr is unaligned?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kunalspathak I don't understand your question, but check the updated code to see if it answers it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. That's what I was expecting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I prefer what it was before. Actually, can't the entire thing just be:

    alignas(8) unsigned char aligned_data[8] = {};
    if (info.compMethodSuperPMIIndex != -1)
    {
        // Work around arm32 alignment bug in SuperPMI
        memcpy(aligned_data, fldAddr, min(sizeof(aligned_data), genTypeSize(lclTyp)));
        fldAddr = aligned_data;
    }

?

Anyway, I guess this workaround will disappear soon anyway, so no real need to do anything more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right that it could be smaller. Would I trust that alignas works for all compilers? Even so, could use double as I'm currently doing. And could do conditional, only-if-needed, as well. I think I'll leave it as is; there's not a lot of reason to optimize it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would I trust that alignas works for all compilers?

I believe alignas is part of C++11.

I think I'll leave it as is; there's not a lot of reason to optimize it.

Agree, sounds fine to me.

Copy link
Member

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@BruceForstall BruceForstall merged commit 38ae818 into dotnet:main Jul 30, 2021
@BruceForstall BruceForstall deleted the WorkAroundSpmiArm32UnalignedDataProblem branch July 30, 2021 04:50
@ghost ghost locked as resolved and limited conversation to collaborators Aug 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants