On 4/27/21 10:32 AM, Bill Schmidt wrote:
The design of the target-specific built-in function support in the
Power back end has not stood the test of time.  The machinery is
grossly inefficient, confusing, and arcane; and adding new built-in
functions is inefficient and error-prone.  This patch set introduces a
replacement.

After I submitted these patches, Iain Sandoe was kind enough to test them on a PPC 970 running Darwin, and uncovered a couple of bugs.  I appreciate the extra testing!

This is the first of two patches to fix these problems.  This one addresses my failure to recognize that decimal floating-point types are not necessarily defined on all Power subtargets.  We need some guards against NULL pointers for these types.

I'd appreciate consideration of this patch along with the rest of the patch set.  Thank you!

Bill

2021-04-29  Bill Schmidt  <wschm...@linux.ibm.com>

gcc/
        * config/rs6000/rs6000-call.c (rs6000_init_builtins): Don't build
        pointer types for decimal float types that don't exist.
        * config/rs6000/rs6000-gen-builtins.c (write_fntype_init): Guard
        against use of undefined decimal float types.
        (write_init_bif_table): Likewise.
        (write_init_ovld_table): Likewise.
---
 gcc/config/rs6000/rs6000-call.c         | 20 +++++++++-----
 gcc/config/rs6000/rs6000-gen-builtins.c | 35 ++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 288bc6b455a..a4999c27cf8 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -15911,12 +15911,20 @@ rs6000_init_builtins (void)
   ptr_long_double_type_node
     = build_pointer_type (build_qualified_type (long_double_type_internal_node,
                                                TYPE_QUAL_CONST));
-  ptr_dfloat64_type_node
-    = build_pointer_type (build_qualified_type (dfloat64_type_internal_node,
-                                               TYPE_QUAL_CONST));
-  ptr_dfloat128_type_node
-    = build_pointer_type (build_qualified_type (dfloat128_type_internal_node,
-                                               TYPE_QUAL_CONST));
+  if (dfloat64_type_node)
+    ptr_dfloat64_type_node
+      = build_pointer_type (build_qualified_type (dfloat64_type_internal_node,
+                                                 TYPE_QUAL_CONST));
+  else
+    ptr_dfloat64_type_node = NULL;
+
+  if (dfloat128_type_node)
+    ptr_dfloat128_type_node
+      = build_pointer_type (build_qualified_type (dfloat128_type_internal_node,
+                                                 TYPE_QUAL_CONST));
+  else
+    ptr_dfloat128_type_node = NULL;
+
   ptr_long_long_integer_type_node
     = build_pointer_type
        (build_qualified_type (long_long_integer_type_internal_node,
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index e7df7c8caab..6bca401a77f 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2392,16 +2392,23 @@ write_fntype_init (char *str)
      must guard against that.  */
   int tf_found = strstr (str, "tf") != NULL;
+ /* Similarly, look for decimal float tokens. */
+  int dfp_found = (strstr (str, "dd") != NULL
+                  || strstr (str, "td") != NULL
+                  || strstr (str, "sd") != NULL);
+
   /* Avoid side effects of strtok on the original string by using a copy.  */
   char *buf = (char *) malloc (strlen (str) + 1);
   strcpy (buf, str);
if (tf_found)
     fprintf (init_file, "  if (float128_type_node)\n  ");
+  else if (dfp_found)
+    fprintf (init_file, "  if (dfloat64_type_node)\n  ");
fprintf (init_file, " %s\n = build_function_type_list (", buf);
   tok = strtok (buf, "_");
-  write_type_node (tok, tf_found);
+  write_type_node (tok, tf_found || dfp_found);
   tok = strtok (0, "_");
   assert (tok);
   assert (!strcmp (tok, "ftype"));
@@ -2413,7 +2420,7 @@ write_fntype_init (char *str)
   /* Note:  A function with no arguments ends with '_ftype_v'.  */
   while (tok && strcmp (tok, "v"))
     {
-      write_type_node (tok, tf_found);
+      write_type_node (tok, tf_found || dfp_found);
       tok = strtok (0, "_");
       fprintf (init_file, ",\n\t\t\t\t");
     }
@@ -2612,6 +2619,11 @@ write_init_bif_table ()
         must guard against that.  */
       int tf_found = strstr (bifs[i].fndecl, "tf") != NULL;
+ /* Similarly, look for decimal float tokens. */
+      int dfp_found = (strstr (bifs[i].fndecl, "dd") != NULL
+                      || strstr (bifs[i].fndecl, "td") != NULL
+                      || strstr (bifs[i].fndecl, "sd") != NULL);
+
       fprintf (init_file,
               "  if (new_builtins_are_live)\n");
       fprintf (init_file, "    {\n");
@@ -2621,6 +2633,11 @@ write_init_bif_table ()
          fprintf (init_file, "      if (float128_type_node)\n");
          fprintf (init_file, "        {\n");
        }
+      else if (dfp_found)
+       {
+         fprintf (init_file, "      if (dfloat64_type_node)\n");
+         fprintf (init_file, "        {\n");
+       }
fprintf (init_file,
               "      rs6000_builtin_decls_x[(int)RS6000_BIF_%s] = t\n",
@@ -2659,7 +2676,7 @@ write_init_bif_table ()
          fprintf (init_file, "        TREE_READONLY (t) = 1;\n");
        }
- if (tf_found)
+      if (tf_found || dfp_found)
        {
          fprintf (init_file, "        }\n");
          fprintf (init_file, "      else\n");
@@ -2696,6 +2713,11 @@ write_init_ovld_table ()
             must guard against that.  */
          int tf_found = strstr (ovlds[i].fndecl, "tf") != NULL;
+ /* Similarly, look for decimal float tokens. */
+         int dfp_found = (strstr (ovlds[i].fndecl, "dd") != NULL
+                          || strstr (ovlds[i].fndecl, "td") != NULL
+                          || strstr (ovlds[i].fndecl, "sd") != NULL);
+
          /* The fndecl for an overload is arbitrarily the first one
             for the overload.  We sort out the real types when
             processing the overload in the gcc front end.  */
@@ -2708,6 +2730,11 @@ write_init_ovld_table ()
              fprintf (init_file, "      if (float128_type_node)\n");
              fprintf (init_file, "        {\n");
            }
+         else if (dfp_found)
+           {
+             fprintf (init_file, "      if (dfloat64_type_node)\n");
+             fprintf (init_file, "        {\n");
+           }
fprintf (init_file,
                   "      rs6000_builtin_decls_x[(int)RS6000_OVLD_%s] = t\n",
@@ -2725,7 +2752,7 @@ write_init_ovld_table ()
          fprintf (init_file,
                   "                                NULL, NULL_TREE);\n");
- if (tf_found)
+         if (tf_found || dfp_found)
            fprintf (init_file, "        }\n");
fprintf (init_file, " }\n\n");
--
2.27.0


Reply via email to