]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
x86 SSE: Improved vector initialization/construction.
authorRoger Sayle <roger@nextmovesoftware.com>
Sat, 1 Aug 2026 16:51:02 +0000 (17:51 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Sat, 1 Aug 2026 16:53:52 +0000 (17:53 +0100)
This patch is a reorganization of x86's vector initialization (vec_init)
functionality to generate more efficient implementations in most/many
cases.  Previously, for most (128-bit and 256-bit) vectors types,
i386-expand.cc made use of "concat" recursion to divide-and-conquor;
splitting each vector into upper and lower halves, initializing them,
then concatenating the results together.  Simple and orthogonal, but
alas inefficient.  This idiom is unable to take advantage of SSE's
zero extension semantics, shuffle/permutation instructions, byte-level
shifts, element insertion instructions nor vector-mode logic operations.
Unfortunately the reality is that these ISAs are irregular, as are the
patterns provided by the backend expose their instructions (which are
often available in one mode but not another).

The patch below recognizes/accepts these asymmetries, and provides
"custom" vector initialization functions for most 128-bit and 256-bit
vector modes.  There are too many optimization/improvements to list
them all, but some examples are given below:

v4si f1(int x, int y) { return (v4si){x,y,0,0}; }

Before with -O2:
f1_old: movd    %edi, %xmm0
        movd    %esi, %xmm1
        punpckldq       %xmm1, %xmm0
        movq    %xmm0, %xmm0
        ret

After with -O2:
f1_new: movd    %edi, %xmm0
        movd    %esi, %xmm1
        punpckldq       %xmm1, %xmm0
        ret

v4si f2(int x) { return (v4si){0,x,x,0}; }

Before with -O2:
f2_old: movd    %edi, %xmm2
        pxor    %xmm0, %xmm0
        movd    %edi, %xmm1
        punpckldq       %xmm2, %xmm0
        punpcklqdq      %xmm1, %xmm0
        ret

f2_new: movd    %edi, %xmm0
        shufps  $65, %xmm0, %xmm0
        ret

v4si f3(int x) { return (v4si){x,1,x,2}; }

Before with -O2:
f3_old: movl    $2, %eax
        movd    %edi, %xmm0
        movd    %eax, %xmm2
        movl    $1, %eax
        movdqa  %xmm0, %xmm1
        movd    %eax, %xmm3
        punpckldq       %xmm2, %xmm1
        punpckldq       %xmm3, %xmm0
        punpcklqdq      %xmm1, %xmm0
        ret

After with -O2:
f3_new: movd    %edi, %xmm0
        shufps  $68, %xmm0, %xmm0
        por     .LC0(%rip), %xmm0
        ret

v16qi f4(char x) { return (v16qi){x,0,0,0,0,0,0,0,0,x,0,0,0,0,0,0}; }

Before with -O2 -mavx2:
f4_old: vmovd   %edi, %xmm0
        xorl    %eax, %eax
        vpxor   %xmm1, %xmm1, %xmm1
        vpinsrb $1, %eax, %xmm0, %xmm0
        vpinsrb $1, %edi, %xmm1, %xmm1
        vpmovzxwd       %xmm0, %xmm0
        vpmovzxwd       %xmm1, %xmm1
        vpmovzxdq       %xmm1, %xmm1
        vpmovzxdq       %xmm0, %xmm0
        vpunpcklqdq     %xmm1, %xmm0, %xmm0
        ret

After with -O2 -mavx2:
f4_new: movzbl  %dil, %eax
        vmovd   %eax, %xmm0
        vpinsrb $9, %edi, %xmm0, %xmm0
        ret

Unfortunately, despite all of the goodness there remains one testsuite
regression: avx512vl-concatv4si-1.c whose f2 function currently expects
3 instructions before the return:

orig: vmovd   (%rdi), %xmm2
        vpinsrd $1, 4(%rdi), %xmm2, %xmm1
        vpunpcklqdq     %xmm1, %xmm0, %xmm16
        ret

where actually an optimal implementation should require only two:

ideal: vpinsrd $2, (%rdi), %xmm0, %xmm0
        vpinsrd $3, 4(%rdi), %xmm0, %xmm0
ret

but unfortunately with this patch we currently (for now) generate:

curr:   vmovd   %xmm0, %eax
        vpextrd $1, %xmm0, %edx
        vmovd   %eax, %xmm0
        vpinsrd $1, %edx, %xmm0, %xmm0
        vpinsrd $2, (%rdi), %xmm0, %xmm0
        vpinsrd $3, 4(%rdi), %xmm0, %xmm0
        vmovdqa32       %xmm0, %xmm16
        ret

which actually contains our two optimal instructions, but between
combine, simplify-rtx and sse.md's define_insn_and_splits, we fail
to notice that the remaining operations (converting V2SI to V4SI)
are a no-op.  I beg the reviewers'/maintainers' indulgence to allow
this to fail for the time being, to be solved in a follow-up patch.
This current patch is large enough already, and this remaining quirk
needs to be resolved outside the RTL expansion pass, in the later
RTL optimizers (where it is currently a missed optimization).

2026-08-01  Roger Sayle  <roger@nextmovesoftware.com>
    Hongtao Liu  <hongtao.liu@intel.com>

gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_vector_init_one_nonzero):
Improved implementations for V2DI, V2DF, V4SI, V4SF, V4DI and V4DF
modes.  Return false for V2SI and V2SF modes if the one non-zero
element isn't the first/lowest.  Improved implementations for V8HI,
V16QI, V2HI and V8QI modes.
(nonzero_int_const_count): New helper function to count the
number of non-zero integer constants in a given array.
(nonzero_float_const_count): Likewise for SFmode floats.
(nonzero_double_const_count): Likewise for DFmode doubles.
(ix86_expand_vector_init_insert): New function to initialize a
V4SI, V8HI or V16QI vector using a sequence of pinsr[bwd] insns.
(onevar_perm_p): New local helper function.
(twovar_perm_p): Likewise.
(ix86_expand_vector_init_v2di): New mode-specific function.
(ix86_expand_vector_init_v2df): Likewise.
(ix86_expand_vector_init_v4si): Likewise.
(ix86_expand_vector_init_v4sf): Likewise.
(ix86_expand_vector_init_v8hi): Likewise.
(ix86_expand_vector_init_v16qi): Likewise.
(ix86_expand_vector_init_v4di): Likewise.
(ix86_expand_vector_init_v4df): Likewise.
(ix86_expand_vector_init_v8si): Likewise.
(ix86_expand_vector_init_v8sf): Likewise.
(ix86_expand_vector_init_general): Call the above custom helper
functions for the relevant modes.
* config/i386/sse.md (*vec_interleave_lowv4si_sse): New pattern
for (V4SImode) unpcklps on TARGET_SSE but not TARGET_SSE2.

gcc/testsuite/ChangeLog
* gcc.target/i386/avx512vl-concatv4si-1.c: Tweak exisiting test.
* gcc.target/i386/avx-init-v16qi-1.c: New test case.
* gcc.target/i386/avx-init-v2df-1.c: Likewise.
* gcc.target/i386/avx-init-v2df-2.c: Likewise.
* gcc.target/i386/avx-init-v2di-1.c: Likewise.
* gcc.target/i386/avx-init-v2di-2.c: Likewise.
* gcc.target/i386/avx-init-v4sf-1.c: Likewise.
* gcc.target/i386/avx-init-v4sf-2.c: Likewise.
* gcc.target/i386/avx-init-v4si-1.c: Likewise.
* gcc.target/i386/avx-init-v8hi-1.c: Likewise.
* gcc.target/i386/avx2-init-v4sf-1.c: Likewise.
* gcc.target/i386/avx2-init-v4si-1.c: Likewise.
* gcc.target/i386/avx2-init-v4si-2.c: Likewise.
* gcc.target/i386/avx512vl-init-v2di-1.c: Likewise.
* gcc.target/i386/avx512vl-init-v2di-2.c: Likewise.
* gcc.target/i386/avx512vl-init-v4si-1.c: Likewise.
* gcc.target/i386/sse-init-v16qi-1.c: Likewise.
* gcc.target/i386/sse-init-v2df-1.c: Likewise.
* gcc.target/i386/sse-init-v2df-2.c: Likewise.
* gcc.target/i386/sse-init-v2di-1.c: Likewise.
* gcc.target/i386/sse-init-v2di-2.c: Likewise.
* gcc.target/i386/sse-init-v4sf-2.c: Likewise.
* gcc.target/i386/sse-init-v4sf-3.c: Likewise.
* gcc.target/i386/sse-init-v4si-1.c: Likewise.
* gcc.target/i386/sse-init-v8hi-1.c: Likewise.
* gcc.target/i386/sse2-init-v16qi-2.c: Likewise.
* gcc.target/i386/sse2-init-v16qi-3.c: Likewise.
* gcc.target/i386/sse2-init-v2df-1.c: Likewise.
* gcc.target/i386/sse2-init-v2df-2.c: Likewise.
* gcc.target/i386/sse2-init-v2di-3.c: Likewise.
* gcc.target/i386/sse2-init-v2di-4.c: Likewise.
* gcc.target/i386/sse2-init-v4sf-1.c: Likewise.
* gcc.target/i386/sse2-init-v4sf-2.c: Likewise.
* gcc.target/i386/sse2-init-v4si-2.c: Likewise.
* gcc.target/i386/sse2-init-v8hi-2.c: Likewise.
* gcc.target/i386/sse4_1-init-v16qi-2.c: Likewise.
* gcc.target/i386/sse4_1-init-v2df-1.c: Likewise.
* gcc.target/i386/sse4_1-init-v2df-2.c: Likewise.
* gcc.target/i386/sse4_1-init-v2di-2.c: Likewise.
* gcc.target/i386/sse4_1-init-v2di-3.c: Likewise.
* gcc.target/i386/sse4_1-init-v4sf-2.c: Likewise.
* gcc.target/i386/sse4_1-init-v4sf-3.c: Likewise.
* gcc.target/i386/sse4_1-init-v4si-2.c: Likewise.

45 files changed:
gcc/config/i386/i386-expand.cc
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/avx-init-v16qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v2df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v2df-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v2di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v2di-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v4sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v4sf-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v4si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-init-v8hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx2-init-v4sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx2-init-v4si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx2-init-v4si-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx512vl-concatv4si-1.c
gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx512vl-init-v4si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v16qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v2df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v2df-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v2di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v2di-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v4sf-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v4sf-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v4si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v8hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v16qi-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v16qi-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v2df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v2di-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v2di-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v4sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v4sf-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v4si-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v8hi-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-2.c [new file with mode: 0644]

