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

Arm64/Sve: Remove unwanted insScalableOpts and instructions #103620

Merged
merged 10 commits into from
Jun 18, 2024

Conversation

kunalspathak
Copy link
Member

@kunalspathak kunalspathak commented Jun 18, 2024

Now that we have separate predicate and vector registers, remove all the unnecessary insScalableOpts entries and fix some unit tests. Also included a fix for GatherVector* which currently AVs.

They are all passing: https://gist.github.com/kunalspathak/797640e95a3f3edfd67ef107c19389ae
Also ran the unit tests and they are all working.

Fixes: #103606

@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 Jun 18, 2024
@kunalspathak
Copy link
Member Author

@dotnet/arm64-contrib @TIHan @amanasifkhalid PTAL

Copy link
Contributor

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

@@ -4252,9 +4252,15 @@ void emitter::emitIns_Mov(
{
if (isPredicateRegister(dstReg) && isPredicateRegister(srcReg))
{
assert(insOptsNone(opt));
if (insOptsNone(opt))
Copy link
Contributor

Choose a reason for hiding this comment

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

This code is odd. This is because for predicates we always use INS_OPTS_SCALABLE_B for a mov, so the passed in opt value doesn't matter ?

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, so basically, this code operates just on INS_OPTS_SCALABLE_B (and we added single test for that). For other places, if we have to pass INS_OPTS_SCALABLE_B if register types are predicate feels like an overhead, so instead this code expects it to be NONE, in which case it will set the options to INS_OPTS_SCALABLE_B.

Copy link
Member

Choose a reason for hiding this comment

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

Would something like this work?

if (!insOptsNone(opt))
{
    assert(opt == INS_OPTS_SCALABLE_B);
}

opt = INS_OPTS_SCALABLE_B;

I think that shape makes it clearer the if-statement is debug-only code, and ensures opt is always INS_OPTS_SCALABLE_B even if we don't have asserts on to catch improper handling.

Copy link
Contributor

Choose a reason for hiding this comment

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

assert(opt == INS_OPTS_SCALABLE_B || insOptsNone(opt));
opt = INS_OPTS_SCALABLE_B;

?

@@ -1926,22 +1926,17 @@ void emitter::emitInsSve_R_R(instruction ins,
assert(insOptsScalableStandard(opt));
return emitInsSve_R_R_I(INS_sve_pmov, attr, reg1, reg2, 0, opt, sopt);
}
if (sopt == INS_SCALABLE_OPTS_TO_PREDICATE)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any functions we can remove sopt completely?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I understand. Can you please elaborate?

Copy link
Member

Choose a reason for hiding this comment

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

I think Alan means are there any emitInsSve_* methods that no longer need the sopt parameter, because it's only checking that sopt is INS_SCALABLE_OPTS_NONE? emitInsSve_R_R seems close to that, though we still check sopt with insScalableOptsWithVectorLength at the end of the method.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah ok. Thanks @amanasifkhalid for clarifying. I didn't check, but can do it as a follow-up work.

return true;
// For some variants, the address is in vector.
// Return false for such cases.
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

I was returning true here because I assumed we needed to track the fact there were addresses in Op2. Is it safe to not track that?

Copy link
Member Author

Choose a reason for hiding this comment

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

Re-reading, the OperIsMemoryLoad() contract is to return true if this intrinsic may throw NullReferenceException of address is "null". Now, for certain non-faulting intrinsics, it should return false, but for Gather*, this should return true.
Fixed it.

Copy link
Contributor

Choose a reason for hiding this comment

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

the OperIsMemoryLoad() contract is to return true if this intrinsic may throw NullReferenceException of address is "null".

That was the part I wasn't sure of.
Happy with the new version.

Copy link
Member

@amanasifkhalid amanasifkhalid left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@kunalspathak
Copy link
Member Author

/ba-g timeout issues

@kunalspathak kunalspathak merged commit d5d2448 into dotnet:main Jun 18, 2024
96 of 107 checks passed
@kunalspathak kunalspathak deleted the sve-todos branch June 18, 2024 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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.

Arm64/Sve: AV in GatherLoad* APIs
3 participants