[Patch 3/17] Implement TARGET_C_EXCESS_PRECISION for s390
authorJames Greenhalgh <james.greenhalgh@arm.com>
Wed, 23 Nov 2016 17:16:29 +0000 (17:16 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Wed, 23 Nov 2016 17:16:29 +0000 (17:16 +0000)
* config/s390/s390.c (s390_excess_precision): New.
(TARGET_C_EXCESS_PRECISION): Define.

From-SVN: r242773

gcc/ChangeLog
gcc/config/s390/s390.c

index 7b6e1b6433d0ce706ba32c7a1fa5d0bd372eddc4..ab0154b899803fc04f5ac1548d9cf3a985e5d88d 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * config/s390/s390.c (s390_excess_precision): New.
+       (TARGET_C_EXCESS_PRECISION): Define.
+
 2016-11-23  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/i386/i386.c (ix86_excess_precision): New.
index aeafdd41f0bfc38957b4b3b5ef1a9d670b19e2cb..dc82fb69082efabb23e1b23a09f80f727a97ca8c 100644 (file)
@@ -15260,6 +15260,43 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty
   return NULL;
 }
 
+/* Implement TARGET_C_EXCESS_PRECISION.
+
+   FIXME: For historical reasons, float_t and double_t are typedef'ed to
+   double on s390, causing operations on float_t to operate in a higher
+   precision than is necessary.  However, it is not the case that SFmode
+   operations have implicit excess precision, and we generate more optimal
+   code if we let the compiler know no implicit extra precision is added.
+
+   That means when we are compiling with -fexcess-precision=fast, the value
+   we set for FLT_EVAL_METHOD will be out of line with the actual precision of
+   float_t (though they would be correct for -fexcess-precision=standard).
+
+   A complete fix would modify glibc to remove the unnecessary typedef
+   of float_t to double.  */
+
+static enum flt_eval_method
+s390_excess_precision (enum excess_precision_type type)
+{
+  switch (type)
+    {
+      case EXCESS_PRECISION_TYPE_IMPLICIT:
+      case EXCESS_PRECISION_TYPE_FAST:
+       /* The fastest type to promote to will always be the native type,
+          whether that occurs with implicit excess precision or
+          otherwise.  */
+       return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
+      case EXCESS_PRECISION_TYPE_STANDARD:
+       /* Otherwise, when we are in a standards compliant mode, to
+          ensure consistency with the implementation in glibc, report that
+          float is evaluated to the range and precision of double.  */
+       return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE;
+      default:
+       gcc_unreachable ();
+    }
+  return FLT_EVAL_METHOD_UNPREDICTABLE;
+}
+
 /* Initialize GCC target structure.  */
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
@@ -15320,6 +15357,9 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
 
+#undef TARGET_C_EXCESS_PRECISION
+#define TARGET_C_EXCESS_PRECISION s390_excess_precision
+
 #undef  TARGET_SCHED_ADJUST_PRIORITY
 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
 #undef TARGET_SCHED_ISSUE_RATE