aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2018-09-26 22:14:16 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2018-09-26 22:14:16 +0100
commit8313a7643a2cf5f0037e08f4e6a6d7002aeef8a0 (patch)
treeca2a8e8b70bfaf75c364c906aa77cfcc45fef4b0 /gcc
parent01414d53cf3c062ca821de9ae48ba4c3db7d8ad7 (diff)
downloadgcc-8313a7643a2cf5f0037e08f4e6a6d7002aeef8a0.zip
gcc-8313a7643a2cf5f0037e08f4e6a6d7002aeef8a0.tar.gz
gcc-8313a7643a2cf5f0037e08f4e6a6d7002aeef8a0.tar.bz2
Support excess precision for integer / floating-point comparisons (PR c/87390).
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. gcc/c: 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: PR c/87390 * gcc.target/i386/excess-precision-9.c, gcc.target/i386/excess-precision-10.c: New tests. From-SVN: r264656
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c14
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-10.c52
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-9.c52
5 files changed, 130 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 1ea87b9..a8e235c 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2018-09-26 Martin Jambor <mjambor@suse.cz>
PR c/87347
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index a5a7da0..9d09b8d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -11249,6 +11249,20 @@ build_binary_op (location_t location, enum tree_code code,
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa005e7..16407e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2018-09-26 Richard Biener <rguenther@suse.de>
PR debug/87443
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-10.c b/gcc/testsuite/gcc.target/i386/excess-precision-10.c
new file mode 100644
index 0000000..f1b9b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-10.c
@@ -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);
+}
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-9.c b/gcc/testsuite/gcc.target/i386/excess-precision-9.c
new file mode 100644
index 0000000..61e5fc1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-9.c
@@ -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);
+}