public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Support excess precision for integer / floating-point comparisons (PR c/87390)
@ 2018-09-26 21:16 Joseph Myers
  2018-09-27 19:24 ` Christophe Lyon
  0 siblings, 1 reply; 5+ messages in thread
From: Joseph Myers @ 2018-09-26 21:16 UTC (permalink / raw)
  To: gcc-patches

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  <joseph@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  <joseph@codesourcery.com>

	PR c/87390
	* gcc.target/i386/excess-precision-9.c,
	gcc.target/i386/excess-precision-10.c: New tests.

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
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Support excess precision for integer / floating-point comparisons (PR c/87390)
  2018-09-26 21:16 Support excess precision for integer / floating-point comparisons (PR c/87390) Joseph Myers
@ 2018-09-27 19:24 ` Christophe Lyon
  2018-09-27 19:31   ` Joseph Myers
  0 siblings, 1 reply; 5+ messages in thread
From: Christophe Lyon @ 2018-09-27 19:24 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc Patches

Hi Joseph,

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Support excess precision for integer / floating-point comparisons (PR c/87390)
  2018-09-27 19:24 ` Christophe Lyon
@ 2018-09-27 19:31   ` Joseph Myers
  2018-09-28  8:11     ` Christophe Lyon
  0 siblings, 1 reply; 5+ messages in thread
From: Joseph Myers @ 2018-09-27 19:31 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc Patches

On Thu, 27 Sep 2018, Christophe Lyon wrote:

> 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)

Does this patch help?

Index: gcc/testsuite/gcc.dg/torture/fp-int-convert.h
===================================================================
--- gcc/testsuite/gcc.dg/torture/fp-int-convert.h	(revision 264666)
+++ gcc/testsuite/gcc.dg/torture/fp-int-convert.h	(working copy)
@@ -90,6 +90,7 @@
   if (ivin != (VAL)					\
       || ((PREC_OK) && ivout != ivin)			\
       || ((PREC_OK) && ivout != (VAL))			\
-      || fv1 != (VAL) || fv2 != (VAL) || fv1 != fv2)	\
+      || fv1 != (FT) (VAL) || fv2 != (FT) (VAL)		\
+      || fv1 != fv2)					\
     abort ();						\
 } while (0)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Support excess precision for integer / floating-point comparisons (PR c/87390)
  2018-09-27 19:31   ` Joseph Myers
@ 2018-09-28  8:11     ` Christophe Lyon
  2018-09-28 15:48       ` Joseph Myers
  0 siblings, 1 reply; 5+ messages in thread
From: Christophe Lyon @ 2018-09-28  8:11 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc Patches

On Thu, 27 Sep 2018 at 21:29, Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Thu, 27 Sep 2018, Christophe Lyon wrote:
>
> > 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)
>
> Does this patch help?
>
> Index: gcc/testsuite/gcc.dg/torture/fp-int-convert.h
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/fp-int-convert.h       (revision 264666)
> +++ gcc/testsuite/gcc.dg/torture/fp-int-convert.h       (working copy)
> @@ -90,6 +90,7 @@
>    if (ivin != (VAL)                                    \
>        || ((PREC_OK) && ivout != ivin)                  \
>        || ((PREC_OK) && ivout != (VAL))                 \
> -      || fv1 != (VAL) || fv2 != (VAL) || fv1 != fv2)   \
> +      || fv1 != (FT) (VAL) || fv2 != (FT) (VAL)                \
> +      || fv1 != fv2)                                   \
>      abort ();                                          \
>  } while (0)
>

Yes, it works, thanks!

> --
> Joseph S. Myers
> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Support excess precision for integer / floating-point comparisons (PR c/87390)
  2018-09-28  8:11     ` Christophe Lyon
@ 2018-09-28 15:48       ` Joseph Myers
  0 siblings, 0 replies; 5+ messages in thread
From: Joseph Myers @ 2018-09-28 15:48 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: gcc Patches

On Fri, 28 Sep 2018, Christophe Lyon wrote:

> Yes, it works, thanks!

Thanks, committed as r264696.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-09-28 15:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-26 21:16 Support excess precision for integer / floating-point comparisons (PR c/87390) Joseph Myers
2018-09-27 19:24 ` Christophe Lyon
2018-09-27 19:31   ` Joseph Myers
2018-09-28  8:11     ` Christophe Lyon
2018-09-28 15:48       ` Joseph Myers

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).