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
This commit is contained in:
parent
f4274af890
commit
c5c5822ae5
6 changed files with 89 additions and 5 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
50
gcc/testsuite/gcc.dg/builtin-tgmath-3.c
Normal file
50
gcc/testsuite/gcc.dg/builtin-tgmath-3.c
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Reference in a new issue