Andrew Stubbs <[email protected]> writes:
> On 26/06/2026 16:53, Richard Sandiford wrote:
>> Andrew Stubbs <[email protected]> writes:
>>>> x86 gets away with
>>>>
>>>> (define_insn "*<avx512>_load<mode>_mask"
>>>>     [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
>>>>       (vec_merge:V48_AVX512VL
>>>>         (unspec:V48_AVX512VL
>>>>           [(match_operand:V48_AVX512VL 1 "memory_operand" "m")]
>>>>           UNSPEC_MASKLOAD)
>>>>         (match_operand:V48_AVX512VL 2 "nonimm_or_0_operand" "0C")
>>>>         (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
>>>>
>>>> so the (unspec ...) is wrapped around the MEM.
>>>
>>> I tried that; it just tried to reload the entire unspec. [...]
>> 
>> Out of curiosity, how did that happen?  In the pattern above, the unspec
>> is a fixed part of the pattern, whereas LRA only reloads match_operands.
>
> You're right; my RTL looked like this, but I had the match_operand 
> recognize the unspec because I wanted to prevent LRA from separating it 
> from the MEM.

With a normal consecutive memory operand like the one above, I thought
LRA would only consider reloading the address.

> With it the way you have it in that example, the unspec is completely 
> inactive, as far as LRA is concerned.

Yeah.  But it does mean that the equivalent of what you described earlier:

  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)))

shouldn't happen for things that need to be masked loads.  The pattern
would start off with the unspec and (unspec [(reg ...)] UNSPEC_MASKLOAD)
would not be valid.

I assume the failure that you describe above came from providing an insn
that has both register and memory alternatives.  And that's a good thing,
of course.  A masked load can validily implement the vec_merge-of-a-normal-
mem above, since there's no requirement for the pattern to fault on
reads that would be discarded.  It's just that there needs to be another
RTL pattern for cases where the masking is semantically required.  The x86
pattern seems to achieve that, even though (like you say) there is no
perfect representation as things stand.

Richard

Reply via email to