summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2019-08-13 10:46:44 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2019-08-13 10:46:44 +0000
commitfb802d91461a2d65e9618abb6298c6ca7d39e7d7 (patch)
treebce0a294e66323ab75c094eaba864653b9fb6ffa
parent4aeb1ba7f62c1d680c819ae3e137c3bad6f520ca (diff)
downloadgcc-fb802d91461a2d65e9618abb6298c6ca7d39e7d7.tar.gz
[AArch64] Fix PR81800
PR81800 is about the lrint inline giving spurious FE_INEXACT exceptions. The previous change for PR81800 didn't fix this: when lrint is disabled in the backend, the midend will simply use llrint. This actually makes things worse since llrint now also ignores FE_INVALID exceptions! The fix is to disable lrint/llrint on double if the size of a long is smaller (ie. ilp32). gcc/ PR target/81800 * gcc/config/aarch64/aarch64.md (lrint): Disable lrint pattern if GPF operand is larger than a long int. testsuite/ PR target/81800 * gcc.target/aarch64/no-inline-lrint_3.c: New test. From-SVN: r274376
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.md2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c17
4 files changed, 29 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4da505ed62b..75e5c2af689 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/81800
+ * gcc/config/aarch64/aarch64.md (lrint): Disable lrint pattern if GPF
+ operand is larger than a long int.
+
2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
* machmode.h (opt_mode::else_mode): New function.
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a8dd070333d..a85bdd13fae 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6323,7 +6323,7 @@
[(match_operand:GPI 0 "register_operand")
(match_operand:GPF 1 "register_operand")]
"TARGET_FLOAT
- && ((GET_MODE_SIZE (<GPF:MODE>mode) <= GET_MODE_SIZE (<GPI:MODE>mode))
+ && ((GET_MODE_BITSIZE (<GPF:MODE>mode) <= LONG_TYPE_SIZE)
|| !flag_trapping_math || flag_fp_int_builtin_inexact)"
{
rtx cvt = gen_reg_rtx (<GPF:MODE>mode);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 11bbee10f0a..baf1b25cf44 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/81800
+ * gcc.target/aarch64/no-inline-lrint_3.c: New test.
+
2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/init_2.c: Expect ld1rd to be used
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
new file mode 100644
index 00000000000..ca772cb999e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -fno-math-errno -fno-fp-int-builtin-inexact" } */
+
+#define TEST(name, float_type, int_type, fn) void f_##name (float_type x) \
+{ \
+ volatile int_type b = __builtin_##fn (x); \
+}
+
+TEST (dld, double, long, lrint)
+TEST (flf, float , long, lrintf)
+
+TEST (did, double, int, lrint)
+TEST (fif, float , int, lrintf)
+
+/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, \[d,s\]\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "bl\tlrint" 2 } } */