Patchwork [i386] : Fix target/48708 - Invalid V2DI vector set insn generated

login
register
mail settings
Submitter Uros Bizjak
Date April 21, 2011, 11:50 a.m.
Message ID <BANLkTin4VCRZWQHLhn+MU-N7j6sDvjfE2A@mail.gmail.com>
Download mbox | patch
Permalink /patch/92399/
State New
Headers show

Comments

Uros Bizjak - April 21, 2011, 11:50 a.m.
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  <ubizjak@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  <ubizjak@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.

Patch

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