Hi Luis,

It seems I've got only this email, and it looks like it is part of a
larger discussion. Did I miss it?
Claudiu

On Wed, Oct 22, 2025 at 3:37 PM Luis Silva <[email protected]> wrote:
>
> From: Loeka Rogge <[email protected]>
>
> V2HI vectors, explicitly or auto-generated, could be stored in memory wrongly
> due to endianness. For example in the following c code stores to the struct
> are SLP vectorized, causing them to be stored in the wrong order:
>
> >   struct S {short a; short b;};
> >   s.a = 520;
> >   s.b = -1;
>
> in the split2 pass the following register set:
>
> > (const_vector:V2HI [
> >         (const_int 520 [0x208])
> >         (const_int -1 [0xffffffffffffffff])
> >     ])) "smallTest.c":16:9 484 {*movv2hi_insn}
>
> is converted to:
>
> > (const_int -65016 [0xffffffffffff0208])) "smallTest.c":16:9 3 {*movsi_insn}
>
> and is then loaded into the struct. For big-endian this is wrong because
> the most significant bytes are written first in memory, storing -1 instead of
> 520 in s.a .
> This patch swaps the 2 values in this step if the target is big-endian.
> The added test creates a vector of 2 shorts and verifies the order when
> it is passed in a register or in memory.
>
> Regtested for arc and big-endian arc.
>
> gcc/ChangeLog:
>
>         * config/arc/simdext.md: Change order for movv2hi for big-endian.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/arc/movv2hi-be.c: New test.
>
> Signed-off-by: Loeka Rogge <[email protected]>
> ---
>  gcc/config/arc/simdext.md                 | 11 ++++----
>  gcc/testsuite/gcc.target/arc/movv2hi-be.c | 32 +++++++++++++++++++++++
>  2 files changed, 38 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/movv2hi-be.c
>
> diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
> index a53b2ba737..94ea0884b7 100644
> --- a/gcc/config/arc/simdext.md
> +++ b/gcc/config/arc/simdext.md
> @@ -1438,11 +1438,12 @@
>    "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR"
>    [(set (match_dup 0) (match_dup 2))]
>    {
> -   HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
> -   intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
> -
> -   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
> -   operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode));
> +    int hi = !TARGET_BIG_ENDIAN;
> +    int lo = !hi;
> +    HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, hi)) << 16;
> +    intval |= INTVAL (XVECEXP (operands[1], 0, lo)) & 0xFFFF;
> +    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
> +    operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode));
>    }
>    [(set_attr "type" "move,move,load,store")
>     (set_attr "predicable" "yes,yes,no,no")
> diff --git a/gcc/testsuite/gcc.target/arc/movv2hi-be.c 
> b/gcc/testsuite/gcc.target/arc/movv2hi-be.c
> new file mode 100644
> index 0000000000..7d4b8e2e5c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/movv2hi-be.c
> @@ -0,0 +1,32 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +typedef short v2hi __attribute__((vector_size(4)));
> +
> +__attribute__((noinline)) void foo3(short a)
> +{
> +    if (a != 520)
> +    {
> +        __builtin_abort();
> +    }
> +}
> +
> +__attribute__((noinline)) void foo2(v2hi v)
> +{
> +    foo3(v[0]);
> +}
> +
> +__attribute__((noinline)) void foo(v2hi *v)
> +{
> +    foo2(*v);
> +}
> +
> +int main (void)
> +{
> +    v2hi v;
> +    v[0] = 520;
> +    v[1] = -1;
> +    foo(&v);
> +    foo2(v);
> +    return 0;
> +}
> --
> 2.43.0
>

Reply via email to