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

Reply via email to