https://gcc.gnu.org/g:526efb6bfc148e1ca5d1ec7dd101cb18fdca5302

commit r15-10023-g526efb6bfc148e1ca5d1ec7dd101cb18fdca5302
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Mon Jul 21 15:41:03 2025 +0100

    aarch64: Fix endianness of DFmode vector constants
    
    aarch64_simd_valid_imm tries to decompose a constant into a repeating
    series of 64 bits, since most Advanced SIMD and SVE immediate forms
    require that.  (The exceptions are handled first.)  It does this by
    building up a byte-level register image, lsb first.  If the image does
    turn out to repeat every 64 bits, it loads the first 64 bits into an
    integer.
    
    At this point, endianness has mostly been dealt with.  Endianness
    applies to transfers between registers and memory, whereas at this
    point we're dealing purely with register values.
    
    However, one of things we try is to bitcast the value to a float
    and use FMOV.  This involves splitting the value into 32-bit chunks
    (stored as longs) and passing them to real_from_target.  The problem
    being fixed by this patch is that, when a value spans multiple 32-bit
    chunks, real_from_target expects them to be in memory rather than
    register order.  Thus index 0 is the most significant chunk if
    FLOAT_WORDS_BIG_ENDIAN and the least significant chunk otherwise.
    
    This fixes aarch64/sve/cond_fadd_1.c and various other tests
    for aarch64_be-elf.
    
    gcc/
            * config/aarch64/aarch64.cc (aarch64_simd_valid_imm): Account
            for FLOAT_WORDS_BIG_ENDIAN when building a floating-point value.
    
    (cherry picked from commit 82dd19890b6139c4bac2385068a68613920ae1a2)

Diff:
---
 gcc/config/aarch64/aarch64.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4f68fe2e0d5f..cfbf0a7eeba6 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -23531,6 +23531,8 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info 
*info,
       long int as_long_ints[2];
       as_long_ints[0] = ival & 0xFFFFFFFF;
       as_long_ints[1] = (ival >> 32) & 0xFFFFFFFF;
+      if (imode == DImode && FLOAT_WORDS_BIG_ENDIAN)
+       std::swap (as_long_ints[0], as_long_ints[1]);
 
       REAL_VALUE_TYPE r;
       real_from_target (&r, as_long_ints, fmode);

Reply via email to