From 1be49a38e45a80d1ee6854f262c94abeb621dfda Mon Sep 17 00:00:00 2001 From: Ramana Radhakrishnan Date: Tue, 28 Nov 2017 10:26:28 +0000 Subject: [PATCH] [Patch AArch64] Fixup floating point division with -march=armv8-a+nosimd 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 | 6 ++++++ gcc/config/aarch64/aarch64.c | 3 +++ gcc/config/aarch64/aarch64.md | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 021035c81ac..641dc072afd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-11-28 Ramana Radhakrishnan + + * config/aarch64/aarch64.md (div3): 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 * tree.def (SWITCH_EXPR): Change from 3 operand to 2 operand tree. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 5bd99f894a0..98221bbba20 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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)); diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 423a3352aab..83e49425090 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -5093,7 +5093,7 @@ [(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; -- 2.30.2