Hi Joseph,

On Wed, 26 Sep 2018 at 23:15, Joseph Myers <jos...@codesourcery.com> 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  <jos...@codesourcery.com>
>
>         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  <jos...@codesourcery.com>
>
>         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
> jos...@codesourcery.com

Reply via email to