* [PATCH][GCC][AArch64] Inline calls to lrint when possible
@ 2017-06-07 11:38 Tamar Christina
2017-06-08 16:51 ` James Greenhalgh
2017-08-10 16:39 ` Szabolcs Nagy
0 siblings, 2 replies; 5+ messages in thread
From: Tamar Christina @ 2017-06-07 11:38 UTC (permalink / raw)
To: GCC Patches; +Cc: nd, James Greenhalgh, Richard Earnshaw, Marcus Shawcroft
[-- Attachment #1: Type: text/plain, Size: 1246 bytes --]
Hi All,
This patch allows the inlining of lrint when -fno-math-errno
assuming that errno does not need to be set when the rounded value
is not representable as a long.
The case
void f(double *a, long *b, double x)
{
*a = __builtin_rint(x);
*b = __builtin_lrint(x);
}
now generates with -fno-math-errno:
f:
frintx d0, d0
fcvtzs x2, d0
str d0, [x0]
str x2, [x1]
ret
When the flag is not used the same function call is emitted as before:
f:
stp x29, x30, [sp, -32]!
frintx d1, d0
add x29, sp, 0
str x19, [sp, 16]
mov x19, x1
str d1, [x0]
bl lrint
str x0, [x19]
ldr x19, [sp, 16]
ldp x29, x30, [sp], 32
ret
Bootstrapped and regtested on aarch64-none-linux-gnu and no regressions.
The patch also has no regressions on Spec2006.
Ok for trunk?
gcc/
2017-06-07 Tamar Christina <tamar.christina@arm.com>
* config/aarch64/aarch64.md (lrint<GPF:mode><GPI:mode>2): New.
gcc/testsuite/
2017-06-07 Tamar Christina <tamar.christina@arm.com>
* gcc.target/aarch64/lrint-matherr.h: New.
* gcc.target/aarch64/inline-lrint_1.c: New.
* gcc.target/aarch64/inline-lrint_2.c: New.
* gcc.target/aarch64/no-inline-lrint_1.c: New.
* gcc.target/aarch64/no-inline-lrint_2.c: New.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: inline-lrint.patch --]
[-- Type: text/x-patch; name="inline-lrint.patch", Size: 5352 bytes --]
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 5adc5edb8dde9c30450b04932a37c41f84cc5ed1..c65159085e342f7611104b2890de99fc02e6fb8e 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4997,6 +4997,18 @@
[(set_attr "type" "f_minmax<stype>")]
)
+(define_expand "lrint<GPF:mode><GPI:mode>2"
+ [(match_operand:GPI 0 "register_operand")
+ (match_operand:GPF 1 "register_operand")]
+ "TARGET_FLOAT"
+{
+ rtx cvt = gen_reg_rtx (<GPF:MODE>mode);
+ emit_insn (gen_rint<GPF:mode>2 (cvt, operands[1]));
+ emit_insn (gen_lbtrunc<GPF:mode><GPI:mode>2 (operands[0], cvt));
+ DONE;
+}
+)
+
;; For copysign (x, y), we want to generate:
;;
;; LDR d2, #(1 << 63)
diff --git a/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..876cecd674b7cb35bc18d5cd3aa5587813e53dd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O3 -fno-math-errno" } */
+
+#include "lrint-matherr.h"
+
+TEST (dld, double, long, )
+TEST (flf, float , long, )
+
+TEST (did, double, int, )
+TEST (fif, float , int, )
+
+TEST (dlld, double, long long, l)
+TEST (fllf, float , long long, l)
+
+/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, d\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-not "bl" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c b/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..baa5aee761788e2b83f8f9283bb0aa7d79aad348
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -fno-math-errno" } */
+
+#include "lrint-matherr.h"
+
+TEST (dld, double, long, )
+TEST (flf, float , long, )
+
+TEST (did, double, int, )
+TEST (fif, float , int, )
+
+TEST (dlld, double, long long, l)
+TEST (fllf, float , long long, l)
+
+/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, d\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, s\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, d\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, s\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-not "bl" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/lrint-matherr.h b/gcc/testsuite/gcc.target/aarch64/lrint-matherr.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc6e3d13f9bd47a316cc56a07917f4b5de185236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/lrint-matherr.h
@@ -0,0 +1,5 @@
+#define TEST(name, float_type, int_type, pref) void f_##name (float_type x) \
+{ \
+ volatile float_type a = __builtin_rint (x); \
+ volatile int_type b = __builtin_l##pref##rint (x); \
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb7f0655687568e9d6783acf88ef56b54a73c2c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O3" } */
+
+#include "lrint-matherr.h"
+
+TEST (dld, double, long, )
+TEST (flf, float , long, )
+
+TEST (did, double, int, )
+TEST (fif, float , int, )
+
+TEST (dlld, double, long long, l)
+TEST (fllf, float , long long, l)
+
+/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "bl\tlrint" 4 } } */
+/* { dg-final { scan-assembler-times "bl\tllrint" 2 } } */
+/* { dg-final { scan-assembler-not "fcvtzs" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..c99843c3a25fbd519f2959d3eb0ce3da3f7f16d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3" } */
+
+#include "lrint-matherr.h"
+
+TEST (dld, double, long, )
+TEST (flf, float , long, )
+
+TEST (did, double, int, )
+TEST (fif, float , int, )
+
+TEST (dlld, double, long long, l)
+TEST (fllf, float , long long, l)
+
+/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "bl\tlrint" 4 } } */
+/* { dg-final { scan-assembler-times "bl\tllrint" 2 } } */
+/* { dg-final { scan-assembler-not "fcvtzs" } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH][GCC][AArch64] Inline calls to lrint when possible
2017-06-07 11:38 [PATCH][GCC][AArch64] Inline calls to lrint when possible Tamar Christina
@ 2017-06-08 16:51 ` James Greenhalgh
2017-06-12 12:10 ` Christophe Lyon
2017-08-10 16:39 ` Szabolcs Nagy
1 sibling, 1 reply; 5+ messages in thread
From: James Greenhalgh @ 2017-06-08 16:51 UTC (permalink / raw)
To: Tamar Christina; +Cc: GCC Patches, nd, Richard Earnshaw, Marcus Shawcroft
On Wed, Jun 07, 2017 at 12:38:27PM +0100, Tamar Christina wrote:
> Hi All,
>
> This patch allows the inlining of lrint when -fno-math-errno
> assuming that errno does not need to be set when the rounded value
> is not representable as a long.
>
> The case
>
> void f(double *a, long *b, double x)
> {
> *a = __builtin_rint(x);
> *b = __builtin_lrint(x);
> }
>
> now generates with -fno-math-errno:
>
> f:
> frintx d0, d0
> fcvtzs x2, d0
> str d0, [x0]
> str x2, [x1]
> ret
>
> When the flag is not used the same function call is emitted as before:
>
> f:
> stp x29, x30, [sp, -32]!
> frintx d1, d0
> add x29, sp, 0
> str x19, [sp, 16]
> mov x19, x1
> str d1, [x0]
> bl lrint
> str x0, [x19]
> ldr x19, [sp, 16]
> ldp x29, x30, [sp], 32
> ret
>
> Bootstrapped and regtested on aarch64-none-linux-gnu and no regressions.
> The patch also has no regressions on Spec2006.
>
> Ok for trunk?
OK.
Thanks,
James
>
> gcc/
> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>
> * config/aarch64/aarch64.md (lrint<GPF:mode><GPI:mode>2): New.
>
> gcc/testsuite/
> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>
> * gcc.target/aarch64/lrint-matherr.h: New.
> * gcc.target/aarch64/inline-lrint_1.c: New.
> * gcc.target/aarch64/inline-lrint_2.c: New.
> * gcc.target/aarch64/no-inline-lrint_1.c: New.
> * gcc.target/aarch64/no-inline-lrint_2.c: New.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH][GCC][AArch64] Inline calls to lrint when possible
2017-06-08 16:51 ` James Greenhalgh
@ 2017-06-12 12:10 ` Christophe Lyon
2017-06-12 14:29 ` Tamar Christina
0 siblings, 1 reply; 5+ messages in thread
From: Christophe Lyon @ 2017-06-12 12:10 UTC (permalink / raw)
To: Tamar Christina; +Cc: GCC Patches, nd, Richard Earnshaw, Marcus Shawcroft
Hi Tamar,
On 8 June 2017 at 18:50, James Greenhalgh <james.greenhalgh@arm.com> wrote:
> On Wed, Jun 07, 2017 at 12:38:27PM +0100, Tamar Christina wrote:
>> Hi All,
>>
>> This patch allows the inlining of lrint when -fno-math-errno
>> assuming that errno does not need to be set when the rounded value
>> is not representable as a long.
>>
>> The case
>>
>> void f(double *a, long *b, double x)
>> {
>> *a = __builtin_rint(x);
>> *b = __builtin_lrint(x);
>> }
>>
>> now generates with -fno-math-errno:
>>
>> f:
>> frintx d0, d0
>> fcvtzs x2, d0
>> str d0, [x0]
>> str x2, [x1]
>> ret
>>
>> When the flag is not used the same function call is emitted as before:
>>
>> f:
>> stp x29, x30, [sp, -32]!
>> frintx d1, d0
>> add x29, sp, 0
>> str x19, [sp, 16]
>> mov x19, x1
>> str d1, [x0]
>> bl lrint
>> str x0, [x19]
>> ldr x19, [sp, 16]
>> ldp x29, x30, [sp], 32
>> ret
>>
>> Bootstrapped and regtested on aarch64-none-linux-gnu and no regressions.
>> The patch also has no regressions on Spec2006.
>>
>> Ok for trunk?
>
> OK.
>
> Thanks,
> James
>
>>
>> gcc/
>> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>>
>> * config/aarch64/aarch64.md (lrint<GPF:mode><GPI:mode>2): New.
>>
>> gcc/testsuite/
>> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>>
>> * gcc.target/aarch64/lrint-matherr.h: New.
>> * gcc.target/aarch64/inline-lrint_1.c: New.
>> * gcc.target/aarch64/inline-lrint_2.c: New.
>> * gcc.target/aarch64/no-inline-lrint_1.c: New.
>> * gcc.target/aarch64/no-inline-lrint_2.c: New.
>
>
The tests
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
fcvtzs\tx[0-9]+, d[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
fcvtzs\tx[0-9]+, s[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
frintx\td[0-9]+, d[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
frintx\ts[0-9]+, s[0-9]+ 3
gcc.target/aarch64/no-inline-lrint_1.c scan-assembler-times
frintx\td[0-9]+, d[0-9]+ 3
gcc.target/aarch64/no-inline-lrint_1.c scan-assembler-times
frintx\ts[0-9]+, s[0-9]+ 3
fail on aarch64 bare-metal targets (and pass on aarch64-linux-gnu)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH][GCC][AArch64] Inline calls to lrint when possible
2017-06-12 12:10 ` Christophe Lyon
@ 2017-06-12 14:29 ` Tamar Christina
0 siblings, 0 replies; 5+ messages in thread
From: Tamar Christina @ 2017-06-12 14:29 UTC (permalink / raw)
To: Christophe Lyon; +Cc: GCC Patches, nd, Richard Earnshaw, Marcus Shawcroft
Hi Christophe,
Thanks, I've committed a fix to the testcase.
Tamar
________________________________________
From: Christophe Lyon <christophe.lyon@linaro.org>
Sent: Monday, June 12, 2017 1:10:38 PM
To: Tamar Christina
Cc: GCC Patches; nd; Richard Earnshaw; Marcus Shawcroft
Subject: Re: [PATCH][GCC][AArch64] Inline calls to lrint when possible
Hi Tamar,
On 8 June 2017 at 18:50, James Greenhalgh <james.greenhalgh@arm.com> wrote:
> On Wed, Jun 07, 2017 at 12:38:27PM +0100, Tamar Christina wrote:
>> Hi All,
>>
>> This patch allows the inlining of lrint when -fno-math-errno
>> assuming that errno does not need to be set when the rounded value
>> is not representable as a long.
>>
>> The case
>>
>> void f(double *a, long *b, double x)
>> {
>> *a = __builtin_rint(x);
>> *b = __builtin_lrint(x);
>> }
>>
>> now generates with -fno-math-errno:
>>
>> f:
>> frintx d0, d0
>> fcvtzs x2, d0
>> str d0, [x0]
>> str x2, [x1]
>> ret
>>
>> When the flag is not used the same function call is emitted as before:
>>
>> f:
>> stp x29, x30, [sp, -32]!
>> frintx d1, d0
>> add x29, sp, 0
>> str x19, [sp, 16]
>> mov x19, x1
>> str d1, [x0]
>> bl lrint
>> str x0, [x19]
>> ldr x19, [sp, 16]
>> ldp x29, x30, [sp], 32
>> ret
>>
>> Bootstrapped and regtested on aarch64-none-linux-gnu and no regressions.
>> The patch also has no regressions on Spec2006.
>>
>> Ok for trunk?
>
> OK.
>
> Thanks,
> James
>
>>
>> gcc/
>> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>>
>> * config/aarch64/aarch64.md (lrint<GPF:mode><GPI:mode>2): New.
>>
>> gcc/testsuite/
>> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>>
>> * gcc.target/aarch64/lrint-matherr.h: New.
>> * gcc.target/aarch64/inline-lrint_1.c: New.
>> * gcc.target/aarch64/inline-lrint_2.c: New.
>> * gcc.target/aarch64/no-inline-lrint_1.c: New.
>> * gcc.target/aarch64/no-inline-lrint_2.c: New.
>
>
The tests
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
fcvtzs\tx[0-9]+, d[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
fcvtzs\tx[0-9]+, s[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
frintx\td[0-9]+, d[0-9]+ 3
gcc.target/aarch64/inline-lrint_1.c scan-assembler-times
frintx\ts[0-9]+, s[0-9]+ 3
gcc.target/aarch64/no-inline-lrint_1.c scan-assembler-times
frintx\td[0-9]+, d[0-9]+ 3
gcc.target/aarch64/no-inline-lrint_1.c scan-assembler-times
frintx\ts[0-9]+, s[0-9]+ 3
fail on aarch64 bare-metal targets (and pass on aarch64-linux-gnu)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH][GCC][AArch64] Inline calls to lrint when possible
2017-06-07 11:38 [PATCH][GCC][AArch64] Inline calls to lrint when possible Tamar Christina
2017-06-08 16:51 ` James Greenhalgh
@ 2017-08-10 16:39 ` Szabolcs Nagy
1 sibling, 0 replies; 5+ messages in thread
From: Szabolcs Nagy @ 2017-08-10 16:39 UTC (permalink / raw)
To: Tamar Christina, GCC Patches
Cc: nd, James Greenhalgh, Richard Earnshaw, Marcus Shawcroft
On 07/06/17 12:38, Tamar Christina wrote:
> Hi All,
>
> This patch allows the inlining of lrint when -fno-math-errno
> assuming that errno does not need to be set when the rounded value
> is not representable as a long.
>
turns out emitting frintx+fcvtzs is wrong for ilp32
because spurious inexact may be raised when the final
result is out-of-bound for 32bit long.
i opened
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81800
> The case
>
> void f(double *a, long *b, double x)
> {
> *a = __builtin_rint(x);
> *b = __builtin_lrint(x);
> }
>
> now generates with -fno-math-errno:
>
> f:
> frintx d0, d0
> fcvtzs x2, d0
> str d0, [x0]
> str x2, [x1]
> ret
>
> When the flag is not used the same function call is emitted as before:
>
> f:
> stp x29, x30, [sp, -32]!
> frintx d1, d0
> add x29, sp, 0
> str x19, [sp, 16]
> mov x19, x1
> str d1, [x0]
> bl lrint
> str x0, [x19]
> ldr x19, [sp, 16]
> ldp x29, x30, [sp], 32
> ret
>
> Bootstrapped and regtested on aarch64-none-linux-gnu and no regressions.
> The patch also has no regressions on Spec2006.
>
> Ok for trunk?
>
> gcc/
> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>
> * config/aarch64/aarch64.md (lrint<GPF:mode><GPI:mode>2): New.
>
> gcc/testsuite/
> 2017-06-07 Tamar Christina <tamar.christina@arm.com>
>
> * gcc.target/aarch64/lrint-matherr.h: New.
> * gcc.target/aarch64/inline-lrint_1.c: New.
> * gcc.target/aarch64/inline-lrint_2.c: New.
> * gcc.target/aarch64/no-inline-lrint_1.c: New.
> * gcc.target/aarch64/no-inline-lrint_2.c: New.
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-08-10 14:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-07 11:38 [PATCH][GCC][AArch64] Inline calls to lrint when possible Tamar Christina
2017-06-08 16:51 ` James Greenhalgh
2017-06-12 12:10 ` Christophe Lyon
2017-06-12 14:29 ` Tamar Christina
2017-08-10 16:39 ` Szabolcs Nagy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).