This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][x86] Fix PR52407
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 28 Feb 2012 12:43:11 +0100 (CET)
- Subject: [PATCH][x86] Fix PR52407
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)
Thanks,
Richard.
2012-02-28 Richard Guenther <rguenther@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,35 ----
+ /* { 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_t vl[4] = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
+ int64_t res[8] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+
+ 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] != res[i])
+ abort ();
+
+ return;
+ }