[AArch64] Fix for gcc-7 regression PR 80530
authorRichard Earnshaw <rearnsha@arm.com>
Thu, 27 Apr 2017 14:09:55 +0000 (14:09 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Thu, 27 Apr 2017 14:09:55 +0000 (14:09 +0000)
This patch fixes the regression caused by the changes to add square root
estimation when compiling for xgene-1 or exynos-m1 targets.

The issue is that the expand path for the reciprocal estimate square
root pattern assumes that pattern cannot fail once it has been decided
that this expansion path is available, but because the logic deep inside
aarch64_emit_approx_sqrt() differs from use_rsqrt_p() the two disagree
as to what is safe.

This patch refactors the logic to ensure that we cannot unknowingly make
different choices here.

PR target/80530
* config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Ensure
that the logic for permitting reciprocal estimates matches that
in use_rsqrt_p.

From-SVN: r247340

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index 0197625970976d83f99bb9505e1c02a7df058cd3..526a91dc9f6817b948418b87f87709d311e8dea1 100644 (file)
@@ -1,3 +1,10 @@
+2017-04-27  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/80530
+       * config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Ensure
+       that the logic for permitting reciprocal estimates matches that
+       in use_rsqrt_p.
+
 2017-04-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80534
index 5ba081701248852faf54d700177e4ff516555329..b760905ce3bb374d49153a68dff7948213d853e0 100644 (file)
@@ -7925,33 +7925,40 @@ aarch64_emit_approx_sqrt (rtx dst, rtx src, bool recp)
   machine_mode mode = GET_MODE (dst);
 
   if (GET_MODE_INNER (mode) == HFmode)
-    return false;
+    {
+      gcc_assert (!recp);
+      return false;
+    }
 
-  machine_mode mmsk = mode_for_vector
-                       (int_mode_for_mode (GET_MODE_INNER (mode)),
-                        GET_MODE_NUNITS (mode));
-  bool use_approx_sqrt_p = (!recp
-                           && (flag_mlow_precision_sqrt
-                               || (aarch64_tune_params.approx_modes->sqrt
-                                   & AARCH64_APPROX_MODE (mode))));
-  bool use_approx_rsqrt_p = (recp
-                            && (flag_mrecip_low_precision_sqrt
-                                || (aarch64_tune_params.approx_modes->recip_sqrt
-                                    & AARCH64_APPROX_MODE (mode))));
+  machine_mode mmsk
+    = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (mode)),
+                      GET_MODE_NUNITS (mode));
+  if (!recp)
+    {
+      if (!(flag_mlow_precision_sqrt
+           || (aarch64_tune_params.approx_modes->sqrt
+               & AARCH64_APPROX_MODE (mode))))
+       return false;
+
+      if (flag_finite_math_only
+         || flag_trapping_math
+         || !flag_unsafe_math_optimizations
+         || optimize_function_for_size_p (cfun))
+       return false;
+    }
+  else
+    /* Caller assumes we cannot fail.  */
+    gcc_assert (use_rsqrt_p (mode));
 
-  if (!flag_finite_math_only
-      || flag_trapping_math
-      || !flag_unsafe_math_optimizations
-      || !(use_approx_sqrt_p || use_approx_rsqrt_p)
-      || optimize_function_for_size_p (cfun))
-    return false;
 
   rtx xmsk = gen_reg_rtx (mmsk);
   if (!recp)
-    /* When calculating the approximate square root, compare the argument with
-       0.0 and create a mask.  */
-    emit_insn (gen_rtx_SET (xmsk, gen_rtx_NEG (mmsk, gen_rtx_EQ (mmsk, src,
-                                                         CONST0_RTX (mode)))));
+    /* When calculating the approximate square root, compare the
+       argument with 0.0 and create a mask.  */
+    emit_insn (gen_rtx_SET (xmsk,
+                           gen_rtx_NEG (mmsk,
+                                        gen_rtx_EQ (mmsk, src,
+                                                    CONST0_RTX (mode)))));
 
   /* Estimate the approximate reciprocal square root.  */
   rtx xdst = gen_reg_rtx (mode);