On Fri, Jul 4, 2025 at 9:18 AM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> Lowpart subregs are generally disallowed on big-endian SVE vector
> registers, since the first memory element is stored at the least
> significant end of the register, rather than the most significant end.
> (See the comment at the head of aarch64-sve.md for details,
> and aarch64_modes_compatible_p for the implementation.)
>
> This means that arm_sve_neon_bridge.h needs to use custom define_insns
> for big-endian targets, in lieu of using lowpart subregs.  However,
> one of those define_insns relied on the prohibited lowparts internally,
> to convert an Advanced SIMD register to an SVE register.  Since the
> lowpart is not allowed, the lowpart_subreg would return null, leading
> to a later ICE.
>
> The simplest fix seems to be to use %Z instead, to force the Advanced
> SIMD register to be written as an SVE register.

Not only the simplest fix, it is also a small compile time improvement
since we are not creating a new reg.

>
> Tested on aarch64-linux-gnu & aarch64_be-elf.  OK to install?

Ok.

>
> Richard
>
>
> gcc/
>         * config/aarch64/aarch64-sve.md (@aarch64_sve_set_neonq_<mode>):
>         Use %Z instead of lowpart_subreg.  Tweak formatting.
> ---
>  gcc/config/aarch64/aarch64-sve.md | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64-sve.md 
> b/gcc/config/aarch64/aarch64-sve.md
> index 4aecb3a6bf8..87ae4cb0402 100644
> --- a/gcc/config/aarch64/aarch64-sve.md
> +++ b/gcc/config/aarch64/aarch64-sve.md
> @@ -11437,16 +11437,12 @@ (define_insn_and_split 
> "@aarch64_sve_get_neonq_<mode>"
>
>  (define_insn "@aarch64_sve_set_neonq_<mode>"
>    [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
> -      (unspec:SVE_FULL
> -       [(match_operand:SVE_FULL 1 "register_operand" "w")
> -       (match_operand:<V128> 2 "register_operand" "w")
> -       (match_operand:<VPRED> 3 "register_operand" "Upl")]
> -       UNSPEC_SET_NEONQ))]
> +       (unspec:SVE_FULL
> +         [(match_operand:SVE_FULL 1 "register_operand" "w")
> +          (match_operand:<V128> 2 "register_operand" "w")
> +          (match_operand:<VPRED> 3 "register_operand" "Upl")]
> +         UNSPEC_SET_NEONQ))]
>    "TARGET_SVE
>     && BYTES_BIG_ENDIAN"
> -  {
> -    operands[2] = lowpart_subreg (<MODE>mode, operands[2],
> -                                  GET_MODE (operands[2]));
> -    return "sel\t%0.<Vetype>, %3, %2.<Vetype>, %1.<Vetype>";
> -  }
> +  "sel\t%0.<Vetype>, %3, %Z2.<Vetype>, %1.<Vetype>"
>  )
> --
> 2.43.0
>

Reply via email to