diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 1ea87b95a52..a8e235c9f9b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-09-26 Joseph Myers + + 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 PR c/87347 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index a5a7da0084c..9d09b8d65fd 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 aa005e71441..16407e5244c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-09-26 Joseph Myers + + PR c/87390 + * gcc.target/i386/excess-precision-9.c, + gcc.target/i386/excess-precision-10.c: New tests. + 2018-09-26 Richard Biener 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 00000000000..f1b9b7e1980 --- /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 00000000000..61e5fc104ad --- /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); +}