This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch ARM 4/4] Enable _Float16


On Mon, Oct 24, 2016 at 10:28:42PM +0000, Joseph Myers wrote:
> On Mon, 24 Oct 2016, James Greenhalgh wrote:
>
> > Hi,
> >
> > Finally, having added support for single-step DFmode to HFmode conversions,
> > this patch adds support for _Float16 to the ARM back-end.
>
> Given the need for -mfp16-format=ieee (on some processors), you should be
> updating target-supports.exp:add_options_for_float16 to add that option in
> the ARM case, and make sure that the tests run in cases where the option
> is needed to enable support for this format.

Done in this revision, though this makes no difference to what gets tested
as these options are not added when compiling the probe functions
(check_effective_target_float16). These would need a patch like:

diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index abc4ac0..36573cc 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2485,7 +2485,7 @@ proc check_effective_target_has_q_floating_suffix { } {
 proc check_effective_target_float16 {} {
     return [check_no_compiler_messages_nocache float16 object {
         _Float16 x;
-    }]
+    } [add_options_for_float16 {}]]
 }

 proc check_effective_target_float32 {} {

To actually enable the tests.

> > That means making sure that only __fp16 promotes and adding similar hooks to
> > those used in the AArch64 port giving the excess precision rules, and
> > marking HFmode as supported in libgcc.
>
> Does "supported in libgcc" mean this patch completes fixing bug 63250?

>From my reading of the bug. Yes. I'll tag the gcc ChangeLog as a fix, so it
is recorded against the PR.

Thanks,
James

---
gcc/

2016-11-02  James Greenhalgh  <james.greenhalgh@arm.com>

	PR target/63250
	* config/arm/arm-builtins.c (arm_simd_floatHF_type_node): Rename to...
	(arm_fp16_type_node): ...This, make visibile.
	(arm_simd_builtin_std_type): Rename arm_simd_floatHF_type_node to
	arm_fp16_type_node.
	(arm_init_simd_builtin_types): Likewise.
	(arm_init_fp16_builtins): Likewise.
	* config/arm/arm.c (arm_excess_precision): New.
	(arm_floatn_mode): Likewise.
	(TARGET_C_EXCESS_PRECISION): Likewise.
	(TARGET_FLOATN_MODE): Likewise.
	(arm_promoted_type): Only promote arm_fp16_type_node.
	* config/arm/arm.h (arm_fp16_type_node): Declare.

gcc/testsuite/

2016-11-02  James Greenhalgh  <james.greenhalgh@arm.com>

	* lib/target-supports.exp (add_options_for_float16): Add
	-mfp16-format=ieee when testign arm*-*-*.

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index e73043d..5ed38d1 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -652,7 +652,8 @@ static struct arm_simd_type_info arm_simd_types [] = {
 };
 #undef ENTRY
 
-static tree arm_simd_floatHF_type_node = NULL_TREE;
+/* The user-visible __fp16 type.  */
+tree arm_fp16_type_node = NULL_TREE;
 static tree arm_simd_intOI_type_node = NULL_TREE;
 static tree arm_simd_intEI_type_node = NULL_TREE;
 static tree arm_simd_intCI_type_node = NULL_TREE;
@@ -739,7 +740,7 @@ arm_simd_builtin_std_type (enum machine_mode mode,
     case XImode:
       return arm_simd_intXI_type_node;
     case HFmode:
-      return arm_simd_floatHF_type_node;
+      return arm_fp16_type_node;
     case SFmode:
       return float_type_node;
     case DFmode:
@@ -840,8 +841,8 @@ arm_init_simd_builtin_types (void)
   /* Continue with standard types.  */
   /* The __builtin_simd{64,128}_float16 types are kept private unless
      we have a scalar __fp16 type.  */
-  arm_simd_types[Float16x4_t].eltype = arm_simd_floatHF_type_node;
-  arm_simd_types[Float16x8_t].eltype = arm_simd_floatHF_type_node;
+  arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node;
+  arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node;
   arm_simd_types[Float32x2_t].eltype = float_type_node;
   arm_simd_types[Float32x4_t].eltype = float_type_node;
 
@@ -1754,11 +1755,11 @@ arm_init_iwmmxt_builtins (void)
 static void
 arm_init_fp16_builtins (void)
 {
-  arm_simd_floatHF_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (arm_simd_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
-  layout_type (arm_simd_floatHF_type_node);
+  arm_fp16_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
+  layout_type (arm_fp16_type_node);
   if (arm_fp16_format)
-    (*lang_hooks.types.register_builtin_type) (arm_simd_floatHF_type_node,
+    (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
 					       "__fp16");
 }
 
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 524c474..5695548 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -272,6 +272,7 @@ static bool arm_builtin_support_vector_misalignment (machine_mode mode,
 						     int misalignment,
 						     bool is_packed);
 static void arm_conditional_register_usage (void);
+static enum flt_eval_method arm_excess_precision (enum excess_precision_type);
 static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
 static unsigned int arm_autovectorize_vector_sizes (void);
 static int arm_default_branch_cost (bool, bool);
@@ -305,6 +306,7 @@ static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
 static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
 						int reloc);
 static void arm_expand_divmod_libfunc (rtx, machine_mode, rtx, rtx, rtx *, rtx *);
+static machine_mode arm_floatn_mode (int, bool);
 
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -450,6 +452,9 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef  TARGET_ASM_INTERNAL_LABEL
 #define TARGET_ASM_INTERNAL_LABEL arm_internal_label
 
+#undef TARGET_FLOATN_MODE
+#define TARGET_FLOATN_MODE arm_floatn_mode
+
 #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
 
@@ -740,6 +745,9 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_EXPAND_DIVMOD_LIBFUNC
 #define TARGET_EXPAND_DIVMOD_LIBFUNC arm_expand_divmod_libfunc
 
+#undef TARGET_C_EXCESS_PRECISION
+#define TARGET_C_EXCESS_PRECISION arm_excess_precision
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Obstack for minipool constant handling.  */
@@ -23740,7 +23748,7 @@ arm_debugger_arg_offset (int value, rtx addr)
 static tree
 arm_promoted_type (const_tree t)
 {
-  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
+  if (TYPE_P (t) && TYPE_MAIN_VARIANT (t) == arm_fp16_type_node)
     return float_type_node;
   return NULL_TREE;
 }
@@ -23762,6 +23770,61 @@ arm_scalar_mode_supported_p (machine_mode mode)
     return default_scalar_mode_supported_p (mode);
 }
 
+/* Set the value of FLT_EVAL_METHOD.
+   ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
+
+    0: evaluate all operations and constants, whose semantic type has at
+       most the range and precision of type float, to the range and
+       precision of float; evaluate all other operations and constants to
+       the range and precision of the semantic type;
+
+    N, where _FloatN is a supported interchange floating type
+       evaluate all operations and constants, whose semantic type has at
+       most the range and precision of _FloatN type, to the range and
+       precision of the _FloatN type; evaluate all other operations and
+       constants to the range and precision of the semantic type;
+
+   If we have the ARMv8.2-A extensions then we support _Float16 in native
+   precision, so we should set this to 16.  Otherwise, we support the type,
+   but want to evaluate expressions in float precision, so set this to
+   0.  */
+
+static enum flt_eval_method
+arm_excess_precision (enum excess_precision_type type)
+{
+  switch (type)
+    {
+      case EXCESS_PRECISION_TYPE_FAST:
+      case EXCESS_PRECISION_TYPE_STANDARD:
+	/* We can calculate either in 16-bit range and precision or
+	   32-bit range and precision.  Make that decision based on whether
+	   we have native support for the ARMv8.2-A 16-bit floating-point
+	   instructions or not.  */
+	return (TARGET_VFP_FP16INST
+		? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
+		: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
+      case EXCESS_PRECISION_TYPE_IMPLICIT:
+	return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
+      default:
+	gcc_unreachable ();
+    }
+  return FLT_EVAL_METHOD_UNPREDICTABLE;
+}
+
+
+/* Implement TARGET_FLOATN_MODE.  Make very sure that we don't provide
+   _Float16 if we are using anything other than ieee format for 16-bit
+   floating point.  Otherwise, punt to the default implementation.  */
+static machine_mode
+arm_floatn_mode (int n, bool extended)
+{
+  if (!extended && n == 16)
+    return arm_fp16_format == ARM_FP16_FORMAT_IEEE ? HFmode : VOIDmode;
+
+  return default_floatn_mode (n, extended);
+}
+
+
 /* Set up OPERANDS for a register copy from SRC to DEST, taking care
    not to early-clobber SRC registers in the process.
 
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 0f9a679..f7aa155 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -82,6 +82,11 @@ extern int arm_ccfsm_state;
 extern GTY(()) rtx arm_target_insn;
 /* Callback to output language specific object attributes.  */
 extern void (*arm_lang_output_object_attributes_hook)(void);
+
+/* This type is the user-visible __fp16.  We need it in a few places in
+   the backend.  Defined in arm-builtins.c.  */
+extern tree arm_fp16_type_node;
+
 
 /* Just in case configure has failed to define anything.  */
 #ifndef TARGET_CPU_DEFAULT
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 722955a..3b3459c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2584,6 +2584,9 @@ proc check_effective_target_floatn_nx_runtime {} {
 # the function name.
 
 proc add_options_for_float16 { flags } {
+    if { [istarget arm*-*-*] } {
+	return "$flags -mfp16-format=ieee"
+    }
     return "$flags"
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]