diff mbox series

[AArch64] Fix PR81800

Message ID VI1PR0801MB2127042BB7ADFD8F69A7F74A831E0@VI1PR0801MB2127.eurprd08.prod.outlook.com
State New
Headers show
Series [AArch64] Fix PR81800 | expand

Commit Message

Wilco Dijkstra May 28, 2019, 5:11 p.m. UTC
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).

Passes regress and bootstrap on AArch64. OK for commit?

ChangeLog
2018-11-13  Wilco Dijkstra  <wdijkstr@arm.com>  

    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.

--

Comments

Wilco Dijkstra July 31, 2019, 5 p.m. UTC | #1
ping

 
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).
 
 Passes regress and bootstrap on AArch64. OK for commit?
 
 ChangeLog
 2018-11-13  Wilco Dijkstra  <wdijkstr@arm.com>  
 
     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.
 
 --
 
 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
 index 5a1894063a1ed2db1cc947c9c449d48808ed96ae..f08cd0930b3fc6527fbca218ad3c464f1ead0103 100644
 --- a/gcc/config/aarch64/aarch64.md
 +++ b/gcc/config/aarch64/aarch64.md
 @@ -6304,7 +6304,7 @@ (define_expand "lrint<GPF:mode><GPI:mode>2"
    [(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/gcc.target/aarch64/no-inline-lrint_3.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
 new file mode 100644
 index 0000000000000000000000000000000000000000..ca772cb999e7b6cfbd3f080111d3eb479d43f47b
 --- /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 } } */
James Greenhalgh Aug. 12, 2019, 5:07 p.m. UTC | #2
On Tue, May 28, 2019 at 06:11:29PM +0100, Wilco Dijkstra wrote:
> 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).
> 
> Passes regress and bootstrap on AArch64. OK for commit?

OK.

Thanks,
James

> 
> ChangeLog
> 2018-11-13  Wilco Dijkstra  <wdijkstr@arm.com>  
> 
>     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.
> 
> --
> 
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 5a1894063a1ed2db1cc947c9c449d48808ed96ae..f08cd0930b3fc6527fbca218ad3c464f1ead0103 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -6304,7 +6304,7 @@ (define_expand "lrint<GPF:mode><GPI:mode>2"
>    [(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/gcc.target/aarch64/no-inline-lrint_3.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..ca772cb999e7b6cfbd3f080111d3eb479d43f47b
> --- /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 } } */
>
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 5a1894063a1ed2db1cc947c9c449d48808ed96ae..f08cd0930b3fc6527fbca218ad3c464f1ead0103 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -6304,7 +6304,7 @@  (define_expand "lrint<GPF:mode><GPI:mode>2"
   [(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/gcc.target/aarch64/no-inline-lrint_3.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
new file mode 100644
index 0000000000000000000000000000000000000000..ca772cb999e7b6cfbd3f080111d3eb479d43f47b
--- /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 } } */