diff mbox

PR 61876: Do not convert cast + __builtin_round into __builtin_lround unless -fno-math-errno is used

Message ID 53D0FDD9.1090408@arm.com
State New
Headers show

Commit Message

Kyrylo Tkachov July 24, 2014, 12:36 p.m. UTC
Hi all,

This fixes PR 61876 by not converting the round + cast into an lround 
unless -fno-math-errno is specified.
This is because lround can potentially set math errno whereas round + 
cast doesn't, so the transformation isn't universally valid.

This will cause the tests:
gcc.target/aarch64/fcvt_double_long.c
gcc.target/aarch64/fcvt_double_ulong.c

to start passing on aarch64-linux.

aarch64 and x86 bootstrap and regtest looks fine.

Ok for trunk?

2014-06-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     PR middle-end/61876
     * convert.c (convert_to_integer): Do not convert BUILT_IN_ROUND and 
cast
     when flat_errno_math is on.

Comments

Richard Biener July 24, 2014, 12:51 p.m. UTC | #1
On Thu, Jul 24, 2014 at 2:36 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
> Hi all,
>
> This fixes PR 61876 by not converting the round + cast into an lround unless
> -fno-math-errno is specified.
> This is because lround can potentially set math errno whereas round + cast
> doesn't, so the transformation isn't universally valid.
>
> This will cause the tests:
> gcc.target/aarch64/fcvt_double_long.c
> gcc.target/aarch64/fcvt_double_ulong.c
>
> to start passing on aarch64-linux.
>
> aarch64 and x86 bootstrap and regtest looks fine.
>
> Ok for trunk?

Ok.  Does this really only apply to the round() case and not to all
the others (floor, ceil, rint) as well?

Thanks,
Richard.

> 2014-06-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>
>     PR middle-end/61876
>     * convert.c (convert_to_integer): Do not convert BUILT_IN_ROUND and cast
>     when flat_errno_math is on.
Kyrylo Tkachov July 24, 2014, 1:06 p.m. UTC | #2
On 24/07/14 13:51, Richard Biener wrote:
> On Thu, Jul 24, 2014 at 2:36 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
>> Hi all,
>>
>> This fixes PR 61876 by not converting the round + cast into an lround unless
>> -fno-math-errno is specified.
>> This is because lround can potentially set math errno whereas round + cast
>> doesn't, so the transformation isn't universally valid.
>>
>> This will cause the tests:
>> gcc.target/aarch64/fcvt_double_long.c
>> gcc.target/aarch64/fcvt_double_ulong.c
>>
>> to start passing on aarch64-linux.
>>
>> aarch64 and x86 bootstrap and regtest looks fine.
>>
>> Ok for trunk?
> Ok.  Does this really only apply to the round() case and not to all
> the others (floor, ceil, rint) as well?
Thanks for the review,

 From what I understand only lround and lrint are defined in the C standard.
There is no lfloor for example, the builtin lfloor in gcc is just an 
extension.
Do we have defined semantics for lfloor somewhere?

The lrint case seems to be similar to the lround case (the documentation 
say the same thing in the Errors section). I can whip up a patch to 
guard that transformation as well...

Kyrill

>
> Thanks,
> Richard.
>
>> 2014-06-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>
>>      PR middle-end/61876
>>      * convert.c (convert_to_integer): Do not convert BUILT_IN_ROUND and cast
>>      when flat_errno_math is on.
diff mbox

Patch

diff --git a/gcc/convert.c b/gcc/convert.c
index 09bc555..8dbf3cb 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -456,8 +456,8 @@  convert_to_integer (tree type, tree expr)
 	  break;
 
 	CASE_FLT_FN (BUILT_IN_ROUND):
-	  /* Only convert in ISO C99 mode.  */
-	  if (!targetm.libc_has_function (function_c99_misc))
+	  /* Only convert in ISO C99 mode and with -fno-math-errno.  */
+	  if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
 	    break;
 	  if (outprec < TYPE_PRECISION (integer_type_node)
 	      || (outprec == TYPE_PRECISION (integer_type_node)