[Patch AArch64] Fixup floating point division with -march=armv8-a+nosimd
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>
Tue, 28 Nov 2017 10:26:28 +0000 (10:26 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Tue, 28 Nov 2017 10:26:28 +0000 (10:26 +0000)
The canonical examples is :

    double
    foo (double x, double y)
      {
        return x / y;
      }

    with -march=armv8-a+nosimd

generates a function that calls __divdf3. Ofcourse on AArch64 we don't
have any software floating point and this causes issues.

There is also a problem in +nosimd that has existed since the dawn of
time in the port with respect to long doubles (128 bit floating
point), here the ABI and the compiler expect the presence of the SIMD
unit as these parameters are passed in the vector registers. Thus
while +nosimd tries to prevent the use of SIMD instructions in the
compile we don't get this right as we end up using ldr qN / str qN
instructions and even there I think things go wrong in a simple
example that I tried.

Is that sufficient to consider marking +nosimd as deprecated in GCC-8
and remove this in a future release ?

That is not a subject for this patch but something separate but I
would like to put this into trunk and the release
branches. Bootstrapped and regression tested on my aarch64 desktop.

Ok ?

From-SVN: r255194

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

index 021035c81ac45203ea487270e1709c2dcc13d3c3..641dc072afdd32cb8d7294196b3465c577db14fe 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-28  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+
+       * config/aarch64/aarch64.md (div<mode>3): Change check to TARGET_FLOAT.
+       * config/aarch64/aarch64.c (aarch64_emit_approx_div): Add early exit
+       for vector mode and !TARGET_SIMD.
+
 2017-11-28  Jakub Jelinek  <jakub@redhat.com>
 
        * tree.def (SWITCH_EXPR): Change from 3 operand to 2 operand tree.
index 5bd99f894a0c9a0d6fa1d0e219710edff3e82c7d..98221bbba20f1ef2bea2bfc71f795ee38155298f 100644 (file)
@@ -8442,6 +8442,9 @@ aarch64_emit_approx_div (rtx quo, rtx num, rtx den)
       || !use_approx_division_p)
     return false;
 
+  if (!TARGET_SIMD && VECTOR_MODE_P (mode))
+    return false;
+
   /* Estimate the approximate reciprocal.  */
   rtx xrcp = gen_reg_rtx (mode);
   emit_insn ((*get_recpe_type (mode)) (xrcp, den));
index 423a3352aab438f645aab6aa99f22f84f3b47ea5..83e494250904bb18982b6b4919b953de6e1efa15 100644 (file)
  [(set (match_operand:GPF_F16 0 "register_operand")
        (div:GPF_F16 (match_operand:GPF_F16 1 "general_operand")
                    (match_operand:GPF_F16 2 "register_operand")))]
- "TARGET_SIMD"
+ "TARGET_FLOAT"
 {
   if (aarch64_emit_approx_div (operands[0], operands[1], operands[2]))
     DONE;