index 9a37607146471581cd55c7c80331efc994291bd8..6ddc402e9ad4ea6af784d49a3ea8d9d62f386b58 100644 (file)
@@ -17983,8 +17983,6 @@ bool
 ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
                                     rtx target, rtx var, int one_var)
 {
-  machine_mode vsimode;
-  rtx new_target;
   rtx x, tmp;
   bool use_vector_set = false;
   rtx (*gen_vec_set_0) (rtx, rtx, rtx) = NULL;
@@ -17992,16 +17990,202 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
   switch (mode)
     {
     case E_V2DImode:
-      /* For SSE4.1, we normally use vector set.  But if the second
-        element is zero and inter-unit moves are OK, we use movq
-        instead.  */
-      use_vector_set = (TARGET_64BIT && TARGET_SSE4_1
-                       && !(TARGET_INTER_UNIT_MOVES_TO_VEC
-                            && one_var == 0));
-      break;
-    case E_V16QImode:
+      if (TARGET_64BIT || MEM_P (var))
+       {
+         if (!REG_P (var) && !MEM_P (var))
+           var = force_reg (DImode, var);
+         x = gen_rtx_VEC_CONCAT (V2DImode, var, CONST0_RTX (DImode));
+         if (!one_var)
+           emit_insn (gen_rtx_SET (target, x));
+         else if (TARGET_SSE2)
+           {
+             tmp = gen_reg_rtx (V2DImode);
+             emit_insn (gen_rtx_SET (tmp, x));
+             emit_insn (gen_vec_shl_v2di (target, tmp, GEN_INT (64)));
+           }
+         else
+           {
+             rtx tmp1 = gen_reg_rtx (V2DImode);
+             emit_insn (gen_rtx_SET (tmp1, x));
+             rtx tmp2 = gen_reg_rtx (V4SImode);
+             emit_move_insn (tmp2, gen_lowpart (V4SImode, tmp1));
+             emit_insn (gen_sse_shufps_v4si (tmp2, tmp2, tmp2,
+                                             GEN_INT (2), GEN_INT (3),
+                                             GEN_INT (4), GEN_INT (5)));
+             emit_move_insn (target, gen_lowpart (V2DImode, tmp2));
+           }
+       }
+      else
+       {
+         rtx lo = force_reg (SImode, gen_lowpart (SImode, var));
+         rtx hi = force_reg (SImode, gen_highpart (SImode, var));
+         tmp = gen_reg_rtx (V4SImode);
+         if (TARGET_SSE4_1)
+           {
+             rtx tmp1 = gen_reg_rtx (V4SImode);
+             emit_insn (gen_vec_setv4si_0 (tmp1, CONST0_RTX (V4SImode), lo));
+             emit_insn (gen_sse4_1_pinsrd (tmp, tmp1, hi, GEN_INT (2)));
+           }
+         else
+           {
+             rtx ltmp = gen_reg_rtx (V4SImode);
+             rtx htmp = gen_reg_rtx (V4SImode);
+             emit_insn (gen_vec_setv4si_0 (ltmp, CONST0_RTX (V4SImode), lo));
+             emit_insn (gen_vec_setv4si_0 (htmp, CONST0_RTX (V4SImode), hi));
+             emit_insn (gen_vec_interleave_lowv4si (tmp, ltmp, htmp));
+           }
+         if (!one_var)
+           emit_move_insn (target, gen_lowpart (V2DImode, tmp));
+         else if (TARGET_SSE2)
+           {
+             rtx tmp2 = gen_reg_rtx (V2DImode);
+             emit_move_insn (tmp2, gen_lowpart (V2DImode, tmp));
+             emit_insn (gen_vec_shl_v2di (target, tmp2, GEN_INT (64)));
+           }
+         else
+           {
+             rtx tmp2 = gen_reg_rtx (V2DImode);
+             emit_insn (gen_sse_shufps_v4si (tmp2, tmp, tmp,
+                                             GEN_INT (2), GEN_INT (3),
+                                             GEN_INT (4), GEN_INT (5)));
+             emit_move_insn (target, gen_lowpart (V2DImode, tmp2));
+           }
+       }
+      return true;
+    case E_V2DFmode:
+      if (!REG_P (var) && !MEM_P (var))
+       var = force_reg (DFmode, var);
+      x = gen_rtx_VEC_CONCAT (V2DFmode, var, CONST0_RTX (DFmode));
+      if (one_var)
+       {
+         tmp = gen_reg_rtx (V2DFmode);
+         emit_insn (gen_rtx_SET (tmp, x));
+         emit_insn (gen_vec_shl_v2df (target, tmp, GEN_INT (64)));
+       }
+      else
+       emit_insn (gen_rtx_SET (target, x));
+      return true;
     case E_V4SImode:
+      var = force_reg (SImode, var);
+      x = gen_rtx_VEC_DUPLICATE (V4SImode, var);
+      x = gen_rtx_VEC_MERGE (V4SImode, x, CONST0_RTX (V4SImode), const1_rtx);
+      if (!one_var)
+       emit_insn (gen_rtx_SET (target, x));
+      else if (TARGET_SSE2)
+       {
+         rtx tmp = gen_reg_rtx (V4SImode);
+         emit_insn (gen_rtx_SET (tmp, x));
+         emit_insn (gen_vec_shl_v4si (target, tmp, GEN_INT (one_var * 32)));
+       }
+      else
+       {
+         rtx tmp = gen_reg_rtx (V4SImode);
+         emit_insn (gen_rtx_SET (tmp, x));
+         emit_insn (gen_sse_shufps_v4si (target, tmp, tmp,
+                                         const1_rtx,
+                                         GEN_INT (one_var == 1 ? 0 : 1),
+                                         GEN_INT (one_var == 2 ? 0+4 : 1+4),
+                                         GEN_INT (one_var == 3 ? 0+4 : 1+4)));
+       }
+      return true;
     case E_V4SFmode:
+      var = force_reg (SFmode, var);
+      x = gen_rtx_VEC_DUPLICATE (V4SFmode, var);
+      x = gen_rtx_VEC_MERGE (V4SFmode, x, CONST0_RTX (V4SFmode), const1_rtx);
+      if (!one_var)
+       emit_insn (gen_rtx_SET (target, x));
+      else if (TARGET_SSE2)
+       {
+         rtx tmp = gen_reg_rtx (V4SFmode);
+         emit_insn (gen_rtx_SET (tmp, x));
+         emit_insn (gen_vec_shl_v4sf (target, tmp, GEN_INT (one_var * 32)));
+       }
+      else
+       {
+         rtx tmp = gen_reg_rtx (V4SFmode);
+         emit_insn (gen_rtx_SET (tmp, x));
+         emit_insn (gen_sse_shufps_v4sf (target, tmp, tmp,
+                                         const1_rtx,
+                                         GEN_INT (one_var == 1 ? 0 : 1),
+                                         GEN_INT (one_var == 2 ? 0+4 : 1+4),
+                                         GEN_INT (one_var == 3 ? 0+4 : 1+4)));
+       }
+      return true;
+    case E_V4DImode:
+      if (TARGET_AVX2 && (TARGET_64BIT || MEM_P (var)))
+       {
+         if (!REG_P (var) && !MEM_P (var))
+           var = force_reg (DImode, var);
+         x = gen_rtx_VEC_DUPLICATE (V4DImode, var);
+         x = gen_rtx_VEC_MERGE (V4DImode, x, CONST0_RTX (V4DImode),
+                                const1_rtx);
+         if (one_var)
+           {
+             tmp = gen_reg_rtx (V4DImode);
+             emit_insn (gen_rtx_SET (tmp, x));
+             emit_insn (gen_avx2_permv4di_1 (target, tmp,
+                                             const1_rtx,
+                                             GEN_INT (one_var == 1 ? 0 : 1),
+                                             GEN_INT (one_var == 2 ? 0 : 1),
+                                             GEN_INT (one_var == 3 ? 0 : 1)));
+           }
+         else
+           emit_insn (gen_rtx_SET (target, x));
+       }
+      else
+       {
+         tmp = gen_reg_rtx (V2DImode);
+         if (!ix86_expand_vector_init_one_nonzero (mmx_ok, V2DImode, tmp,
+                                                   var, one_var & 1))
+           gcc_unreachable ();
+         rtx zero = CONST0_RTX (V2DImode);
+         if (one_var >= 2)
+           {
+             zero = force_reg (V2DImode, zero);
+             emit_insn (gen_avx_vec_concatv4di (target, zero, tmp));
+           }
+         else
+           emit_insn (gen_avx_vec_concatv4di (target, tmp, zero));
+       }
+      return true;
+    case E_V4DFmode:
+      if (TARGET_AVX2)
+       {
+         if (!REG_P (var) && !MEM_P (var))
+           var = force_reg (DFmode, var);
+         x = gen_rtx_VEC_DUPLICATE (V4DFmode, var);
+         x = gen_rtx_VEC_MERGE (V4DFmode, x, CONST0_RTX (V4DFmode),
+                                const1_rtx);
+         if (one_var)
+           {
+             tmp = gen_reg_rtx (V4DFmode);
+             emit_insn (gen_rtx_SET (tmp, x));
+             emit_insn (gen_avx2_permv4df_1 (target, tmp,
+                                             const1_rtx,
+                                             GEN_INT (one_var == 1 ? 0 : 1),
+                                             GEN_INT (one_var == 2 ? 0 : 1),
+                                             GEN_INT (one_var == 3 ? 0 : 1)));
+           }
+         else
+           emit_insn (gen_rtx_SET (target, x));
+       }
+      else
+       {
+         tmp = gen_reg_rtx (V2DFmode);
+         if (!ix86_expand_vector_init_one_nonzero (mmx_ok, V2DFmode, tmp,
+                                                   var, one_var & 1))
+           gcc_unreachable ();
+         rtx zero = CONST0_RTX (V2DFmode);
+         if (one_var >= 2)
+           {
+             zero = force_reg (V2DFmode, zero);
+             emit_insn (gen_avx_vec_concatv4df (target, zero, tmp));
+           }
+         else
+           emit_insn (gen_avx_vec_concatv4df (target, tmp, zero));
+       }
+      return true;
+    case E_V16QImode:
       use_vector_set = TARGET_SSE4_1;
       break;
     case E_V8HImode:
@@ -18036,15 +18220,6 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
       use_vector_set = TARGET_AVX;
       gen_vec_set_0 = gen_vec_setv8sf_0;
       break;
-    case E_V4DFmode:
-      use_vector_set = TARGET_AVX;
-      gen_vec_set_0 = gen_vec_setv4df_0;
-      break;
-    case E_V4DImode:
-      /* Use ix86_expand_vector_set in 64bit mode only.  */
-      use_vector_set = TARGET_AVX && TARGET_64BIT;
-      gen_vec_set_0 = gen_vec_setv4di_0;
-      break;
     case E_V16SImode:
       use_vector_set = TARGET_AVX512F && one_var == 0;
       gen_vec_set_0 = gen_vec_setv16si_0;
@@ -18111,9 +18286,12 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
     {
     case E_V2SFmode:
     case E_V2SImode:
-      if (!mmx_ok)
+      if (!mmx_ok || one_var != 0)
        return false;
-      /* FALLTHRU */
+      var = force_reg (GET_MODE_INNER (mode), var);
+      x = gen_rtx_VEC_CONCAT (mode, var, CONST0_RTX (GET_MODE_INNER (mode)));
+      emit_insn (gen_rtx_SET (target, x));
+      return true;
 
     case E_V2DFmode:
     case E_V2DImode:
@@ -18124,82 +18302,92 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
       emit_insn (gen_rtx_SET (target, x));
       return true;
 
-    case E_V4SFmode:
-    case E_V4SImode:
-      if (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
-       new_target = gen_reg_rtx (mode);
+    case E_V8HImode:
+      if (one_var > 1 && !TARGET_SSE2)
+       return false;
+      /* Zero extend the variable element to SImode and recurse.  */
+      var = convert_modes (SImode, HImode, var, true);
+      var = force_reg (SImode, var);
+      if (one_var == 1)
+       {
+         var = simplify_gen_binary (ASHIFT, SImode, var, GEN_INT (16));
+         var = force_reg (SImode, var);
+         one_var = 0;
+       }
       else
-       new_target = target;
-      var = force_reg (GET_MODE_INNER (mode), var);
-      x = gen_rtx_VEC_DUPLICATE (mode, var);
-      x = gen_rtx_VEC_MERGE (mode, x, CONST0_RTX (mode), const1_rtx);
-      emit_insn (gen_rtx_SET (new_target, x));
-      if (one_var != 0)
+       one_var *= 16;
+      x = gen_reg_rtx (V4SImode);
+      if (!ix86_expand_vector_init_one_nonzero (mmx_ok, V4SImode, x, var, 0))
+       gcc_unreachable ();
+      if (one_var)
        {
-         /* We need to shuffle the value to the correct position, so
-            create a new pseudo to store the intermediate result.  */
-
-         /* With SSE2, we can use the integer shuffle insns.  */
-         if (mode != V4SFmode && TARGET_SSE2)
-           {
-             emit_insn (gen_sse2_pshufd_1 (new_target, new_target,
-                                           const1_rtx,
-                                           GEN_INT (one_var == 1 ? 0 : 1),
-                                           GEN_INT (one_var == 2 ? 0 : 1),
-                                           GEN_INT (one_var == 3 ? 0 : 1)));
-             if (target != new_target)
-               emit_move_insn (target, new_target);
-             return true;
-           }
-
-         /* Otherwise convert the intermediate result to V4SFmode and
-            use the SSE1 shuffle instructions.  */
-         if (mode != V4SFmode)
-           {
-             tmp = gen_reg_rtx (V4SFmode);
-             emit_move_insn (tmp, gen_lowpart (V4SFmode, new_target));
-           }
-         else
-           tmp = new_target;
-
-         emit_insn (gen_sse_shufps_v4sf (tmp, tmp, tmp,
-                                      const1_rtx,
-                                      GEN_INT (one_var == 1 ? 0 : 1),
-                                      GEN_INT (one_var == 2 ? 0+4 : 1+4),
-                                      GEN_INT (one_var == 3 ? 0+4 : 1+4)));
-
-         if (mode != V4SFmode)
-           emit_move_insn (target, gen_lowpart (V4SImode, tmp));
-         else if (tmp != target)
-           emit_move_insn (target, tmp);
+         tmp = gen_reg_rtx (V4SImode);
+         emit_insn (gen_vec_shl_v4si (tmp, x, GEN_INT (one_var)));
+         x = tmp;
        }
-      else if (target != new_target)
-       emit_move_insn (target, new_target);
+      emit_move_insn (target, gen_lowpart (mode, x));
       return true;
 
-    case E_V8HImode:
     case E_V16QImode:
-      vsimode = V4SImode;
-      goto widen;
-    case E_V4HImode:
-    case E_V8QImode:
-      if (!mmx_ok)
+      if (one_var > 3 && !TARGET_SSE2)
        return false;
-      vsimode = V2SImode;
-      goto widen;
-    widen:
-      if (one_var != 0)
-       return false;
-
       /* Zero extend the variable element to SImode and recurse.  */
-      var = convert_modes (SImode, GET_MODE_INNER (mode), var, true);
+      var = convert_modes (SImode, QImode, var, true);
+      var = force_reg (SImode, var);
+      if (one_var < 4)
+       {
+         var = simplify_gen_binary (ASHIFT, SImode, var,
+                                    GEN_INT (one_var * 8));
+         var = force_reg (SImode, var);
+         one_var = 0;
+       }
+      else
+       one_var *= 8;
+      x = gen_reg_rtx (V4SImode);
+      if (!ix86_expand_vector_init_one_nonzero (mmx_ok, V4SImode, x, var, 0))
+       gcc_unreachable ();
+      if (one_var)
+       {
+         tmp = gen_reg_rtx (V4SImode);
+         emit_insn (gen_vec_shl_v4si (tmp, x, GEN_INT (one_var)));
+         x = tmp;
+       }
+      emit_move_insn (target, gen_lowpart (V16QImode, x));
+      return true;
 
-      x = gen_reg_rtx (vsimode);
-      if (!ix86_expand_vector_init_one_nonzero (mmx_ok, vsimode, x,
-                                               var, one_var))
+    case E_V4HImode:
+      if (!mmx_ok || one_var > 1)
+       return false;
+      /* Zero extend the variable element to SImode and recurse.  */
+      var = convert_modes (SImode, HImode, var, true);
+      var = force_reg (SImode, var);
+      if (one_var == 1)
+       {
+         var = simplify_gen_binary (ASHIFT, SImode, var, GEN_INT (16));
+         var = force_reg (SImode, var);
+       }
+      x = gen_reg_rtx (V2SImode);
+      if (!ix86_expand_vector_init_one_nonzero (true, V2SImode, x, var, 0))
        gcc_unreachable ();
+      emit_move_insn (target, gen_lowpart (V4HImode, x));
+      return true;
 
-      emit_move_insn (target, gen_lowpart (mode, x));
+    case E_V8QImode:
+      if (!mmx_ok || one_var > 3)
+       return false;
+      /* Zero extend the variable element to SImode and recurse.  */
+      var = convert_modes (SImode, QImode, var, true);
+      var = force_reg (SImode, var);
+      if (one_var)
+       {
+         var = simplify_gen_binary (ASHIFT, SImode, var,
+                                    GEN_INT (one_var * 8));
+         var = force_reg (SImode, var);
+       }
+      x = gen_reg_rtx (V2SImode);
+      if (!ix86_expand_vector_init_one_nonzero (true, V2SImode, x, var, 0))
+       gcc_unreachable ();
+      emit_move_insn (target, gen_lowpart (V8QImode, x));
       return true;
 
     default:
@@ -18630,6 +18818,1060 @@ ix86_expand_vector_init_interleave (machine_mode mode,
     }
 }
 
+/* Count number of non-zero integer constants in OPS array of length N.  */
+
+static int
+nonzero_int_const_count (rtx *ops, int n)
+{
+  int result = 0;
+  int i;
+  for (i = 0; i < n; i++)
+    if (CONST_INT_P (ops[i]) && ops[i] != const0_rtx)
+      result++;
+  return result;
+}
+
+/* Count number of non-zero float constants in OPS array of length N.  */
+
+static int
+nonzero_float_const_count (rtx *ops, int n)
+{
+  int result = 0;
+  int i;
+  for (i = 0; i < n; i++)
+    if (CONST_DOUBLE_P (ops[i]) && ops[i] != CONST0_RTX (SFmode))
+      result++;
+  return result;
+}
+
+/* Count number of non-zero double constants in OPS array of length N.  */
+
+static int
+nonzero_double_const_count (rtx *ops, int n)
+{
+  int result = 0;
+  int i;
+  for (i = 0; i < n; i++)
+    if (CONST_DOUBLE_P (ops[i]) && ops[i] != CONST0_RTX (DFmode))
+      result++;
+  return result;
+}
+
+
+/* A subroutine of ix86_expand_vector_init_general.  Handle the most
+   general case: all values variable and none identical.  */
+
+static void
+ix86_expand_vector_init_insert (machine_mode mode, rtx target,
+                               rtx *ops, int n)
+{
+  machine_mode inner_mode = GET_MODE_INNER (mode);
+  rtx (*pinsr)(rtx, rtx, rtx, rtx);
+  rtx tmp = gen_reg_rtx (mode);
+  rtx var, x;
+  int i;
+
+  var = ops[0];
+
+  switch (mode)
+    {
+    case E_V16QImode:
+      if (var != const0_rtx)
+       {
+         var = convert_modes (SImode, QImode, var, true);
+         var = force_reg (SImode, var);
+         x = gen_reg_rtx (V4SImode);
+         emit_insn (gen_vec_setv4si_0 (x, CONST0_RTX (V4SImode), var));
+         emit_move_insn (tmp, gen_lowpart (V16QImode, x));
+       }
+      else
+       emit_move_insn (tmp, CONST0_RTX (mode));
+      pinsr = gen_sse4_1_pinsrb;
+      break;
+    case E_V8HImode:
+      if (var != const0_rtx)
+       {
+         var = convert_modes (SImode, HImode, var, true);
+         var = force_reg (SImode, var);
+         x = gen_reg_rtx (V4SImode);
+         emit_insn (gen_vec_setv4si_0 (x, CONST0_RTX (V4SImode), var));
+         emit_move_insn (tmp, gen_lowpart (V8HImode, x));
+       }
+      else
+       emit_move_insn (tmp, CONST0_RTX (mode));
+      pinsr = gen_sse2_pinsrw;
+      break;
+    case E_V4SImode:
+      if (var != const0_rtx)
+       {
+         if (!REG_P (var) && !MEM_P (var))
+           var = force_reg (SImode, var);
+         emit_insn (gen_vec_setv4si_0 (tmp, CONST0_RTX (mode), var));
+       }
+      else
+       emit_move_insn (tmp, CONST0_RTX (mode));
+      pinsr = gen_sse4_1_pinsrd;
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  for (i=1; i<n; i++)
+    if (ops[i] != CONST0_RTX (inner_mode))
+      {
+       rtx val = ops[i];
+       if (!REG_P (val) && !MEM_P (val))
+         val = force_reg (inner_mode, val);
+       emit_insn (pinsr (tmp, tmp, val, GEN_INT (1 << i)));
+      }
+  emit_move_insn (target, tmp);
+}
+
+/* Helper function.  Determine if the given OPS array of size N
+   contains only zeros and one other value (possible repeated).
+   If TRUE, *VAR returns the value, PERM[i] contains 0 for
+   this value and 1 for a CONST0_RTX.  */
+
+static bool
+onevar_perm_p (const rtx *ops, int n, int *perm, rtx *var)
+{
+  bool found = false;
+  int i;
+
+  for (i = 0; i < n; i++)
+    if (ops[i] == const0_rtx
+       || ops[i] == CONST0_RTX (SFmode)
+       || ops[i] == CONST0_RTX (DFmode))
+      perm[i] = 1;
+    else if (!found)
+      {
+       *var = ops[i];
+       found = true;
+       perm[i] = 0;
+      }
+    else if (rtx_equal_p (*var, ops[i]))
+      perm[i] = 0;
+    else
+      return false;
+
+  return found;
+}
+
+/* Helper function.  Determine if the given OPS array of size N
+   contains only zeros and two other values (possible repeated).
+   If TRUE, VARS returns the values, PERM[i] contains 0 for
+   the first value, 1 for the second value and 2 for CONST0_RTX.  */
+
+static bool
+twovar_perm_p (const rtx *ops, int n, int *perm, rtx *vars)
+{
+  int count = 0;
+  int i;
+
+  for (i = 0; i < n; i++)
+    if (ops[i] == const0_rtx
+       || ops[i] == CONST0_RTX (SFmode)
+       || ops[i] == CONST0_RTX (DFmode))
+      perm[i] = 2;
+    else if (count == 0)
+      {
+       vars[0] = ops[i];
+       perm[i] = 0;
+       count = 1;
+      }
+    else if (rtx_equal_p (vars[0], ops[i]))
+      perm[i] = 0;
+    else if (count == 1)
+      {
+       vars[1] = ops[i];
+       perm[i] = 1;
+       count = 2;
+      }
+    else if (rtx_equal_p (vars[1], ops[i]))
+      perm[i] = 1;
+    else
+      return false;
+
+  return count == 2;
+}
+
+/* A subroutine of ix86_expand_vector_init for V2DImode.  */
+
+static void
+ix86_expand_vector_init_v2di (rtx target, rtx *ops)
+{
+  if (ops[0] == const0_rtx && ops[1] == const0_rtx)
+    emit_move_insn (target, CONST0_RTX (V2DImode));
+  else if (CONST_INT_P (ops[0]) && CONST_INT_P (ops[1]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V2DImode, gen_rtvec_v (2, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (rtx_equal_p (ops[0], ops[1]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DImode, val);
+      /* TARGET_SSE has *vec_dupv2di.  */
+      emit_move_insn (target, gen_rtx_VEC_DUPLICATE (V2DImode, val));
+    }
+  else
+    {
+      rtx op0 = force_reg (DImode, ops[0]);
+      rtx op1 = force_reg (DImode, ops[1]);
+      emit_insn (gen_vec_concatv2di (target, op0, op1));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V2DFmode.  */
+
+static void
+ix86_expand_vector_init_v2df (rtx target, rtx *ops)
+{
+  if (ops[0] == CONST0_RTX (DFmode)
+      && ops[1] == CONST0_RTX (DFmode))
+    emit_move_insn (target, CONST0_RTX (V2DFmode));
+  else if (CONST_DOUBLE_P (ops[0])
+          && CONST_DOUBLE_P (ops[1]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec_v (2, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (TARGET_SSE2
+          && rtx_equal_p (ops[0], ops[1]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DFmode, val);
+      emit_move_insn (target, gen_rtx_VEC_DUPLICATE (V2DFmode, val));
+    }
+  else
+    {
+      rtx op0 = force_reg (DFmode, ops[0]);
+      rtx op1 = force_reg (DFmode, ops[1]);
+      emit_insn (gen_vec_concatv2df (target, op0, op1));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V4SImode.  */
+
+static void
+ix86_expand_vector_init_v4si (rtx target, rtx *ops)
+{
+  rtx vars[4];
+  int perm[4];
+
+  if (ops[0] == const0_rtx
+      && ops[1] == const0_rtx
+      && ops[2] == const0_rtx
+      && ops[3] == const0_rtx)
+    emit_move_insn (target, CONST0_RTX (V4SImode));
+  else if (ops[1] == const0_rtx
+          && ops[2] == const0_rtx
+          && ops[3] == const0_rtx)
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SImode, val);
+      emit_insn (gen_vec_setv4si_0 (target, CONST0_RTX (V4SImode), val));
+    }
+  else if (rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SImode, val);
+      emit_move_insn (target, gen_rtx_VEC_DUPLICATE (V4SImode, val));
+    }
+  else if (CONST_INT_P (ops[0])
+          && CONST_INT_P (ops[1])
+          && CONST_INT_P (ops[2])
+          && CONST_INT_P (ops[3]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V4SImode, gen_rtvec_v (4, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (onevar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4SImode);
+      vars[1] = const0_rtx;
+      vars[2] = const0_rtx;
+      vars[3] = const0_rtx;
+      ix86_expand_vector_init_v4si (tmp, vars);
+      emit_insn (gen_sse_shufps_v4si (target, tmp, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2] + 4),
+                                     GEN_INT (perm[3] + 4)));
+    }
+  else if (ops[2] == const0_rtx && ops[3] == const0_rtx)
+    {
+      rtx tmp1 = gen_reg_rtx (V4SImode);
+      vars[0] = ops[0];
+      vars[1] = const0_rtx;
+      vars[2] = const0_rtx;
+      vars[3] = const0_rtx;
+      ix86_expand_vector_init_v4si (tmp1, vars);
+
+      if (TARGET_SSE4_1)
+       {
+         rtx val = ops[1];
+         if (!REG_P (val) && !MEM_P (val))
+           val = force_reg (SImode, val);
+         emit_insn (gen_sse4_1_pinsrd (target, tmp1, val, GEN_INT (2)));
+       }
+      else
+       {
+         rtx tmp2 = gen_reg_rtx (V4SImode);
+         vars[0] = ops[1];
+         ix86_expand_vector_init_v4si (tmp2, vars);
+         emit_insn (gen_vec_interleave_lowv4si (target, tmp1, tmp2));
+       }
+    }
+  else if (TARGET_SSE4_1
+          && ops[1] == const0_rtx
+          && (ops[2] == const0_rtx || ops[3] == const0_rtx))
+    /* { a, 0, b, 0 } and { a, 0, 0, b } become mov; pinsrd.  */
+    ix86_expand_vector_init_insert (V4SImode, target, ops, 4);
+  else if (twovar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4SImode);
+      vars[2] = const0_rtx;
+      vars[3] = const0_rtx;
+      ix86_expand_vector_init_v4si (tmp, vars);
+      emit_insn (gen_sse_shufps_v4si (target, tmp, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2] + 4),
+                                     GEN_INT (perm[3] + 4)));
+    }
+  else if (nonzero_int_const_count (ops, 4) >= 2)
+    {
+      rtx csts[4];
+      int i;
+      for (i = 0; i < 4; i++)
+       if (CONST_INT_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = const0_rtx;
+         }
+       else
+         {
+           csts[i] = const0_rtx;
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V4SImode);
+      rtx vec = gen_rtx_CONST_VECTOR (V4SImode, gen_rtvec_v (4, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V4SImode, tmp1, tmp2)));
+    }
+  else if (TARGET_SSE4_1)
+    ix86_expand_vector_init_insert (V4SImode, target, ops, 4);
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V4SImode);
+      rtx tmp2 = gen_reg_rtx (V4SImode);
+      vars[0] = ops[0];
+      vars[1] = ops[1];
+      vars[2] = const0_rtx;
+      vars[3] = const0_rtx;
+      ix86_expand_vector_init_v4si (tmp1, vars);
+      vars[0] = ops[2];
+      vars[1] = ops[3];
+      ix86_expand_vector_init_v4si (tmp2, vars);
+      emit_insn (gen_sse_shufps_v4si (target, tmp1, tmp2,
+                                     const0_rtx, const1_rtx,
+                                     GEN_INT (4), GEN_INT (5)));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V4SFmode.  */
+
+static void
+ix86_expand_vector_init_v4sf (rtx target, rtx *ops)
+{
+  rtx vars[4];
+  int perm[4];
+
+  if (ops[0] == CONST0_RTX (SFmode) 
+      && ops[1] == CONST0_RTX (SFmode)
+      && ops[2] == CONST0_RTX (SFmode)
+      && ops[3] == CONST0_RTX (SFmode))
+    emit_move_insn (target, CONST0_RTX (V4SFmode));
+  else if (ops[1] == CONST0_RTX (SFmode)
+          && ops[2] == CONST0_RTX (SFmode)
+          && ops[3] == CONST0_RTX (SFmode))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SFmode, val);
+      emit_insn (gen_vec_setv4sf_0 (target, CONST0_RTX (V4SFmode), val));
+    }
+  else if (rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SFmode, val);
+      emit_move_insn (target, gen_rtx_VEC_DUPLICATE (V4SFmode, val));
+    }
+  else if (CONST_DOUBLE_P (ops[0])
+          && CONST_DOUBLE_P (ops[1])
+          && CONST_DOUBLE_P (ops[2])
+          && CONST_DOUBLE_P (ops[3]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec_v (4, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (onevar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4SFmode);
+      vars[1] = CONST0_RTX (SFmode);
+      vars[2] = CONST0_RTX (SFmode);
+      vars[3] = CONST0_RTX (SFmode);
+      ix86_expand_vector_init_v4sf (tmp, vars);
+      emit_insn (gen_sse_shufps_v4sf (target, tmp, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2] + 4),
+                                     GEN_INT (perm[3] + 4)));
+    }
+  else if (ops[2] == CONST0_RTX (SFmode)
+          && ops[3] == CONST0_RTX (SFmode))
+    {
+      rtx tmp1 = gen_reg_rtx (V4SFmode);
+      vars[0] = ops[0];
+      vars[1] = CONST0_RTX (SFmode);
+      vars[2] = CONST0_RTX (SFmode);
+      vars[3] = CONST0_RTX (SFmode);
+      ix86_expand_vector_init_v4sf (tmp1, vars);
+
+      rtx tmp2 = gen_reg_rtx (V4SFmode);
+      vars[0] = ops[1];
+      ix86_expand_vector_init_v4sf (tmp2, vars);
+      emit_insn (gen_vec_interleave_lowv4sf (target, tmp1, tmp2));
+    }
+  else if (twovar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4SFmode);
+      vars[2] = CONST0_RTX (SFmode);
+      vars[3] = CONST0_RTX (SFmode);
+      ix86_expand_vector_init_v4sf (tmp, vars);
+      emit_insn (gen_sse_shufps_v4sf (target, tmp, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2] + 4),
+                                     GEN_INT (perm[3] + 4)));
+    }
+  else if (nonzero_float_const_count (ops, 4) >= 2)
+    {
+      rtx csts[4];
+      int i;
+      for (i = 0; i < 4; i++)
+       if (CONST_DOUBLE_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = CONST0_RTX (SFmode);
+         }
+       else
+         {
+           csts[i] = CONST0_RTX (SFmode);
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V4SFmode);
+      rtx vec = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec_v (4, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V4SFmode, tmp1, tmp2)));
+    }
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V4SFmode);
+      rtx tmp2 = gen_reg_rtx (V4SFmode);
+      vars[0] = ops[0];
+      vars[1] = ops[1];
+      vars[2] = CONST0_RTX (SFmode);
+      vars[3] = CONST0_RTX (SFmode);
+      ix86_expand_vector_init_v4sf (tmp1, vars);
+      vars[0] = ops[2];
+      vars[1] = ops[3];
+      ix86_expand_vector_init_v4sf (tmp2, vars);
+      emit_insn (gen_sse_shufps_v4sf (target, tmp1, tmp2,
+                                     const0_rtx, const1_rtx,
+                                     GEN_INT (4), GEN_INT (5)));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V8HImode.  */
+
+static bool
+ix86_expand_vector_init_v8hi (rtx target, rtx *ops)
+{
+  rtx vars[8];
+  int i;
+
+  bool all_zero_p = true;
+  for (i = 0; i < 8; i++)
+    if (ops[i] != const0_rtx)
+      {
+       all_zero_p = false;
+       break;
+      }
+  if (all_zero_p)
+    {
+      emit_move_insn (target, CONST0_RTX (V8HImode));
+      return true;
+    }
+
+  bool all_const_p = true;
+  for (i = 0; i < 8; i++)
+    if (!CONST_INT_P (ops[i]))
+      {
+       all_const_p = false;
+       break;
+      }
+  if (all_const_p)
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V8HImode, gen_rtvec_v (8, ops));
+      emit_move_insn (target, vec);
+      return true;
+    }
+
+  if (TARGET_SSE2
+      && nonzero_int_const_count (ops, 8) >= 2)
+    {
+      rtx csts[8];
+      for (i = 0; i < 8; i++)
+       if (CONST_INT_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = const0_rtx;
+         }
+       else
+         {
+           csts[i] = const0_rtx;
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V8HImode);
+      if (!ix86_expand_vector_init_v8hi (tmp1, vars))
+        gcc_unreachable ();
+      rtx tmp2 = gen_reg_rtx (V8HImode);
+      rtx vec = gen_rtx_CONST_VECTOR (V8HImode, gen_rtvec_v (8, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V8HImode, tmp1, tmp2)));
+      return true;
+    }
+
+  if (TARGET_SSE2)
+    {
+      ix86_expand_vector_init_insert (V8HImode, target, ops, 8);
+      return true;
+    }
+  return false;
+}
+
+/* A subroutine of ix86_expand_vector_init for V16QImode.  */
+
+static bool
+ix86_expand_vector_init_v16qi (rtx target, rtx *ops)
+{
+  rtx vars[16];
+  int i;
+
+  bool all_zero_p = true;
+  for (i = 0; i < 16; i++)
+    if (ops[i] != const0_rtx)
+      {
+       all_zero_p = false;
+       break;
+      }
+  if (all_zero_p)
+    {
+      emit_move_insn (target, CONST0_RTX (V16QImode));
+      return true;
+    }
+
+  bool all_const_p = true;
+  for (i = 0; i < 16; i++)
+    if (!CONST_INT_P (ops[i]))
+      {
+       all_const_p = false;
+       break;
+      }
+  if (all_const_p)
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, ops));
+      emit_move_insn (target, vec);
+      return true;
+    }
+
+  if (TARGET_SSE4_1
+      && nonzero_int_const_count (ops, 16) >= 2)
+    {
+      rtx csts[16];
+      for (i = 0; i < 16; i++)
+       if (CONST_INT_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = const0_rtx;
+         }
+       else
+         {
+           csts[i] = const0_rtx;
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V16QImode);
+      if (!ix86_expand_vector_init_v16qi (tmp1, vars))
+       gcc_unreachable ();
+      rtx tmp2 = gen_reg_rtx (V16QImode);
+      rtx vec = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V16QImode, tmp1, tmp2)));
+      return true;
+    }
+
+  if (TARGET_SSE4_1)
+    {
+      ix86_expand_vector_init_insert (V16QImode, target, ops, 16);
+      return true;
+    }
+  return false;
+}
+
+/* A subroutine of ix86_expand_vector_init for V4DImode.  */
+
+static void
+ix86_expand_vector_init_v4di (rtx target, rtx *ops)
+{
+  rtx vars[4];
+  int perm[4];
+
+  if (ops[0] == const0_rtx
+      && ops[1] == const0_rtx
+      && ops[2] == const0_rtx
+      && ops[3] == const0_rtx)
+    emit_move_insn (target, CONST0_RTX (V4DImode));
+  else if (ops[1] == const0_rtx
+          && ops[2] == const0_rtx
+          && ops[3] == const0_rtx)
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DImode, val);
+      emit_insn (gen_vec_setv4di_0 (target, CONST0_RTX (V4DImode), val));
+    }
+  else if ((TARGET_64BIT || MEM_P (ops[0]))
+          && rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DImode, val);
+      emit_insn (gen_vec_dupv4di (target, val));
+    }
+  else if (CONST_INT_P (ops[0])
+          && CONST_INT_P (ops[1])
+          && CONST_INT_P (ops[2])
+          && CONST_INT_P (ops[3]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V4DImode, gen_rtvec_v (4, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (TARGET_AVX2 
+          && onevar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4DImode);
+      vars[1] = const0_rtx;
+      vars[2] = const0_rtx;
+      vars[3] = const0_rtx;
+      ix86_expand_vector_init_v4di (tmp, vars);
+      emit_insn (gen_avx2_permv4di_1 (target, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2]),
+                                     GEN_INT (perm[3])));
+    }
+  else if (rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[1], ops[3]))
+    {
+      rtx tmp = gen_reg_rtx (V2DImode);
+      ix86_expand_vector_init_v2di (tmp, ops);
+      emit_insn (gen_avx_vec_concatv4di (target, tmp, tmp));
+    }
+  else if (nonzero_int_const_count (ops, 4) >= 2)
+    {
+      rtx csts[4];
+      int i;
+      for (i = 0; i < 4; i++)
+       if (CONST_INT_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = const0_rtx;
+         }
+       else
+         {
+           csts[i] = const0_rtx;
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V4DImode);
+      ix86_expand_vector_init_v4di (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V4DImode);
+      rtx vec = gen_rtx_CONST_VECTOR (V4DImode, gen_rtvec_v (4, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V4DImode, tmp1, tmp2)));
+    }
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V2DImode);
+      ix86_expand_vector_init_v2di (tmp1, ops);
+      rtx tmp2 = gen_reg_rtx (V2DImode);
+      ix86_expand_vector_init_v2di (tmp2, ops + 2);
+      emit_insn (gen_avx_vec_concatv4di (target, tmp1, tmp2));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V4DFmode.  */
+
+static void
+ix86_expand_vector_init_v4df (rtx target, rtx *ops)
+{
+  rtx vars[4];
+  int perm[4];
+
+  if (ops[0] == CONST0_RTX (DFmode)
+      && ops[1] == CONST0_RTX (DFmode)
+      && ops[2] == CONST0_RTX (DFmode)
+      && ops[3] == CONST0_RTX (DFmode))
+    emit_move_insn (target, CONST0_RTX (V4DFmode));
+  else if (ops[1] == CONST0_RTX (DFmode)
+          && ops[2] == CONST0_RTX (DFmode)
+          && ops[3] == CONST0_RTX (DFmode))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DFmode, val);
+      emit_insn (gen_vec_setv4df_0 (target, CONST0_RTX (V4DFmode), val));
+    }
+  else if (rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (DFmode, val);
+      emit_insn (gen_vec_dupv4df (target, val));
+    }
+  else if (CONST_DOUBLE_P (ops[0])
+          && CONST_DOUBLE_P (ops[1])
+          && CONST_DOUBLE_P (ops[2])
+          && CONST_DOUBLE_P (ops[3]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V4DFmode, gen_rtvec_v (4, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (TARGET_AVX2 
+          && onevar_perm_p (ops, 4, perm, vars))
+    {
+      rtx tmp = gen_reg_rtx (V4DFmode);
+      vars[1] = CONST0_RTX (DFmode);
+      vars[2] = CONST0_RTX (DFmode);
+      vars[3] = CONST0_RTX (DFmode);
+      ix86_expand_vector_init_v4df (tmp, vars);
+      emit_insn (gen_avx2_permv4df_1 (target, tmp,
+                                     GEN_INT (perm[0]),
+                                     GEN_INT (perm[1]),
+                                     GEN_INT (perm[2]),
+                                     GEN_INT (perm[3])));
+    }
+  else if (rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[1], ops[3]))
+    {
+      rtx tmp = gen_reg_rtx (V2DFmode);
+      ix86_expand_vector_init_v2df (tmp, ops);
+      emit_insn (gen_avx_vec_concatv4df (target, tmp, tmp));
+    }
+  else if (nonzero_double_const_count (ops, 4) >= 2)
+    {
+      rtx csts[4];
+      int i;
+      for (i = 0; i < 4; i++)
+       if (CONST_DOUBLE_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = CONST0_RTX (DFmode);
+         }
+       else
+         {
+           csts[i] = CONST0_RTX (DFmode);
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V4DFmode);
+      ix86_expand_vector_init_v4df (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V4DFmode);
+      rtx vec = gen_rtx_CONST_VECTOR (V4DFmode, gen_rtvec_v (4, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V4DFmode, tmp1, tmp2)));
+    }
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V2DFmode);
+      ix86_expand_vector_init_v2df (tmp1, ops);
+      rtx tmp2 = gen_reg_rtx (V2DFmode);
+      ix86_expand_vector_init_v2df (tmp2, ops + 2);
+      emit_insn (gen_avx_vec_concatv4df (target, tmp1, tmp2));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V8SImode.  */
+
+static void
+ix86_expand_vector_init_v8si (rtx target, rtx *ops)
+{
+  rtx vars[8];
+
+  if (ops[0] == const0_rtx
+      && ops[1] == const0_rtx
+      && ops[2] == const0_rtx
+      && ops[3] == const0_rtx
+      && ops[4] == const0_rtx
+      && ops[5] == const0_rtx
+      && ops[6] == const0_rtx
+      && ops[7] == const0_rtx)
+    emit_move_insn (target, CONST0_RTX (V8SImode));
+  else if (ops[1] == const0_rtx
+          && ops[2] == const0_rtx
+          && ops[3] == const0_rtx
+          && ops[4] == const0_rtx
+          && ops[5] == const0_rtx
+          && ops[6] == const0_rtx
+          && ops[7] == const0_rtx)
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SImode, val);
+      emit_insn (gen_vec_setv8si_0 (target, CONST0_RTX (V8SImode), val));
+    }
+  else if (rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3])
+          && rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[0], ops[5])
+          && rtx_equal_p (ops[0], ops[6])
+          && rtx_equal_p (ops[0], ops[7]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SImode, val);
+      emit_insn (gen_vec_dupv8si (target, val));
+    }
+  else if (TARGET_AVX2
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[0], ops[6])
+          && rtx_equal_p (ops[1], ops[3])
+          && rtx_equal_p (ops[1], ops[5])
+          && rtx_equal_p (ops[1], ops[7]))
+    {
+      rtx tmp_ops[4] = { ops[0], ops[1], const0_rtx, const0_rtx };
+      rtx tmp1 = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp1, tmp_ops);
+      tmp1 = gen_lowpart (V2DImode, tmp1);
+      rtx tmp2 = gen_reg_rtx (V4DImode);
+      emit_insn (gen_avx2_pbroadcastv4di (tmp2, tmp1));
+      emit_move_insn (target, gen_lowpart (V8SImode, tmp2));
+    }
+  else if (ops[4] == const0_rtx
+          && ops[5] == const0_rtx
+          && ops[6] == const0_rtx
+          && ops[7] == const0_rtx)
+    {
+      rtx tmp = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp, ops);
+      emit_insn (gen_avx_vec_concatv8si (target, tmp, CONST0_RTX (V4SImode)));
+    }
+  else if (CONST_INT_P (ops[0])
+          && CONST_INT_P (ops[1])
+          && CONST_INT_P (ops[2])
+          && CONST_INT_P (ops[3])
+          && CONST_INT_P (ops[4])
+          && CONST_INT_P (ops[5])
+          && CONST_INT_P (ops[6])
+          && CONST_INT_P (ops[7]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[1], ops[5])
+          && rtx_equal_p (ops[2], ops[6])
+          && rtx_equal_p (ops[3], ops[7]))
+    {
+      rtx tmp = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp, ops);
+      emit_insn (gen_avx_vec_concatv8si (target, tmp, tmp));
+    }
+  else if (nonzero_int_const_count (ops, 8) >= 2)
+    {
+      rtx csts[8];
+      int i;
+      for (i = 0; i < 8; i++)
+       if (CONST_INT_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = const0_rtx;
+         }
+       else
+         {
+           csts[i] = const0_rtx;
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V8SImode);
+      ix86_expand_vector_init_v8si (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V8SImode);
+      rtx vec = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V8SImode, tmp1, tmp2)));
+    }
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp1, ops);
+      rtx tmp2 = gen_reg_rtx (V4SImode);
+      ix86_expand_vector_init_v4si (tmp2, ops + 4);
+      emit_insn (gen_avx_vec_concatv8si (target, tmp1, tmp2));
+    }
+}
+
+/* A subroutine of ix86_expand_vector_init for V8SFmode.  */
+
+static void
+ix86_expand_vector_init_v8sf (rtx target, rtx *ops)
+{
+  rtx vars[8];
+
+  if (ops[0] == CONST0_RTX (SFmode)
+      && ops[1] == CONST0_RTX (SFmode)
+      && ops[2] == CONST0_RTX (SFmode)
+      && ops[3] == CONST0_RTX (SFmode)
+      && ops[4] == CONST0_RTX (SFmode)
+      && ops[5] == CONST0_RTX (SFmode)
+      && ops[6] == CONST0_RTX (SFmode)
+      && ops[7] == CONST0_RTX (SFmode))
+    emit_move_insn (target, CONST0_RTX (V8SFmode));
+  else if (ops[1] == CONST0_RTX (SFmode)
+          && ops[2] == CONST0_RTX (SFmode)
+          && ops[3] == CONST0_RTX (SFmode)
+          && ops[4] == CONST0_RTX (SFmode)
+          && ops[5] == CONST0_RTX (SFmode)
+          && ops[6] == CONST0_RTX (SFmode)
+          && ops[7] == CONST0_RTX (SFmode))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SFmode, val);
+      emit_insn (gen_vec_setv8sf_0 (target, CONST0_RTX (V8SFmode), val));
+    }
+  else if (TARGET_AVX2
+          && rtx_equal_p (ops[0], ops[1])
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[3])
+          && rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[0], ops[5])
+          && rtx_equal_p (ops[0], ops[6])
+          && rtx_equal_p (ops[0], ops[7]))
+    {
+      rtx val = ops[0];
+      if (!REG_P (val) && !MEM_P (val))
+       val = force_reg (SFmode, val);
+      emit_insn (gen_avx2_vec_dupv8sf_1 (target, val));
+    }
+  else if (TARGET_AVX2
+          && rtx_equal_p (ops[0], ops[2])
+          && rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[0], ops[6])
+          && rtx_equal_p (ops[1], ops[3])
+          && rtx_equal_p (ops[1], ops[5])
+          && rtx_equal_p (ops[1], ops[7]))
+    {
+      rtx tmp_ops[4] = { ops[0], ops[1], CONST0_RTX (SFmode),
+                                        CONST0_RTX (SFmode) };
+      rtx tmp1 = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp1, tmp_ops);
+      tmp1 = gen_lowpart (V2DImode, tmp1);
+      rtx tmp2 = gen_reg_rtx (V4DImode);
+      emit_insn (gen_avx2_pbroadcastv4di (tmp2, tmp1));
+      emit_move_insn (target, gen_lowpart (V8SFmode, tmp2));
+    }
+  else if (ops[4] == CONST0_RTX (SFmode)
+          && ops[5] == CONST0_RTX (SFmode)
+          && ops[6] == CONST0_RTX (SFmode)
+          && ops[7] == CONST0_RTX (SFmode))
+    {
+      rtx tmp = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp, ops);
+      emit_insn (gen_avx_vec_concatv8sf (target, tmp, CONST0_RTX (V4SFmode)));
+    }
+  else if (CONST_DOUBLE_P (ops[0])
+          && CONST_DOUBLE_P (ops[1])
+          && CONST_DOUBLE_P (ops[2])
+          && CONST_DOUBLE_P (ops[3])
+          && CONST_DOUBLE_P (ops[4])
+          && CONST_DOUBLE_P (ops[5])
+          && CONST_DOUBLE_P (ops[6])
+          && CONST_DOUBLE_P (ops[7]))
+    {
+      rtx vec = gen_rtx_CONST_VECTOR (V8SFmode, gen_rtvec_v (8, ops));
+      emit_move_insn (target, vec);
+    }
+  else if (rtx_equal_p (ops[0], ops[4])
+          && rtx_equal_p (ops[1], ops[5])
+          && rtx_equal_p (ops[2], ops[6])
+          && rtx_equal_p (ops[3], ops[7]))
+    {
+      rtx tmp = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp, ops);
+      emit_insn (gen_avx_vec_concatv8sf (target, tmp, tmp));
+    }
+  else if (nonzero_float_const_count (ops, 8) >= 2)
+    {
+      rtx csts[8];
+      int i;
+      for (i = 0; i < 8; i++)
+       if (CONST_DOUBLE_P (ops[i]))
+         {
+           csts[i] = ops[i];
+           vars[i] = CONST0_RTX (SFmode);
+         }
+       else
+         {
+           csts[i] = CONST0_RTX (SFmode);
+           vars[i] = ops[i];
+         }
+      rtx tmp1 = gen_reg_rtx (V8SFmode);
+      ix86_expand_vector_init_v8sf (tmp1, vars);
+      rtx tmp2 = gen_reg_rtx (V8SFmode);
+      rtx vec = gen_rtx_CONST_VECTOR (V8SFmode, gen_rtvec_v (8, csts));
+      emit_move_insn (tmp2, vec);
+      emit_insn (gen_rtx_SET (target, gen_rtx_IOR (V8SFmode, tmp1, tmp2)));
+    }
+  else
+    {
+      rtx tmp1 = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp1, ops);
+      rtx tmp2 = gen_reg_rtx (V4SFmode);
+      ix86_expand_vector_init_v4sf (tmp2, ops + 4);
+      emit_insn (gen_avx_vec_concatv8sf (target, tmp1, tmp2));
+    }
+}
+
+
 /* A subroutine of ix86_expand_vector_init.  Handle the most general case:
    all values variable, and none identical.  */
 
