https://gcc.gnu.org/g:82f5dd231e2e25bc18853f3f1d217a6bde778b20

commit r14-11910-g82f5dd231e2e25bc18853f3f1d217a6bde778b20
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Sat Jul 26 18:38:47 2025 +0100

    aarch64: Fix neon-sve-bridge.c failures for big-endian
    
    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.
    
    gcc/
            * config/aarch64/aarch64-sve.md (@aarch64_sve_set_neonq_<mode>):
            Use %Z instead of lowpart_subreg.  Tweak formatting.
    
    (cherry picked from commit 69c839c7361430ec27d1f13f909531b872588f27)

Diff:
---
 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 0434358122d2..c94f4b7c995c 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -10989,16 +10989,12 @@
 
 (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>"
 )

Reply via email to