On Tue, 28 Feb 2012, Uros Bizjak wrote: > Hello! > > > This fixes element ordering for V2SFmode, V2SImode and V2DImode > > concats in ix86_expand_vector_set. > > > > Boostrap / regtest pending on x86_64-unknown-linux-gnu. > > > > Ok everywhere? (the testcase only fails on trunk) > > > > 2012-02-28 Richard Guenther <rguent...@suse.de> > > > > 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.dg/torture/pr52407.c: New testcase. > > OK, but please add Jakub's testcase from Comment #5 [1] instead (it > uses long long, calculates result on-the-fly and returns 0 from main > ;) ). > > [1] http://gcc.gnu.org/ml/gcc-bugs/2012-02/msg02687.html
I guess using __INT64_TYPE__ is more portable to weird targets though. I integrated the other testcase changes though. Richard. 2012-02-28 Richard Guenther <rguent...@suse.de> 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.dg/torture/pr52407.c: New testcase. Index: gcc/config/i386/i386.c =================================================================== *** gcc/config/i386/i386.c (revision 184622) --- gcc/config/i386/i386.c (working copy) *************** ix86_expand_vector_set (bool mmx_ok, rtx *** 33562,33570 **** 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); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; } --- 33562,33570 ---- 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, val, tmp); + else + tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; } *************** ix86_expand_vector_set (bool mmx_ok, rtx *** 33578,33586 **** 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); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; --- 33578,33586 ---- 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, val, tmp); + else + tmp = gen_rtx_VEC_CONCAT (mode, tmp, val); emit_insn (gen_rtx_SET (VOIDmode, target, tmp)); return; Index: gcc/testsuite/gcc.dg/torture/pr52407.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr52407.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr52407.c (revision 0) *************** *** 0 **** --- 1,33 ---- + /* { dg-do run } */ + + extern void abort (void); + + typedef __INT64_TYPE__ int64_t; + typedef int64_t vl_t __attribute__((vector_size(16))); + + 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, int64_t x, int m) + { + vl_t w; + int64_t *p = (int64_t *)&w; + p[0] = p[1] = x; + while (m--) + *u++ = *v++ * w; + } + + int + main(int argc, char *argv[]) + { + int i; + int64_t *pl; + + pl = (int64_t *) &ul; + mul_vl_l(ul, vl, 2, 4); + for (i = 0; i < 8; i++) + if (pl[i] != 2 * (i + 1)) + abort (); + + return 0; + }