@@ -18645,6 +19887,68 @@ ix86_expand_vector_init_general (bool mmx_ok, machine_mode mode,
 
   switch (mode)
     {
+    case E_V2DImode:
+      ops[0] = XVECEXP (vals, 0, 0);
+      ops[1] = XVECEXP (vals, 0, 1);
+      ix86_expand_vector_init_v2di (target, ops);
+      return;
+
+    case E_V2DFmode:
+      ops[0] = XVECEXP (vals, 0, 0);
+      ops[1] = XVECEXP (vals, 0, 1);
+      ix86_expand_vector_init_v2df (target, ops);
+      return;
+
+    case E_V4SImode:
+      for (i = 0; i < 4; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v4si (target, ops);
+      return;
+
+    case E_V4SFmode:
+      for (i = 0; i < 4; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v4sf (target, ops);
+      return;
+
+    case E_V8HImode:
+      for (i = 0; i < 8; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      if (ix86_expand_vector_init_v8hi (target, ops))
+       return;
+      break;
+
+    case E_V16QImode:
+      for (i = 0; i < 16; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      if (ix86_expand_vector_init_v16qi (target, ops))
+       return;
+      break;
+
+    case E_V4DImode:
+      for (i = 0; i < 4; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v4di (target,ops);
+      return;
+
+    case E_V4DFmode:
+      for (i = 0; i < 4; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v4df (target,ops);
+      return;
+
+    case E_V8SImode:
+      for (i = 0; i < 8; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v8si (target,ops);
+      return;
+
+    case E_V8SFmode:
+      for (i = 0; i < 8; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      ix86_expand_vector_init_v8sf (target,ops);
+      return;
+
     case E_V2SFmode:
     case E_V2SImode:
       if (!mmx_ok && !TARGET_SSE)
@@ -18655,14 +19959,6 @@ ix86_expand_vector_init_general (bool mmx_ok, machine_mode mode,
     case E_V16SFmode:
     case E_V8DFmode:
     case E_V8DImode:
-    case E_V8SFmode:
-    case E_V8SImode:
-    case E_V4DFmode:
-    case E_V4DImode:
-    case E_V4SFmode:
-    case E_V4SImode:
-    case E_V2DFmode:
-    case E_V2DImode:
       n = GET_MODE_NUNITS (mode);
       for (i = 0; i < n; i++)
        ops[i] = XVECEXP (vals, 0, i);
@@ -18761,24 +20057,8 @@ quarter:
       emit_insn (gen_rtx_SET (target, gen_rtx_VEC_CONCAT (mode, op4, op5)));
       return;
 
-    case E_V16QImode:
-      if (!TARGET_SSE4_1)
-       break;
-      /* FALLTHRU */
-
-    case E_V8HImode:
-      if (!TARGET_SSE2)
-       break;
-
-      /* Don't use ix86_expand_vector_init_interleave if we can't
-        move from GPR to SSE register directly.  */
-      if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
-       break;
-      /* FALLTHRU */
-
     case E_V8HFmode:
     case E_V8BFmode:
-
       n = GET_MODE_NUNITS (mode);
       for (i = 0; i < n; i++)
        ops[i] = XVECEXP (vals, 0, i);
index bd6ce2ac70c8a6930f52f9cb1161254220921ec3..7d71f8ba54628e8b1262868559215260654edb68 100644 (file)
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "TI")])
 
+(define_insn "*vec_interleave_lowv4si_sse"
+  [(set (match_operand:V4SI 0 "register_operand" "=x")
+       (vec_select:V4SI
+         (vec_concat:V8SI
+           (match_operand:V4SI 1 "register_operand" "0")
+           (match_operand:V4SI 2 "vector_operand" "xBm"))
+         (parallel [(const_int 0) (const_int 4)
+                    (const_int 1) (const_int 5)])))]
+  "TARGET_SSE && !TARGET_SSE2"
+  "unpcklps\t{%2, %0|%0, %2}"
+  [(set_attr "isa" "noavx")
+   (set_attr "type" "sselog")
+   (set_attr "prefix" "orig")
+   (set_attr "mode" "V4SF")])
+
 (define_expand "vec_interleave_high<mode>"
   [(match_operand:VI_256 0 "register_operand")
    (match_operand:VI_256 1 "register_operand")
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v16qi-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v16qi-1.c
new file mode 100644 (file)
index 0000000..f608d09
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef char v16qi __attribute__ ((__vector_size__ (16)));
+
+char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+v16qi fa000000000000000() { return (v16qi){a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0a00000000000000() { return (v16qi){0,a,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00a0000000000000() { return (v16qi){0,0,a,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000a000000000000() { return (v16qi){0,0,0,a,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000a00000000000() { return (v16qi){0,0,0,0,a,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00000a0000000000() { return (v16qi){0,0,0,0,0,a,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000000a000000000() { return (v16qi){0,0,0,0,0,0,a,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000000a00000000() { return (v16qi){0,0,0,0,0,0,0,a,0,0,0,0,0,0,0,0}; }
+v16qi f00000000a0000000() { return (v16qi){0,0,0,0,0,0,0,0,a,0,0,0,0,0,0,0}; }
+v16qi f000000000a000000() { return (v16qi){0,0,0,0,0,0,0,0,0,a,0,0,0,0,0,0}; }
+v16qi f0000000000a00000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,a,0,0,0,0,0}; }
+v16qi f00000000000a0000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,a,0,0,0,0}; }
+v16qi f000000000000a000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,a,0,0,0}; }
+v16qi f0000000000000a00() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,a,0,0}; }
+v16qi f00000000000000a0() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,a,0}; }
+v16qi f000000000000000a() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,a}; }
+
+v16qi fabcdefghijklmnop() { return (v16qi){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}; }
+
+/* { dg-final { scan-assembler-times "vpxor" 16 } } */
+/* { dg-final { scan-assembler-times "vpinsrb" 31 } } */
+/* { dg-final { scan-assembler-times "movzbl" 1 } } */
+/* { dg-final { scan-assembler-times "vmovd" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v2df-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v2df-1.c
new file mode 100644 (file)
index 0000000..c57b838
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -mavx2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovq" 4 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vmovddup" 2 } } */
+/* { dg-final { scan-assembler-times "vunpcklpd" 1 } } */
+/* { dg-final { scan-assembler-times "vmovsd" 1 } } */
+/* { dg-final { scan-assembler-times "vmovhpd" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v2df-2.c b/gcc/testsuite/gcc.target/i386/avx-init-v2df-2.c
new file mode 100644 (file)
index 0000000..4f2db81
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovq" 4 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vmovddup" 2 } } */
+/* { dg-final { scan-assembler-times "vmovsd" 2 } } */
+/* { dg-final { scan-assembler-times "vmovhpd" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v2di-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v2di-1.c
new file mode 100644 (file)
index 0000000..c898832
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovq" 7 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vpunpcklqdq" 1 } } */
+/* { dg-final { scan-assembler-times "vpinsrq" 2 } } */
+/* { dg-final { scan-assembler-times "vmovddup" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v2di-2.c b/gcc/testsuite/gcc.target/i386/avx-init-v2di-2.c
new file mode 100644 (file)
index 0000000..22ca6b5
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovd\[ \t\]" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 2 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vmovddup" 2 } } */
+/* { dg-final { scan-assembler-times "vmovq" 4 } } */
+/* { dg-final { scan-assembler-times "vmovhps" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v4sf-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v4sf-1.c
new file mode 100644 (file)
index 0000000..a1f63c6
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vinsertps" 16 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 3 } } */
+/* { dg-final { scan-assembler-times "vmovlhps" 4 } } */
+/* { dg-final { scan-assembler-times "vunpcklps" 5 } } */
+/* { dg-final { scan-assembler-times "vmovss" 2 } } */
+/* { dg-final { scan-assembler-times "vbroadcastss" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v4sf-2.c b/gcc/testsuite/gcc.target/i386/avx-init-v4sf-2.c
new file mode 100644 (file)
index 0000000..6d3ff17
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vmovss" 18 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 2 } } */
+/* { dg-final { scan-assembler-times "vmovlhps" 4 } } */
+/* { dg-final { scan-assembler-times "vbroadcastss" 2 } } */
+/* { dg-final { scan-assembler-times "vunpcklps" 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v4si-1.c
new file mode 100644 (file)
index 0000000..a551031
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vmovd" 14 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 4 } } */
+/* { dg-final { scan-assembler-times "vpshufd" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 6 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-init-v8hi-1.c b/gcc/testsuite/gcc.target/i386/avx-init-v8hi-1.c
new file mode 100644 (file)
index 0000000..b8f9f67
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef short v8hi __attribute__ ((__vector_size__ (16)));
+
+short a, b, c, d, e, f, g, h;
+
+v8hi fa0000000() { return (v8hi){a,0,0,0,0,0,0,0}; }
+v8hi f0a000000() { return (v8hi){0,a,0,0,0,0,0,0}; }
+v8hi f00a00000() { return (v8hi){0,0,a,0,0,0,0,0}; }
+v8hi f000a0000() { return (v8hi){0,0,0,a,0,0,0,0}; }
+v8hi f0000a000() { return (v8hi){0,0,0,0,a,0,0,0}; }
+v8hi f00000a00() { return (v8hi){0,0,0,0,0,a,0,0}; }
+v8hi f000000a0() { return (v8hi){0,0,0,0,0,0,a,0}; }
+v8hi f0000000a() { return (v8hi){0,0,0,0,0,0,0,a}; }
+v8hi fabcdefgh() { return (v8hi){a,b,c,d,e,f,g,h}; }
+
+/* { dg-final { scan-assembler-times "pxor" 8 } } */
+/* { dg-final { scan-assembler-times "pinsrw" 15 } } */
+/* { dg-final { scan-assembler-times "movzwl" 1 } } */
+/* { dg-final { scan-assembler-times "movd" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx2-init-v4sf-1.c b/gcc/testsuite/gcc.target/i386/avx2-init-v4sf-1.c
new file mode 100644 (file)
index 0000000..23ff0e7
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx2 -mno-avx512vl" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vinsertps" 16 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 2 } } */
+/* { dg-final { scan-assembler-times "vmovlhps" 4 } } */
+/* { dg-final { scan-assembler-times "vunpcklps" 5 } } */
+/* { dg-final { scan-assembler-times "vmovss" 2 } } */
+/* { dg-final { scan-assembler-times "vbroadcastss" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx2-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/avx2-init-v4si-1.c
new file mode 100644 (file)
index 0000000..02bc7b0
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx2 -mno-avx512vl" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vmovd" 13 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 6 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx2-init-v4si-2.c b/gcc/testsuite/gcc.target/i386/avx2-init-v4si-2.c
new file mode 100644 (file)
index 0000000..3f68d5c
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx2 -mno-avx512vl" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vmovd" 12 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 6 } } */
+
index 88d4682278c2c9061faca94954363d566edcdcaa..30744c4c2241308e681fb402c9a51c7560b61256 100644 (file)
@@ -20,4 +20,5 @@ f2 (V x, V *y)
   asm volatile ("" : "+v" (c));
 }
 
-/* { dg-final { scan-assembler-times "vpunpcklqdq\[^\n\r]*xmm16" 2 } } */
+/* { dg-final { scan-assembler-times "vpunpcklqdq\[^\n\r]*xmm16" 1 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-1.c
new file mode 100644 (file)
index 0000000..12a7388
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovq" 6 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrq" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-2.c
new file mode 100644 (file)
index 0000000..18807b3
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "vmovd\[ \t\]" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 2 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 2 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastq" 2 } } */
+/* { dg-final { scan-assembler-times "vmovq" 4 } } */
+/* { dg-final { scan-assembler-times "vmovhps" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-init-v4si-1.c
new file mode 100644 (file)
index 0000000..65af665
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "vmovd" 12 } } */
+/* { dg-final { scan-assembler-times "vpslldq" 3 } } */
+/* { dg-final { scan-assembler-times "vshufps" 4 } } */
+/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */
+/* { dg-final { scan-assembler-times "vpinsrd" 6 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v16qi-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v16qi-1.c
new file mode 100644 (file)
index 0000000..244dda3
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef char v16qi __attribute__ ((__vector_size__ (16)));
+
+char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+v16qi fa000000000000000() { return (v16qi){a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0a00000000000000() { return (v16qi){0,a,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00a0000000000000() { return (v16qi){0,0,a,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000a000000000000() { return (v16qi){0,0,0,a,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000a00000000000() { return (v16qi){0,0,0,0,a,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00000a0000000000() { return (v16qi){0,0,0,0,0,a,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000000a000000000() { return (v16qi){0,0,0,0,0,0,a,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000000a00000000() { return (v16qi){0,0,0,0,0,0,0,a,0,0,0,0,0,0,0,0}; }
+v16qi f00000000a0000000() { return (v16qi){0,0,0,0,0,0,0,0,a,0,0,0,0,0,0,0}; }
+v16qi f000000000a000000() { return (v16qi){0,0,0,0,0,0,0,0,0,a,0,0,0,0,0,0}; }
+v16qi f0000000000a00000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,a,0,0,0,0,0}; }
+v16qi f00000000000a0000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,a,0,0,0,0}; }
+v16qi f000000000000a000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,a,0,0,0}; }
+v16qi f0000000000000a00() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,a,0,0}; }
+v16qi f00000000000000a0() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,a,0}; }
+v16qi f000000000000000a() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,a}; }
+
+v16qi fabcdefghijklmnop() { return (v16qi){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}; }
+
+/* { dg-final { scan-assembler-times "movaps" 17 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v2df-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v2df-1.c
new file mode 100644 (file)
index 0000000..f686d4e
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 10 } } */
+/* { dg-final { scan-assembler-times "movlps" 5 } } */
+/* { dg-final { scan-assembler-times "movaps" 8 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v2df-2.c b/gcc/testsuite/gcc.target/i386/sse-init-v2df-2.c
new file mode 100644 (file)
index 0000000..a867045
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movaps" 8 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v2di-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v2di-1.c
new file mode 100644 (file)
index 0000000..d6015ba
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movaps" 8 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v2di-2.c b/gcc/testsuite/gcc.target/i386/sse-init-v2di-2.c
new file mode 100644 (file)
index 0000000..3efc81d
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movaps" 12 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v4sf-2.c b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-2.c
new file mode 100644 (file)
index 0000000..c958ae9
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "xorps" 16 } } */
+/* { dg-final { scan-assembler-times "movss" 19 } } */
+/* { dg-final { scan-assembler-times "movaps" 10 } } */
+/* { dg-final { scan-assembler-times "shufps" 7 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v4sf-3.c b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-3.c
new file mode 100644 (file)
index 0000000..d98386e
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movss" 20 } } */
+/* { dg-final { scan-assembler-times "shufps" 7 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v4si-1.c
new file mode 100644 (file)
index 0000000..cf8da9b
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movss" 20 } } */
+/* { dg-final { scan-assembler-times "shufps" 11 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v8hi-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v8hi-1.c
new file mode 100644 (file)
index 0000000..5ce9faf
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse -mno-sse2" } */
+
+typedef short v8hi __attribute__ ((__vector_size__ (16)));
+
+short a, b, c, d, e, f, g, h;
+
+v8hi fa0000000() { return (v8hi){a,0,0,0,0,0,0,0}; }
+v8hi f0a000000() { return (v8hi){0,a,0,0,0,0,0,0}; }
+v8hi f00a00000() { return (v8hi){0,0,a,0,0,0,0,0}; }
+v8hi f000a0000() { return (v8hi){0,0,0,a,0,0,0,0}; }
+v8hi f0000a000() { return (v8hi){0,0,0,0,a,0,0,0}; }
+v8hi f00000a00() { return (v8hi){0,0,0,0,0,a,0,0}; }
+v8hi f000000a0() { return (v8hi){0,0,0,0,0,0,a,0}; }
+v8hi f0000000a() { return (v8hi){0,0,0,0,0,0,0,a}; }
+v8hi fabcdefgh() { return (v8hi){a,b,c,d,e,f,g,h}; }
+
+/* { dg-final { scan-assembler-times "movaps" 9 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-2.c
new file mode 100644 (file)
index 0000000..b448ecf
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef char v16qi __attribute__ ((__vector_size__ (16)));
+
+char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+v16qi fa000000000000000() { return (v16qi){a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0a00000000000000() { return (v16qi){0,a,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00a0000000000000() { return (v16qi){0,0,a,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000a000000000000() { return (v16qi){0,0,0,a,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000a00000000000() { return (v16qi){0,0,0,0,a,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00000a0000000000() { return (v16qi){0,0,0,0,0,a,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000000a000000000() { return (v16qi){0,0,0,0,0,0,a,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000000a00000000() { return (v16qi){0,0,0,0,0,0,0,a,0,0,0,0,0,0,0,0}; }
+v16qi f00000000a0000000() { return (v16qi){0,0,0,0,0,0,0,0,a,0,0,0,0,0,0,0}; }
+v16qi f000000000a000000() { return (v16qi){0,0,0,0,0,0,0,0,0,a,0,0,0,0,0,0}; }
+v16qi f0000000000a00000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,a,0,0,0,0,0}; }
+v16qi f00000000000a0000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,a,0,0,0,0}; }
+v16qi f000000000000a000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,a,0,0,0}; }
+v16qi f0000000000000a00() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,a,0,0}; }
+v16qi f00000000000000a0() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,a,0}; }
+v16qi f000000000000000a() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,a}; }
+
+v16qi fabcdefghijklmnop() { return (v16qi){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}; }
+
+/* { dg-final { scan-assembler-times "movzbl" 32 } } */
+/* { dg-final { scan-assembler-times "movd" 16 } } */
+/* { dg-final { scan-assembler-times "sall" 3 } } */
+/* { dg-final { scan-assembler-times "pslldq" 12 } } */
+/* { dg-final { scan-assembler-times "movq" 2 } } */
+/* { dg-final { scan-assembler-times "punpcklqdq" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-3.c b/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-3.c
new file mode 100644 (file)
index 0000000..ea741e3
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef char v16qi __attribute__ ((__vector_size__ (16)));
+
+char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+v16qi fa000000000000000() { return (v16qi){a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0a00000000000000() { return (v16qi){0,a,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00a0000000000000() { return (v16qi){0,0,a,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000a000000000000() { return (v16qi){0,0,0,a,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000a00000000000() { return (v16qi){0,0,0,0,a,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00000a0000000000() { return (v16qi){0,0,0,0,0,a,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000000a000000000() { return (v16qi){0,0,0,0,0,0,a,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000000a00000000() { return (v16qi){0,0,0,0,0,0,0,a,0,0,0,0,0,0,0,0}; }
+v16qi f00000000a0000000() { return (v16qi){0,0,0,0,0,0,0,0,a,0,0,0,0,0,0,0}; }
+v16qi f000000000a000000() { return (v16qi){0,0,0,0,0,0,0,0,0,a,0,0,0,0,0,0}; }
+v16qi f0000000000a00000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,a,0,0,0,0,0}; }
+v16qi f00000000000a0000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,a,0,0,0,0}; }
+v16qi f000000000000a000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,a,0,0,0}; }
+v16qi f0000000000000a00() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,a,0,0}; }
+v16qi f00000000000000a0() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,a,0}; }
+v16qi f000000000000000a() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,a}; }
+
+v16qi fabcdefghijklmnop() { return (v16qi){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}; }
+
+/* { dg-final { scan-assembler-times "movzbl" 32 } } */
+/* { dg-final { scan-assembler-times "movd" 20 } } */
+/* { dg-final { scan-assembler-times "sall" 15 } } */
+/* { dg-final { scan-assembler-times "pslldq" 12 } } */
+/* { dg-final { scan-assembler-times "punpckldq" 2 } } */
+/* { dg-final { scan-assembler-times "shufps" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2df-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-1.c
new file mode 100644 (file)
index 0000000..d73a32e
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 4 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "unpcklpd" 3 } } */
+/* { dg-final { scan-assembler-times "movsd" 2 } } */
+/* { dg-final { scan-assembler-times "movhpd" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c
new file mode 100644 (file)
index 0000000..2e091ee
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 5 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "unpcklpd" 2 } } */
+/* { dg-final { scan-assembler-times "movsd" 3 } } */
+/* { dg-final { scan-assembler-times "movhpd" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2di-3.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-3.c
new file mode 100644 (file)
index 0000000..b054daa
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 9 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "punpcklqdq" 3 } } */
+/* { dg-final { scan-assembler-times "movhps" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2di-4.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-4.c
new file mode 100644 (file)
index 0000000..272b6b2
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movd" 4 } } */
+/* { dg-final { scan-assembler-times "movq" 6 } } */
+/* { dg-final { scan-assembler-times "punpckldq" 2 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "punpcklqdq" 2 } } */
+/* { dg-final { scan-assembler-times "movhps" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-1.c
new file mode 100644 (file)
index 0000000..716d55b
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movd" 32 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 4 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
+/* { dg-final { scan-assembler-times "movss" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-2.c
new file mode 100644 (file)
index 0000000..44ed994
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movss" 20 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 4 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v4si-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v4si-2.c
new file mode 100644 (file)
index 0000000..af3fcac
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movd" 20 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 6 } } */
+/* { dg-final { scan-assembler-times "pshufd" 2 } } */
+/* { dg-final { scan-assembler-times "punpckldq" 5 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v8hi-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v8hi-2.c
new file mode 100644 (file)
index 0000000..b8f9f67
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse4.1" } */
+
+typedef short v8hi __attribute__ ((__vector_size__ (16)));
+
+short a, b, c, d, e, f, g, h;
+
+v8hi fa0000000() { return (v8hi){a,0,0,0,0,0,0,0}; }
+v8hi f0a000000() { return (v8hi){0,a,0,0,0,0,0,0}; }
+v8hi f00a00000() { return (v8hi){0,0,a,0,0,0,0,0}; }
+v8hi f000a0000() { return (v8hi){0,0,0,a,0,0,0,0}; }
+v8hi f0000a000() { return (v8hi){0,0,0,0,a,0,0,0}; }
+v8hi f00000a00() { return (v8hi){0,0,0,0,0,a,0,0}; }
+v8hi f000000a0() { return (v8hi){0,0,0,0,0,0,a,0}; }
+v8hi f0000000a() { return (v8hi){0,0,0,0,0,0,0,a}; }
+v8hi fabcdefgh() { return (v8hi){a,b,c,d,e,f,g,h}; }
+
+/* { dg-final { scan-assembler-times "pxor" 8 } } */
+/* { dg-final { scan-assembler-times "pinsrw" 15 } } */
+/* { dg-final { scan-assembler-times "movzwl" 1 } } */
+/* { dg-final { scan-assembler-times "movd" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-2.c
new file mode 100644 (file)
index 0000000..bc6748b
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef char v16qi __attribute__ ((__vector_size__ (16)));
+
+char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+v16qi fa000000000000000() { return (v16qi){a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0a00000000000000() { return (v16qi){0,a,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00a0000000000000() { return (v16qi){0,0,a,0,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000a000000000000() { return (v16qi){0,0,0,a,0,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000a00000000000() { return (v16qi){0,0,0,0,a,0,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f00000a0000000000() { return (v16qi){0,0,0,0,0,a,0,0,0,0,0,0,0,0,0,0}; }
+v16qi f000000a000000000() { return (v16qi){0,0,0,0,0,0,a,0,0,0,0,0,0,0,0,0}; }
+v16qi f0000000a00000000() { return (v16qi){0,0,0,0,0,0,0,a,0,0,0,0,0,0,0,0}; }
+v16qi f00000000a0000000() { return (v16qi){0,0,0,0,0,0,0,0,a,0,0,0,0,0,0,0}; }
+v16qi f000000000a000000() { return (v16qi){0,0,0,0,0,0,0,0,0,a,0,0,0,0,0,0}; }
+v16qi f0000000000a00000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,a,0,0,0,0,0}; }
+v16qi f00000000000a0000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,a,0,0,0,0}; }
+v16qi f000000000000a000() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,a,0,0,0}; }
+v16qi f0000000000000a00() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,a,0,0}; }
+v16qi f00000000000000a0() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,a,0}; }
+v16qi f000000000000000a() { return (v16qi){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,a}; }
+
+v16qi fabcdefghijklmnop() { return (v16qi){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}; }
+
+/* { dg-final { scan-assembler-times "pxor" 16 } } */
+/* { dg-final { scan-assembler-times "pinsrb" 31 } } */
+/* { dg-final { scan-assembler-times "movzbl" 1 } } */
+/* { dg-final { scan-assembler-times "movd" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-1.c
new file mode 100644 (file)
index 0000000..678fb57
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 4 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "unpcklpd" 2 } } */
+/* { dg-final { scan-assembler-times "movsd" 1 } } */
+/* { dg-final { scan-assembler-times "movhpd" 1 } } */
+/* { dg-final { scan-assembler-times "movddup" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c
new file mode 100644 (file)
index 0000000..218cc8b
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+double m, n;
+
+v2df fx0(double x) { return (v2df){ x, 0.0 }; }
+v2df f0x(double x) { return (v2df){ 0.0, x }; }
+v2df fxx(double x) { return (v2df){ x, x }; }
+v2df fxy(double x, double y) { return (v2df){ x, y }; }
+
+v2df fm0() { return (v2df){ m, 0.0 }; }
+v2df f0m() { return (v2df){ 0.0, m }; }
+v2df fmm() { return (v2df){ m, m }; }
+v2df fmn() { return (v2df){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 5 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "movddup" 2 } } */
+/* { dg-final { scan-assembler-times "movsd" 1 } } */
+/* { dg-final { scan-assembler-times "movhpd" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-2.c
new file mode 100644 (file)
index 0000000..f050f01
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movq" 7 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "punpcklqdq" 1 } } */
+/* { dg-final { scan-assembler-times "pinsrq" 2 } } */
+/* { dg-final { scan-assembler-times "movddup" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-3.c
new file mode 100644 (file)
index 0000000..5bc2f57
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef long long v2di __attribute__ ((__vector_size__ (16)));
+
+long long m,n;
+
+v2di fx0(long long x) { return (v2di){ x, 0 }; }
+v2di f0x(long long x) { return (v2di){ 0, x }; }
+v2di fxx(long long x) { return (v2di){ x, x }; }
+v2di fxy(long long x, long long y) { return (v2di){ x, y }; }
+
+v2di fm0() { return (v2di){ m, 0 }; }
+v2di f0m() { return (v2di){ 0, m }; }
+v2di fmm() { return (v2di){ m, m }; }
+v2di fmn() { return (v2di){ m, n }; }
+
+/* { dg-final { scan-assembler-times "movd\[ \t\]" 2 } } */
+/* { dg-final { scan-assembler-times "pinsrd" 2 } } */
+/* { dg-final { scan-assembler-times "pslldq" 2 } } */
+/* { dg-final { scan-assembler-times "movddup" 2 } } */
+/* { dg-final { scan-assembler-times "movq" 4 } } */
+/* { dg-final { scan-assembler-times "movhps" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-2.c
new file mode 100644 (file)
index 0000000..b4e7f72
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "insertps" 16 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 4 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
+/* { dg-final { scan-assembler-times "movss" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-3.c
new file mode 100644 (file)
index 0000000..9a51d1b
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef float v4sf __attribute__ ((__vector_size__ (16)));
+
+float m,n;
+
+v4sf fa000(float a) { return (v4sf){a,0.0f,0.0f,0.0f}; }
+v4sf f0a00(float a) { return (v4sf){0.0f,a,0.0f,0.0f}; }
+v4sf f00a0(float a) { return (v4sf){0.0f,0.0f,a,0.0f}; }
+v4sf f000a(float a) { return (v4sf){0.0f,0.0f,0.0f,a}; }
+
+v4sf faa00(float a) { return (v4sf){a,a,0.0f,0.0f}; }
+v4sf fa0a0(float a) { return (v4sf){a,0.0f,a,0.0f}; }
+
+v4sf faaaa(float a) { return (v4sf){a,a,a,a}; }
+
+v4sf fab00(float a, float b) { return (v4sf){a,b,0.0f,0.0f}; }
+v4sf fa0b0(float a, float b) { return (v4sf){a,0.0f,b,0.0f}; }
+v4sf fabab(float a, float b) { return (v4sf){a,b,a,b}; }
+v4sf fabcd(float a, float b, float c, float d) { return (v4sf){a,b,c,d}; }
+
+v4sf fm000() { return (v4sf){m,0.0f,0.0f,0.0f}; }
+v4sf fm0m0() { return (v4sf){m,0.0f,m,0.0f}; }
+v4sf fmmmm() { return (v4sf){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movss" 20 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 4 } } */
+/* { dg-final { scan-assembler-times "movlhps" 4 } } */
+/* { dg-final { scan-assembler-times "unpcklps" 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-2.c
new file mode 100644 (file)
index 0000000..978b1d4
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1 -mno-avx" } */
+
+typedef int v4si __attribute__ ((__vector_size__ (16)));
+
+int m,n;
+
+v4si fa000(int a) { return (v4si){a,0,0,0}; }
+v4si f0a00(int a) { return (v4si){0,a,0,0}; }
+v4si f00a0(int a) { return (v4si){0,0,a,0}; }
+v4si f000a(int a) { return (v4si){0,0,0,a}; }
+
+v4si faa00(int a) { return (v4si){a,a,0,0}; }
+v4si fa0a0(int a) { return (v4si){a,0,a,0}; }
+
+v4si faaaa(int a) { return (v4si){a,a,a,a}; }
+
+v4si fab00(int a, int b) { return (v4si){a,b,0,0}; }
+v4si fa0b0(int a, int b) { return (v4si){a,0,b,0}; }
+v4si fabab(int a, int b) { return (v4si){a,b,a,b}; }
+v4si fabcd(int a, int b, int c, int d) { return (v4si){a,b,c,d}; }
+
+v4si fm000() { return (v4si){m,0,0,0}; }
+v4si fm0m0() { return (v4si){m,0,m,0}; }
+v4si fmmmm() { return (v4si){m,m,m,m}; }
+
+/* { dg-final { scan-assembler-times "movd" 14 } } */
+/* { dg-final { scan-assembler-times "pslldq" 3 } } */
+/* { dg-final { scan-assembler-times "shufps" 4 } } */
+/* { dg-final { scan-assembler-times "pshufd" 2 } } */
+/* { dg-final { scan-assembler-times "pinsrd" 6 } } */
+