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;
+ }

Reply via email to