[backport from gcc-4.7/trunk r184627 ] gcc/ 2012-02-28 Richard Guenther PR target/52407 * config/i386/i386.c (ix86_expand_vector_set): Fix element ordering for the VEC_CONCAT for two element vectors for V2SFmode, V2SImode and V2DImode. gcc/testsuite/ 2012-02-28 Richard Guenther PR target/52407 * gcc.dg/torture/pr52407.c: New testcase. --- gcc-4.6.3/gcc/config/i386/i386.c.~1~ 2012-02-22 20:17:42.000000000 +0100 +++ gcc-4.6.3/gcc/config/i386/i386.c 2012-03-04 17:58:23.000000000 +0100 @@ -31377,9 +31377,9 @@ ix86_expand_vector_set (bool mmx_ok, rtx tmp = gen_reg_rtx (GET_MODE_INNER (mode)); ix86_expand_vector_extract (true, tmp, target, 1 - elt); if (elt == 0) - tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); - else tmp = gen_rtx_VEC_CONCAT (mode, val, tmp); + else + tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; } @@ -31393,9 +31393,9 @@ ix86_expand_vector_set (bool mmx_ok, rtx tmp = gen_reg_rtx (GET_MODE_INNER (mode)); ix86_expand_vector_extract (false, tmp, target, 1 - elt); if (elt == 0) - tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); - else tmp = gen_rtx_VEC_CONCAT (mode, val, tmp); + else + tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; --- gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr52407.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr52407.c 2012-03-04 17:58:23.000000000 +0100 @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +extern void abort (void); + +typedef long long T; +typedef T vl_t __attribute__((vector_size(2 * sizeof (T)))); + +vl_t ul[4], vl[4] = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; + +static void +mul_vl_l(vl_t *u, vl_t *v, T x, int m) +{ + vl_t w; + T *p = (T *)&w; + p[0] = p[1] = x; + while (m--) + *u++ = *v++ * w; +} + +int +main(int argc, char *argv[]) +{ + int i; + T *pl; + + pl = (T *) &ul; + mul_vl_l(ul, vl, 2, 4); + for (i = 0; i < 8; i++) + if (pl[i] != 2 * (i + 1)) + abort (); + + return 0; +}