if (msize > UNITS_PER_WORD)
return true;
- /* In addition to SImode moves, AVX512FP16 also enables HImode moves. */
- int minsize = GET_MODE_SIZE (TARGET_AVX512FP16 ? HImode : SImode);
+ /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
+ Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16. */
+ int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
if (msize < minsize)
return true;
if (!TARGET_AVX512FP16)
{
rtx res = gen_reg_rtx (V4SFmode);
- rtx tmp = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
+ rtx tmp = gen_reg_rtx (V8HFmode);
+ rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
- ix86_expand_vector_set (false, tmp, operands[1], 0);
+ if (TARGET_AVX2)
+ {
+ rtx dup = gen_reg_rtx (V8HFmode);
+ emit_move_insn (dup, gen_rtx_VEC_DUPLICATE (V8HFmode, operands[1]));
+ emit_move_insn (tmp, gen_rtx_VEC_MERGE (V8HFmode, dup,
+ zero, const1_rtx));
+ }
+ else
+ emit_insn (gen_sse2_pinsrph (tmp, zero, operands[1], const1_rtx));
emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
emit_move_insn (operands[0], gen_lowpart (SFmode, res));
DONE;
if (!TARGET_AVX512FP16)
{
rtx res = gen_reg_rtx (V8HFmode);
- rtx tmp = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
+ rtx tmp = gen_reg_rtx (V4SFmode);
+ rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
- ix86_expand_vector_set (false, tmp, operands[1], 0);
+ emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
emit_move_insn (operands[0], gen_lowpart (HFmode, res));
DONE;
(V2DI "TARGET_SSE4_1 && TARGET_64BIT")])
(define_mode_attr sse2p4_1
- [(V16QI "sse4_1") (V8HI "sse2") (V8HF "sse4_1")
+ [(V16QI "sse4_1") (V8HI "sse2") (V8HF "sse2")
(V4SI "sse4_1") (V2DI "sse4_1")])
(define_mode_attr pinsr_evex_isa
/* { dg-do compile } */
/* { dg-options "-O2 -mf16c -mno-avx512fp16" } */
-/* { dg-final { scan-assembler-times "vpxor\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "vpxor\[ \\t\]" 1 } } */
/* { dg-final { scan-assembler-times "vcvtph2ps\[ \\t\]" 2 } } */
/* { dg-final { scan-assembler-times "vcvtps2ph\[ \\t\]" 1 } } */
/* { dg-final { scan-assembler-not "__truncsfhf2\[ \\t\]"} } */
--- /dev/null
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mf16c -mno-avx512fp16" } */
+/* { dg-final { scan-assembler-times "pextrw" 1 } } */
+/* { dg-final { scan-assembler-times "pinsrw" 1 } } */
+/* { dg-final { scan-assembler-not "\\\(%rsp\\\)"} } */
+short test (_Float16 a)
+{
+ union{
+ short b;
+ _Float16 a;}u;
+ u.a = a;
+ return u.b;
+}
+
+_Float16 test1 (short a)
+{
+ union{
+ _Float16 b;
+ short a;}u;
+ u.a = a;
+ return u.b;
+}