Commit 8313a764 by Joseph Myers Committed by Joseph Myers

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
parent 01414d53
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
......
......@@ -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;
......
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
......
/* 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);
}
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment