gcc/ChangeLog: * config/i386/i386.md (*avx512fp16_1_roundhf2): New define_insn. * config/i386/sse.md (*avx512fp16_1_roundhf): New fine_insn.
gcc/testsuite/ChangeLog: * gcc.target/i386/avx512fp16-builtin-round-2.c: New test. --- gcc/config/i386/i386.md | 22 ++++++++++++++ gcc/config/i386/sse.md | 20 +++++++++++++ .../i386/avx512fp16-builtin-round-2.c | 29 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/avx512fp16-builtin-round-2.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 684b2080a93..457f37dcb61 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17738,6 +17738,28 @@ (define_expand "significand<mode>2" }) +/* Optimize for code like (_Float16) __builtin_ceif ((float) f16) + since it's not handled in frontend. */ + +(define_insn "*avx512fp16_1_roundhf2" + [(set (match_operand:HF 0 "register_operand" "=v,v") + (float_truncate:HF + (unspec:MODEF + [(float_extend:MODEF + (match_operand:HF 1 "nonimmediate_operand" "v,m")) + (match_operand:SI 2 "const_0_to_15_operand" "n,n")] + UNSPEC_ROUND)))] + "TARGET_AVX512FP16" + "@ + vrndscalesh\t{%2, %d1, %0|%0, %d1, %2} + vrndscalesh\t{%2, %1, %d0|%d0, %1, %2}" + [(set_attr "type" "ssecvt") + (set_attr "length_immediate" "1,1") + (set_attr "prefix" "evex") + (set_attr "avx_partial_xmm_update" "false,true") + (set_attr "mode" "HF")]) + + (define_insn "sse4_1_round<mode>2" [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v") (unspec:MODEFH diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 2b8d12086f4..b3d8ffb4f8e 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -20220,6 +20220,26 @@ (define_insn "sse4_1_round<ssescalarmodesuffix>" (set_attr "prefix" "orig,orig,vex,evex") (set_attr "mode" "<MODE>")]) +(define_insn "*avx512fp16_1_roundhf" + [(set (match_operand:V8HF 0 "register_operand" "=v") + (vec_merge:V8HF + (vec_duplicate:V8HF + (float_truncate:HF + (unspec:MODEF + [(float_extend:MODEF + (match_operand:HF 2 "nonimmediate_operand" "vm")) + (match_operand:SI 3 "const_0_to_15_operand" "n")] + UNSPEC_ROUND))) + (match_operand:V8HF 1 "register_operand" "v") + (const_int 1)))] + "TARGET_AVX512FP16" + "vrndscalesh\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssecvt") + (set_attr "length_immediate" "1") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "evex") + (set_attr "mode" "HF")]) + (define_insn "*sse4_1_round<ssescalarmodesuffix>" [(set (match_operand:VFH_128 0 "register_operand" "=Yr,*x,x,v") (vec_merge:VFH_128 diff --git a/gcc/testsuite/gcc.target/i386/avx512fp16-builtin-round-2.c b/gcc/testsuite/gcc.target/i386/avx512fp16-builtin-round-2.c new file mode 100644 index 00000000000..bcd41929637 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512fp16-builtin-round-2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512fp16" } */ + +_Float16 +foo1 (_Float16 a) +{ + return __builtin_roundeven (a); +} + +_Float16 +foo2 (_Float16 a) +{ + return __builtin_trunc (a); +} + +_Float16 +foo3 (_Float16 a) +{ + return __builtin_ceil (a); +} + +_Float16 +foo4 (_Float16 a) +{ + return __builtin_floor (a); +} + +/* { dg-final { scan-assembler-not "vcvtsh2s\[sd\]" } } */ +/* { dg-final { scan-assembler-times "vrndscalesh\[^\n\r\]*xmm\[0-9\]" 4 } } */ -- 2.18.1