diff options
author | Joseph Myers <joseph@codesourcery.com> | 2018-03-21 22:29:37 +0000 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2018-03-21 22:29:37 +0000 |
commit | c5c5822ae5c421e2f22e201366231a502c91b70a (patch) | |
tree | a1c2dc12c2981309138920b82613f39bb26024b4 /gcc | |
parent | f4274af890e1a2938ff4604cee1113f33cdce03e (diff) | |
download | gcc-c5c5822ae5c421e2f22e201366231a502c91b70a.zip gcc-c5c5822ae5c421e2f22e201366231a502c91b70a.tar.gz gcc-c5c5822ae5c421e2f22e201366231a502c91b70a.tar.bz2 |
Adjust __builtin_tgmath handling of integer arguments to _FloatN narrowing macros.
When adding __builtin_tgmath to support a better tgmath.h
implementation, I noted that further changes might be needed regarding
the TS 18661 functions that round their results to a narrower type,
because of unresolved issues with how the corresponding type-generic
macros are defined in TS 18661.
The resolution of those issues is still in flux, but the latest
version does indeed require something slightly different from
__builtin_tgmath. It specifies that integer arguments to type-generic
macros such as f32xadd are treated as _Float64 not double - which was
also present in earlier versions of the resolution - but then it also
specifies different handling for _Float64 arguments and double
arguments, which wasn't in earlier versions. Specifically, in the
latest version
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2213.pdf>, f32xadd
with _Float64 arguments would call f32xaddf64, while f32xadd with
double arguments would call f32xaddf64x. Since integer arguments are
converted directly to the argument type of the selected function (not
to double / _Float64x unless that ends up as the argument type), this
is a user-visible difference in semantics that means __builtin_tgmath
actually needs to implement treating integer arguments as _Float64 in
this case (the rest of the latest semantics can then be implemented in
the header, with a few inline functions there).
To avoid releasing with the older version of the __builtin_tgmath
semantics that doesn't work with the latest proposed DR#13 resolution,
this patch implements a rule in __builtin_tgmath that maps integer
types to _Float64 (respectively _Complex _Float64 for complex integer
types) where all the specified functions return the same _FloatN or
_FloatNx type. This does not affect any existing uses of
__builtin_tgmath in glibc's or GCC's tgmath.h since I haven't yet
added any of these type-generic macros to glibc when adding the
corresponding narrowing functions.
Bootstrapped with no regressions on x86_64-pc-linux-gnu.
* doc/extend.texi (__builtin_tgmath): Document when complex
integer types are treated as _Complex _Float64.
gcc/c:
* c-parser.c (c_parser_postfix_expression): For __builtin_tgmath
where all functions return the same _FloatN or _FloatNx type,
treat integer types as _Float64 instead of double.
gcc/testsuite:
* gcc.dg/builtin-tgmath-3.c: New test.
From-SVN: r258751
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 25 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-tgmath-3.c | 50 |
6 files changed, 89 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d02f1c..90c558c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-03-21 Joseph Myers <joseph@codesourcery.com> + + * doc/extend.texi (__builtin_tgmath): Document when complex + integer types are treated as _Complex _Float64. + 2018-03-21 Tom de Vries <tom@codesourcery.com> * doc/extend.texi (__builtin_extend_pointer): Remove pasto. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c1e204d..fc077a8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-03-21 Joseph Myers <joseph@codesourcery.com> + + * c-parser.c (c_parser_postfix_expression): For __builtin_tgmath + where all functions return the same _FloatN or _FloatNx type, + treat integer types as _Float64 instead of double. + 2018-03-21 Jakub Jelinek <jakub@redhat.com> PR c/84999 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 945838c..4772086 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -8530,10 +8530,12 @@ c_parser_postfix_expression (c_parser *parser) argument is decimal, or if the only alternatives for type-generic arguments are of decimal types, and are otherwise treated as double (or _Complex double for - complex integer types). After that adjustment, types - are combined following the usual arithmetic - conversions. If the function only accepts complex - arguments, a complex type is produced. */ + complex integer types, or _Float64 or _Complex _Float64 + if all the return types are the same _FloatN or + _FloatNx type). After that adjustment, types are + combined following the usual arithmetic conversions. + If the function only accepts complex arguments, a + complex type is produced. */ bool arg_complex = all_complex; bool arg_binary = all_binary; bool arg_int_decimal = all_decimal; @@ -8632,6 +8634,19 @@ c_parser_postfix_expression (c_parser *parser) } } } + /* For a macro rounding its result to a narrower type, map + integer types to _Float64 not double if the return type + is a _FloatN or _FloatNx type. */ + bool arg_int_float64 = false; + if (parm_kind[0] == tgmath_fixed + && SCALAR_FLOAT_TYPE_P (parm_first[0]) + && float64_type_node != NULL_TREE) + for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++) + if (parm_first[0] == FLOATN_TYPE_NODE (j)) + { + arg_int_float64 = true; + break; + } tree arg_real = NULL_TREE; for (unsigned int j = 1; j <= nargs; j++) { @@ -8644,6 +8659,8 @@ c_parser_postfix_expression (c_parser *parser) if (INTEGRAL_TYPE_P (type)) type = (arg_int_decimal ? dfloat64_type_node + : arg_int_float64 + ? float64_type_node : double_type_node); if (arg_real == NULL_TREE) arg_real = type; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e94351b..98d06f7 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -11848,7 +11848,9 @@ corresponding to @var{t} for each function. The standard rules for @code{<tgmath.h>} macros are used to find a common type @var{u} from the types of the arguments for parameters whose types vary between the functions; complex integer types (a GNU -extension) are treated like @code{_Complex double} for this purpose. +extension) are treated like @code{_Complex double} for this purpose +(or @code{_Complex _Float64} if all the function return types are the +same @code{_Float@var{n}} or @code{_Float@var{n}x} type). If the function return types vary, or are all the same integer type, the function called is the one for which @var{t} is @var{u}, and it is an error if there is no such function. If the function return types diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea5437a..cc4cbbc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-03-21 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/builtin-tgmath-3.c: New test. + 2018-03-21 Alexandre Oliva <aoliva@redhat.com> PR c++/71965 diff --git a/gcc/testsuite/gcc.dg/builtin-tgmath-3.c b/gcc/testsuite/gcc.dg/builtin-tgmath-3.c new file mode 100644 index 0000000..35364ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-tgmath-3.c @@ -0,0 +1,50 @@ +/* Test __builtin_tgmath: integer arguments mapped to _Float64. */ +/* { dg-do run } */ +/* { dg-options "" } */ +/* { dg-add-options float32 } */ +/* { dg-add-options float64 } */ +/* { dg-require-effective-target float32_runtime } */ +/* { dg-require-effective-target float64_runtime } */ + +extern void abort (void); +extern void exit (int); + +#define CHECK_CALL(C, E, V) \ + do \ + { \ + if ((C) != (E)) \ + abort (); \ + extern __typeof (C) V; \ + } \ + while (0) + +extern _Float32 var_f32; + +_Float32 t1f (float x) { return x + 1; } +_Float32 t1d (double x) { return x + 2; } +_Float32 t1l (long double x) { return x + 3; } +_Float32 t1f64 (_Float64 x) { return x + 4; } + +#define t1v(x) __builtin_tgmath (t1f, t1d, t1l, t1f64, x) + +static void +test_1 (void) +{ + float f = 1; + double d = 2; + long double ld = 3; + _Float64 f64 = 4; + int i = 5; + CHECK_CALL (t1v (f), 2, var_f32); + CHECK_CALL (t1v (d), 4, var_f32); + CHECK_CALL (t1v (ld), 6, var_f32); + CHECK_CALL (t1v (f64), 8, var_f32); + CHECK_CALL (t1v (i), 9, var_f32); +} + +int +main (void) +{ + test_1 (); + exit (0); +} |