Hello!

ix86_expand_vector_set (around line 31485) synthesizes unrecognisable
vec_concat/vec_select insn in invalid mode. The problem is, that
V2DImode goes through the same code path as V2DFmode.

2011-04-21  Uros Bizjak  <ubiz...@gmail.com>

        * config/i386/i386.c (ix86_expand_vector_set) <V2DImode>: Generate
        vec_extract and vec_concat for non-SSE4_1 targets.

testsuite/ChangeLog:

2011-04-21  Uros Bizjak  <ubiz...@gmail.com>

        * gcc.target/i386/pr48708.c: New test.

Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.

Patch was committed to mainline SVN and will be committed to all
relevant release branches.

Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c  (revision 172811)
+++ config/i386/i386.c  (working copy)
@@ -31483,10 +31483,19 @@ ix86_expand_vector_set (bool mmx_ok, rtx
       break;
 
     case V2DImode:
-      use_vec_merge = TARGET_SSE4_1;
+      use_vec_merge = TARGET_SSE4_1 && TARGET_64BIT;
       if (use_vec_merge)
        break;
 
+      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;
+
     case V2DFmode:
       {
        rtx op0, op1;
Index: testsuite/gcc.target/i386/pr48708.c
===================================================================
--- testsuite/gcc.target/i386/pr48708.c (revision 0)
+++ testsuite/gcc.target/i386/pr48708.c (revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2" } */
+
+#include <emmintrin.h>
+
+typedef long long T __attribute__((may_alias));
+struct S { __m128i d; };
+
+__m128i
+foo (long long *x, struct S *y, __m128i *z)
+{
+  struct S s = *y;
+  ((T *) &s.d)[0] = *x;
+  return _mm_cmpeq_epi16 (s.d, *z);
+}

Reply via email to