Hello,

On Mon, 22 Jun 2026, Andrew Stubbs wrote:

> > TARGET_POINTER_MODE and TARGET_ADDR_SPACE_POINTER mode only return one mode,
> > but now we have multiple valid modes: DImode, V2DImode, V4DImode, etc. They
> > also return scalar_int_mode so I can't even invent a new address space for
> > the vector pointers.
> > 
> > Same for TARGET_ADDR_SPACE_ADDRESS_MODE.
> > 
> > TARGET_VALID_POINTER_MODE and TARGET_ADDR_SPACE_VALID_POINTER_MODE only
> > accept scalar_int_mode, so automatically exclude vector pointers.
> > 
> > These can be patched to use plain machine_mode, perhaps, or keep them all
> > scalar and add a new TARGET_ADDR_SPACE_ALLOWS_VECTOR_POINTERS to fix the
> > problem at the call sites, which might make more sense?
> 
> I've been working on this proposal some more. I've solved the above problem by
> keeping all the hooks returning pointer/address types scalar, but changing
> TARGET_ADDR_SPACE_VALID_POINTER_MODE to accept vector types, so the backend
> can approve them. When the target independent code encounters a vector of
> addresses it checks that the inner mode matches the appropriate hook values.
> 
> I was hoping to post a patch series this week, but I've hit against another
> issue.....
> 
> I have an insn that looks like this:
> 
>   (set (reg:V64SI 123)
>        (vec_merge:V64SI
>           (mem:V64SI (reg:V64DI 456))
>           (reg:V64SI 123)
>           (reg:DI 789)))

How would anything in RTL-land see that this load is masked?  There's no 
info anywhere that makes it differ from

   (set (reg:V64SI 123)
        (vec_merge:V64SI
           (mem:V64SI (reg:V64DI 456))
           (reg:V64SI 123)
           (reg:DI 789)))

with me saying that this is a vector merge operation with a memory operand 
that is loaded completely.  It's a verbatim copy of your RTL pattern.  See 
my point? :)

> I can workaround the "reload" in the backend by using unspecs (exactly 
> what I was trying to avoid), but does anyone have a better suggestion?

(a) unspec
(b) teaching RTL-land generally that vec_merge(...(mem)) is "special" and 
    its operands cannot just be lifted out (nah)
(c) biting the bullet and introduce and set a flag on (mem)s that it is 
    "special"/partial
(c') similar flag on the vec_merge
(d) biting a different bullet and introduce a new top-level RTL expression
    (partial_mem:mode (addr) (mask))  (with either target-defined methods 
    to specify content of unselected bits/bytes, or with a third operand 
    to specify them (which then makes this just a different vec_merge)

I think (d) is most elegant and most involved, (c) or (c') are the "best" 
on a cost/benefit basis, (b) the most hacky, but may be fine if done via a 
target hook and (a) the easiest but most unelegant.  (a) has subcases: 
where to put the unspec: around the (mem), around the (vec_merge), around 
the whole (set).  IMHO, around the vec_merge makes "most sense", whatever 
that means for unspecs, but, well, still unspecs :-/


Ciao,
Michael.

Reply via email to