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