Hi Joseph,
On Wed, 26 Sep 2018 at 23:15, Joseph Myers <[email protected]> wrote:
>
> In C11, implicit conversions from integer to floating-point types
> produce results with the range and precision of the corresponding
> evaluation format rather than only those of the type implicitly
> converted to. This patch implements that case of C11 excess precision
> semantics in the case of a comparison between integer and
> floating-point types, previously missed when implementing other cases
> of excess precision for such implicit conversions. As with other such
> fixes, this patch conservatively follows the reading of C99 where
> conversions from integer to floating-point do not produce results with
> excess precision and so the change is made for C11 mode only.
>
> Bootstrapped with no regressions on x86_64-pc-linux-gnu. Applied to
> mainline.
>
> gcc/c:
> 2018-09-26 Joseph Myers <[email protected]>
>
> PR c/87390
> * c-typeck.c (build_binary_op): Use excess precision for
> comparisons of integers and floating-point for C11 and later.
>
> gcc/testsuite:
> 2018-09-26 Joseph Myers <[email protected]>
>
> PR c/87390
> * gcc.target/i386/excess-precision-9.c,
> gcc.target/i386/excess-precision-10.c: New tests.
>
After this patch I've noticed regressions on
fp-int-convert-float16-timode.c
gcc.dg/torture/fp-int-convert-float16.c
on aarch64 and arm (at execution time)
Christophe
> Index: gcc/c/c-typeck.c
> ===================================================================
> --- gcc/c/c-typeck.c (revision 264650)
> +++ gcc/c/c-typeck.c (working copy)
> @@ -11249,6 +11249,20 @@ build_binary_op (location_t location, enum tree_co
> case EXACT_DIV_EXPR:
> may_need_excess_precision = true;
> break;
> +
> + case EQ_EXPR:
> + case NE_EXPR:
> + case LE_EXPR:
> + case GE_EXPR:
> + case LT_EXPR:
> + case GT_EXPR:
> + /* Excess precision for implicit conversions of integers to
> + floating point in C11 and later. */
> + may_need_excess_precision = (flag_isoc11
> + && (ANY_INTEGRAL_TYPE_P (type0)
> + || ANY_INTEGRAL_TYPE_P (type1)));
> + break;
> +
> default:
> may_need_excess_precision = false;
> break;
> Index: gcc/testsuite/gcc.target/i386/excess-precision-10.c
> ===================================================================
> --- gcc/testsuite/gcc.target/i386/excess-precision-10.c (nonexistent)
> +++ gcc/testsuite/gcc.target/i386/excess-precision-10.c (working copy)
> @@ -0,0 +1,52 @@
> +/* Excess precision tests. Test implicit conversions in comparisons:
> + excess precision in C11 mode. */
> +/* { dg-do run } */
> +/* { dg-options "-std=c11 -mfpmath=387 -fexcess-precision=standard" } */
> +
> +extern void abort (void);
> +extern void exit (int);
> +
> +int
> +main (void)
> +{
> + float f = 0x1p63f;
> + unsigned long long int u = (1ULL << 63) + 1;
> +
> + if ((f == u) != 0)
> + abort ();
> +
> + if ((u == f) != 0)
> + abort ();
> +
> + if ((f != u) != 1)
> + abort ();
> +
> + if ((u != f) != 1)
> + abort ();
> +
> + if ((f < u) != 1)
> + abort ();
> +
> + if ((u < f) != 0)
> + abort ();
> +
> + if ((f <= u) != 1)
> + abort ();
> +
> + if ((u <= f) != 0)
> + abort ();
> +
> + if ((f > u) != 0)
> + abort ();
> +
> + if ((u > f) != 1)
> + abort ();
> +
> + if ((f >= u) != 0)
> + abort ();
> +
> + if ((u >= f) != 1)
> + abort ();
> +
> + exit (0);
> +}
> Index: gcc/testsuite/gcc.target/i386/excess-precision-9.c
> ===================================================================
> --- gcc/testsuite/gcc.target/i386/excess-precision-9.c (nonexistent)
> +++ gcc/testsuite/gcc.target/i386/excess-precision-9.c (working copy)
> @@ -0,0 +1,52 @@
> +/* Excess precision tests. Test implicit conversions in comparisons:
> + no excess precision in C99 mode. */
> +/* { dg-do run } */
> +/* { dg-options "-std=c99 -mfpmath=387 -fexcess-precision=standard" } */
> +
> +extern void abort (void);
> +extern void exit (int);
> +
> +int
> +main (void)
> +{
> + float f = 0x1p63f;
> + unsigned long long int u = (1ULL << 63) + 1;
> +
> + if ((f == u) != 1)
> + abort ();
> +
> + if ((u == f) != 1)
> + abort ();
> +
> + if ((f != u) != 0)
> + abort ();
> +
> + if ((u != f) != 0)
> + abort ();
> +
> + if ((f < u) != 0)
> + abort ();
> +
> + if ((u < f) != 0)
> + abort ();
> +
> + if ((f <= u) != 1)
> + abort ();
> +
> + if ((u <= f) != 1)
> + abort ();
> +
> + if ((f > u) != 0)
> + abort ();
> +
> + if ((u > f) != 0)
> + abort ();
> +
> + if ((f >= u) != 1)
> + abort ();
> +
> + if ((u >= f) != 1)
> + abort ();
> +
> + exit (0);
> +}
>
> --
> Joseph S. Myers
> [email protected]