From f0bd50e831792692ffcedf288b312167a9339260 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 1 Aug 2026 17:51:02 +0100 Subject: [PATCH] x86 SSE: Improved vector initialization/construction. 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 Hongtao Liu 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. --- gcc/config/i386/i386-expand.cc | 1500 +++++++++++++++-- gcc/config/i386/sse.md | 15 + .../gcc.target/i386/avx-init-v16qi-1.c | 30 + .../gcc.target/i386/avx-init-v2df-1.c | 24 + .../gcc.target/i386/avx-init-v2df-2.c | 23 + .../gcc.target/i386/avx-init-v2di-1.c | 23 + .../gcc.target/i386/avx-init-v2di-2.c | 24 + .../gcc.target/i386/avx-init-v4sf-1.c | 33 + .../gcc.target/i386/avx-init-v4sf-2.c | 32 + .../gcc.target/i386/avx-init-v4si-1.c | 32 + .../gcc.target/i386/avx-init-v8hi-1.c | 21 + .../gcc.target/i386/avx2-init-v4sf-1.c | 33 + .../gcc.target/i386/avx2-init-v4si-1.c | 32 + .../gcc.target/i386/avx2-init-v4si-2.c | 32 + .../gcc.target/i386/avx512vl-concatv4si-1.c | 3 +- .../gcc.target/i386/avx512vl-init-v2di-1.c | 22 + .../gcc.target/i386/avx512vl-init-v2di-2.c | 24 + .../gcc.target/i386/avx512vl-init-v4si-1.c | 32 + .../gcc.target/i386/sse-init-v16qi-1.c | 27 + .../gcc.target/i386/sse-init-v2df-1.c | 21 + .../gcc.target/i386/sse-init-v2df-2.c | 19 + .../gcc.target/i386/sse-init-v2di-1.c | 18 + .../gcc.target/i386/sse-init-v2di-2.c | 18 + .../gcc.target/i386/sse-init-v4sf-2.c | 32 + .../gcc.target/i386/sse-init-v4sf-3.c | 30 + .../gcc.target/i386/sse-init-v4si-1.c | 30 + .../gcc.target/i386/sse-init-v8hi-1.c | 18 + .../gcc.target/i386/sse2-init-v16qi-2.c | 32 + .../gcc.target/i386/sse2-init-v16qi-3.c | 32 + .../gcc.target/i386/sse2-init-v2df-1.c | 23 + .../gcc.target/i386/sse2-init-v2df-2.c | 23 + .../gcc.target/i386/sse2-init-v2di-3.c | 22 + .../gcc.target/i386/sse2-init-v2di-4.c | 24 + .../gcc.target/i386/sse2-init-v4sf-1.c | 32 + .../gcc.target/i386/sse2-init-v4sf-2.c | 31 + .../gcc.target/i386/sse2-init-v4si-2.c | 32 + .../gcc.target/i386/sse2-init-v8hi-2.c | 21 + .../gcc.target/i386/sse4_1-init-v16qi-2.c | 30 + .../gcc.target/i386/sse4_1-init-v2df-1.c | 24 + .../gcc.target/i386/sse4_1-init-v2df-2.c | 23 + .../gcc.target/i386/sse4_1-init-v2di-2.c | 23 + .../gcc.target/i386/sse4_1-init-v2di-3.c | 24 + .../gcc.target/i386/sse4_1-init-v4sf-2.c | 32 + .../gcc.target/i386/sse4_1-init-v4sf-3.c | 31 + .../gcc.target/i386/sse4_1-init-v4si-2.c | 32 + 45 files changed, 2528 insertions(+), 111 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v16qi-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v2df-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v2df-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v2di-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v2di-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v4sf-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v4sf-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v4si-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx-init-v8hi-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx2-init-v4sf-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx2-init-v4si-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx2-init-v4si-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-init-v4si-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v16qi-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v2df-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v2df-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v2di-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v2di-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v4sf-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v4sf-3.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v4si-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse-init-v8hi-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v16qi-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v16qi-3.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v2df-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v2di-3.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v2di-4.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v4sf-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v4sf-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v4si-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse2-init-v8hi-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-3.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-2.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-3.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-2.c diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 9a3760714647..6ddc402e9ad4 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -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= 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); diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index bd6ce2ac70c8..7d71f8ba5462 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -20602,6 +20602,21 @@ (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" [(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 index 000000000000..f608d0940746 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v16qi-1.c @@ -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 index 000000000000..c57b8388094d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v2df-1.c @@ -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 index 000000000000..4f2db81b61ee --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v2df-2.c @@ -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 index 000000000000..c8988324b2a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v2di-1.c @@ -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 index 000000000000..22ca6b5add3e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v2di-2.c @@ -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 index 000000000000..a1f63c6a44aa --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v4sf-1.c @@ -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 index 000000000000..6d3ff179d16e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v4sf-2.c @@ -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 index 000000000000..a551031b1f1e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v4si-1.c @@ -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 index 000000000000..b8f9f6799bed --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-init-v8hi-1.c @@ -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 index 000000000000..23ff0e76836b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-init-v4sf-1.c @@ -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 index 000000000000..02bc7b0a7e93 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-init-v4si-1.c @@ -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 index 000000000000..3f68d5c7a878 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx2-init-v4si-2.c @@ -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 } } */ + diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-concatv4si-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-concatv4si-1.c index 88d4682278c2..30744c4c2241 100644 --- a/gcc/testsuite/gcc.target/i386/avx512vl-concatv4si-1.c +++ b/gcc/testsuite/gcc.target/i386/avx512vl-concatv4si-1.c @@ -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 index 000000000000..12a7388f8e07 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-1.c @@ -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 index 000000000000..18807b3ec0fc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-init-v2di-2.c @@ -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 index 000000000000..65af66573a20 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-init-v4si-1.c @@ -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 index 000000000000..244dda3e59aa --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v16qi-1.c @@ -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 index 000000000000..f686d4ed5e80 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v2df-1.c @@ -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 index 000000000000..a8670453fe88 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v2df-2.c @@ -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 index 000000000000..d6015ba7b225 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v2di-1.c @@ -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 index 000000000000..3efc81d37dba --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v2di-2.c @@ -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 index 000000000000..c958ae9e7f80 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-2.c @@ -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 index 000000000000..d98386e9ffc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-3.c @@ -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 index 000000000000..cf8da9b02b29 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v4si-1.c @@ -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 index 000000000000..5ce9fafd3022 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-init-v8hi-1.c @@ -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 index 000000000000..b448ecfe01b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-2.c @@ -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 index 000000000000..ea741e38bfa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-3.c @@ -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 index 000000000000..d73a32e9e884 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-1.c @@ -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 index 000000000000..2e091eeabf6d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c @@ -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 index 000000000000..b054daad119f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-3.c @@ -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 index 000000000000..272b6b230394 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-4.c @@ -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 index 000000000000..716d55b81610 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-1.c @@ -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 index 000000000000..44ed9944ef2a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v4sf-2.c @@ -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 index 000000000000..af3fcacd491c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v4si-2.c @@ -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 index 000000000000..b8f9f6799bed --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v8hi-2.c @@ -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 index 000000000000..bc6748b0e7b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-2.c @@ -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 index 000000000000..678fb57ff41a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-1.c @@ -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 index 000000000000..218cc8bf896a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c @@ -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 index 000000000000..f050f012fada --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-2.c @@ -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 index 000000000000..5bc2f57ef76a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-3.c @@ -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 index 000000000000..b4e7f7293a91 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-2.c @@ -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 index 000000000000..9a51d1b7dcf4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-3.c @@ -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 index 000000000000..978b1d4051b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-2.c @@ -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 } } */ + -- 2.47.3