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 >