[GCC][BUG][ARM] Fix ICE due to BFmode libfunc call (PR93300)
authorStam Markianos-Wright <stam.markianos-wright@arm.com>
Wed, 5 Feb 2020 19:21:42 +0000 (19:21 +0000)
committerStam Markianos-Wright <stam.markianos-wright@arm.com>
Thu, 6 Feb 2020 10:20:08 +0000 (10:20 +0000)
    This was sent and approved on gcc-patches as "[GCC][BUG][Aarch64][ARM]
    (PR93300) Fix ICE due to BFmode placement in GET_MODES_WIDER chain".

    The observed error came about because BFmode was placed between HFmode
    and SFmode in the GET_MODES_WIDER chain, resulting in convert_mode_scalar
    attempting to gen a libfunc for a HFmode -> BFmode conversion.

    This patch registers NULL for all libfuncs in BFmode, which stops the
    middle-end from attempting to generate them.

    gcc/ChangeLog:
    2020-02-06  Stam Markianos-Wright  <stam.markianos-wright@arm.com>

PR target/93300
* config/arm/arm.c (arm_block_arith_comp_libfuncs_for_mode): New.
(arm_init_libfuncs): Add BFmode support to block spurious BF libfuncs.
Use arm_block_arith_comp_libfuncs_for_mode for HFmode.

gcc/ChangeLog
gcc/config/arm/arm.c

index 382e31368dc11822707dbc9d190e9f93eeb08d05..82079c763256a71f84ec7ba632042d3e8af75c00 100644 (file)
@@ -1,3 +1,10 @@
+2020-02-06  Stam Markianos-Wright  <stam.markianos-wright@arm.com>
+
+       PR target/93300
+       * config/arm/arm.c (arm_block_arith_comp_libfuncs_for_mode): New.
+       (arm_init_libfuncs): Add BFmode support to block spurious BF libfuncs.
+       Use arm_block_arith_comp_libfuncs_for_mode for HFmode.
+
 2020-02-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/93594
index fe3bc675b42ca31b3aa0a84498779182c2cef25f..9cc7bc0e56217574d436e257d2d7a03b132912e4 100644 (file)
@@ -2491,10 +2491,35 @@ arm_set_fixed_conv_libfunc (convert_optab optable, machine_mode to,
 
 static GTY(()) rtx speculation_barrier_libfunc;
 
+/* Record that we have no arithmetic or comparison libfuncs for
+   machine mode MODE.  */
+
+static void
+arm_block_arith_comp_libfuncs_for_mode (machine_mode mode)
+{
+  /* Arithmetic.  */
+  set_optab_libfunc (add_optab, mode, NULL);
+  set_optab_libfunc (sdiv_optab, mode, NULL);
+  set_optab_libfunc (smul_optab, mode, NULL);
+  set_optab_libfunc (neg_optab, mode, NULL);
+  set_optab_libfunc (sub_optab, mode, NULL);
+
+  /* Comparisons.  */
+  set_optab_libfunc (eq_optab, mode, NULL);
+  set_optab_libfunc (ne_optab, mode, NULL);
+  set_optab_libfunc (lt_optab, mode, NULL);
+  set_optab_libfunc (le_optab, mode, NULL);
+  set_optab_libfunc (ge_optab, mode, NULL);
+  set_optab_libfunc (gt_optab, mode, NULL);
+  set_optab_libfunc (unord_optab, mode, NULL);
+}
+
 /* Set up library functions unique to ARM.  */
 static void
 arm_init_libfuncs (void)
 {
+  machine_mode mode_iter;
+
   /* For Linux, we have access to kernel support for atomic operations.  */
   if (arm_abi == ARM_ABI_AAPCS_LINUX)
     init_sync_libfuncs (MAX_SYNC_LIBFUNC_SIZE);
@@ -2623,27 +2648,23 @@ arm_init_libfuncs (void)
                         ? "__gnu_d2h_ieee"
                         : "__gnu_d2h_alternative"));
 
-      /* Arithmetic.  */
-      set_optab_libfunc (add_optab, HFmode, NULL);
-      set_optab_libfunc (sdiv_optab, HFmode, NULL);
-      set_optab_libfunc (smul_optab, HFmode, NULL);
-      set_optab_libfunc (neg_optab, HFmode, NULL);
-      set_optab_libfunc (sub_optab, HFmode, NULL);
-
-      /* Comparisons.  */
-      set_optab_libfunc (eq_optab, HFmode, NULL);
-      set_optab_libfunc (ne_optab, HFmode, NULL);
-      set_optab_libfunc (lt_optab, HFmode, NULL);
-      set_optab_libfunc (le_optab, HFmode, NULL);
-      set_optab_libfunc (ge_optab, HFmode, NULL);
-      set_optab_libfunc (gt_optab, HFmode, NULL);
-      set_optab_libfunc (unord_optab, HFmode, NULL);
+      arm_block_arith_comp_libfuncs_for_mode (HFmode);
       break;
 
     default:
       break;
     }
 
+  /* For all possible libcalls in BFmode, record NULL.  */
+  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
+    {
+      set_conv_libfunc (trunc_optab, BFmode, mode_iter, NULL);
+      set_conv_libfunc (trunc_optab, mode_iter, BFmode, NULL);
+      set_conv_libfunc (sext_optab, mode_iter, BFmode, NULL);
+      set_conv_libfunc (sext_optab, BFmode, mode_iter, NULL);
+    }
+  arm_block_arith_comp_libfuncs_for_mode (BFmode);
+
   /* Use names prefixed with __gnu_ for fixed-point helper functions.  */
   {
     const arm_fixed_mode_set fixed_arith_modes[] =