Message ID | VI1PR0801MB2127042BB7ADFD8F69A7F74A831E0@VI1PR0801MB2127.eurprd08.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [AArch64] Fix PR81800 | expand |
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 } } */
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 --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 } } */