Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

kunalspathak
Copy link
Contributor

@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

@ghost ghost 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
Contributor 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.

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
Contributor 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
Contributor

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;

?

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
Contributor 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
Contributor

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
Contributor 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
Contributor 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
Contributor

@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
Contributor Author

/ba-g timeout issues

@kunalspathak kunalspathak merged commit d5d2448 into dotnet:main Jun 18, 2024
@kunalspathak kunalspathak deleted the sve-todos branch June 18, 2024 22:18
@github-actions github-actions bot locked and limited conversation to collaborators Jul 19, 2024
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.

Arm64/Sve: AV in GatherLoad* APIs
3 participants