On 18/03/2026 17:12, Andrew Stubbs wrote:
On 17/03/2026 15:25, Andrew Stubbs wrote:
I have run out of places that ICE or cause test failures (for C) when
the mode is a vector. Do you have any other suggestions to find them?
(I already plan to test C++ and Fortran.)
I found some problems ....
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)))
I.e. a masked load from a vector of addresses in pseudo 456, using a
mask in pseudo 789.
LRA sometimes tries to transform this by pulling out the MEM:
(set (reg:V64SI 248)
(mem:V64SI (reg:V64DI 456))
(set (reg:V64SI 123)
(vec_merge:V64SI
(reg:V64SI 248)
(reg:V64SI 123)
(reg:DI 789)))
This looks valid to LRA, but the no-longer-masked memory access causes a
memory fault if the address vector had undefined values in the lanes
that were not intended to be used (which it might well do).
It does this when I use define_special_memory_constraint (which is what
we had for the previous scheme), but switching to
define_memory_constraint only breaks in a different way: now it tries to
create a new base-address register of type Pmode (arguably, this should
be changed by this project, but it looks to be already broken for
address-spaces with pointer sizes that don't match Pmode).
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?
Thanks
Andrew