> It's essentially vectorization in the backend, for code with specific
> attributes. I definitely do not want to do it at gimple level because that
> would have the exact same problems that the existing vectorizer has.
> For example, in most cases I can simply transform
>
> (set (reg:SI) (plus:SI (reg:SI) (const_int)))
>
> into
>
> (set (reg:V64SI) (plus:V64SI (reg:V64SI) (const_vector:V64SI)))
>
> which makes total sense and Just Works on AMD GCN for almost all
> instructions.
>
> So, I want to do the same thing for a MEM:
>
> (set (reg:SI) (mem:SI (reg:DI)))
>
> becomes
>
> (set (reg:V64SI) (mem:V64SI (reg:V64DI)))
>
> except that the MEM is not valid because the address "isn't valid".
> There's no reason it shouldn't work on the architecture -- the two RTL
> patterns here will emit the *exact same* assembler code (obviously I set
> the execution mask differently) -- it's just an old assumption built
> into the compiler.
I'm not sure I follow 100% so let me just spell it out for myself. You're
probably trying to "just vectorize everything", like in a GPU/SIMT programming
model? And obviously this clashes with the vectorizer which doesn't if-convert
everything, bails, costs etc.?
But I don't see how vectorization, even simple one, is easier at RTL level.
What about divergence, calls, aliasing, loops? Or is your target much
narrower?
Even if narrow, for a proper gimple solution you'd need a "second vectorizer"
with limited scope and predicated gimple (because our usual IFNs aren't
comprehensive enough)? It would "just" eat all conditions turning them into
masks. That's a long-term goal for the vectorizer as well BTW :)
Then, however, you'd still have the representational problem post expand :/
A vec_predicate would be helpful there, but only if it supported moves, loads
and stores, which my initial RFC skipped for the known reasons ("they are
special").
I guess it's time to start thinking more about them but that's obviously the
opposite of a quick solution... so nothing here will actually help you right
away :/
> It might be that a "vec_predicate" would be better than "vec_merge"? But if
> the register allocator can pull the MEM out of context then we didn't gain
> anything for the specific issues I discussed in the gcc@ thread.
Yeah, one of the main reasons for vec_predicate as a "first-class" citizen is
that we should not be able use its constituents context free. Under that model
a vec_merge is already an atomic operation, a predicated reg-move. I wouldn't
re-use vec_merge of course but we'd have something like
(set (reg...) (vec_predicate [(reg ...)] vmask velse ...))
--
Regards
Robin