On 11/11/16 15:42, James Greenhalgh wrote:
Hi,

This patch adds the half-to-double conversions, both as library functions,
or when supported in hardware, using the appropriate instructions.

That means adding support for the __gnu_d2h_{ieee/alternative} library calls
added in patch 2/4, and providing a more aggressive truncdfhf2 where we can.

This also lets us remove the implementation of TARGET_CONVERT_TO_TYPE.

Bootstrapped on an ARMv8-A machine,and crosstested with no issues.

OK?

Thanks,
James

---
gcc/

2016-11-09  James Greenhalgh  <james.greenha...@arm.com>

        * config/arm/arm.c (arm_convert_to_type): Delete.
        (TARGET_CONVERT_TO_TYPE): Delete.
        (arm_init_libfuncs): Enable trunc_optab from DFmode to HFmode.
        (arm_libcall_uses_aapcs_base): Add trunc_optab from DF- to HFmode.
        * config/arm/arm.h (TARGET_FP16_TO_DOUBLE): New.
        * config/arm/arm.md (truncdfhf2): Only convert through SFmode if we
        are in fast math mode, and have no single step hardware instruction.
        (extendhfdf2): Only expand through SFmode if we don't have a
        single-step hardware instruction.
        * config/arm/vfp.md (*truncdfhf2): New.
        (extendhfdf2): Likewise.

gcc/testsuite/

2016-11-09  James Greenhalgh  <james.greenha...@arm.com>

        * gcc.target/arm/fp16-rounding-alt-1.c (ROUNDED): Change expected
        result.
        * gcc.target/arm/fp16-rounding-ieee-1.c (ROUNDED): Change expected
        result.

<...>

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8393f65..4074773 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -5177,20 +5177,35 @@
   ""
 )
-;; DFmode to HFmode conversions have to go through SFmode.
+;; DFmode to HFmode conversions on targets without a single-step hardware
+;; instruction for it would have to go through SFmode.  This is dangerous
+;; as it introduces double rounding.
+;;
+;; Disable this pattern unless we are in an unsafe math mode, or we have
+;; a single-step instruction.
+
 (define_expand "truncdfhf2"
-  [(set (match_operand:HF  0 "general_operand" "")
+  [(set (match_operand:HF  0 "s_register_operand" "")
        (float_truncate:HF
-        (match_operand:DF 1 "general_operand" "")))]
-  "TARGET_EITHER"
-  "
-  {
-    rtx op1;
-    op1 = convert_to_mode (SFmode, operands[1], 0);
-    op1 = convert_to_mode (HFmode, op1, 0);
-    emit_move_insn (operands[0], op1);
-    DONE;
-  }"
+        (match_operand:DF 1 "s_register_operand" "")))]
+  "(TARGET_EITHER && flag_unsafe_math_optimizations)
+   || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
+{
+  /* We don't have a direct instruction for this, so we must be in
+     an unsafe math mode, and going via SFmode.  */
+
+  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
+    {
+      rtx op1;
+      gcc_assert (flag_unsafe_math_optimizations);

I'd remove this assert. From the condition of the expander it is obvious
that if !(TARGET_32BIT && TARGET_FP16_TO_DOUBLE) then 
flag_unsafe_math_optimizations is true.


Ok with this change.
Thanks,
Kyrill

Reply via email to