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 >
