Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Can unmasked stores update tail elements in memory? #846

Closed
palmer-dabbelt opened this issue Dec 16, 2022 · 5 comments
Closed

Can unmasked stores update tail elements in memory? #846

palmer-dabbelt opened this issue Dec 16, 2022 · 5 comments

Comments

@palmer-dabbelt
Copy link
Member

A recent GCC patch https://inbox.sourceware.org/gcc-patches/20221214113641.63320-1-juzhe.zhong@rivai.ai/ brought up a bit of a grey area in the spec: there's nothing explicitly defining the behavior of tail elements for unmasked vector stores. I'd always assumed the intent was to have tail elements defined to not manifest as stores (aside from the whole-register flavors), but I've never tried to look this close before.

Not sure if I'm just missing something in the spec here?

@nick-knight
Copy link
Contributor

nick-knight commented Dec 16, 2022

It sounds like your concern is that

Masked vector stores only update active memory elements.

doesn't appear to address the unmasked case.

I think the fundamental confusion is what it means to be "masked" or "unmasked": I think these terms are used in slightly different ways at different points in the spec. For example, the sentence before the one I quoted says

Vector loads and stores are masked [...]

I interpret this as meaning that they have masked forms, where vm=0 indicates that v0 is an additional input operand that serves as the mask register. This is in addition to unmasked forms (vm=1).

Another example of a potentially confusing usage concerns the instructions that use vm=0 to indicate that v0 is an additional input operand, that doesn't play the same role as a mask: see, e.g., the description of vmadc and vmsbc. Confusion about this caused some wrinkles in the C intrinsics API, which we're hoping to iron out in time for ratification.

Anyway, my perspective is that the spec intends some kind of functional equivalence between "unmasked" and "masked with all mask bits asserted". I guess I'm basing this on common sense, on the choice vm=1 (vs. =0) to indicate unmasked, and on the following definition of "active" and "inactive" (in terms of "mask"):

   mask(x)     = unmasked || v0.mask[x] == 1
   active(x)   = body(x) && mask(x)
   inactive(x) = body(x) && !mask(x)

It seems inconsistent if unmasked stores can update "tail memory" but masked stores cannot.

In summary, I also feel that some of the language is confusing, but I also feel that the intent is clear. I'm not addressing the question of whether there is or isn't an omission ("gray area") in the spec.

@aswaterman
Copy link
Member

Although I think this follows from the definition of "active" and the sentence Nick quoted is not necessary, I'm just going to delete the word "masked" from that sentence to avoid this question going forward.

@palmer-dabbelt
Copy link
Member Author

My concern was with the "masked" part, not the "active" part, but I think Nick's point about

Vector loads and stores are masked and do not raise exceptions on inactive elements. 

meaning all vector loads and stores are masked is probably sufficient? For some reason I'd been reading that as "masked vector loads and stores do not raise exceptions on inactive elements", which is slightly different.

@aswaterman
Copy link
Member

Ack. I'd still like to clarify this in the spec, even though it's not a normative change, to short-circuit this kind of question in the future. I'll make a PR shortly.

@palmer-dabbelt
Copy link
Member Author

WFM.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants