Commit c5c5822a by Joseph Myers Committed by Joseph Myers

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
parent f4274af8
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> 2018-03-21 Tom de Vries <tom@codesourcery.com>
* doc/extend.texi (__builtin_extend_pointer): Remove pasto. * doc/extend.texi (__builtin_extend_pointer): Remove pasto.
......
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> 2018-03-21 Jakub Jelinek <jakub@redhat.com>
PR c/84999 PR c/84999
......
...@@ -8530,10 +8530,12 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -8530,10 +8530,12 @@ c_parser_postfix_expression (c_parser *parser)
argument is decimal, or if the only alternatives for argument is decimal, or if the only alternatives for
type-generic arguments are of decimal types, and are type-generic arguments are of decimal types, and are
otherwise treated as double (or _Complex double for otherwise treated as double (or _Complex double for
complex integer types). After that adjustment, types complex integer types, or _Float64 or _Complex _Float64
are combined following the usual arithmetic if all the return types are the same _FloatN or
conversions. If the function only accepts complex _FloatNx type). After that adjustment, types are
arguments, a complex type is produced. */ 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_complex = all_complex;
bool arg_binary = all_binary; bool arg_binary = all_binary;
bool arg_int_decimal = all_decimal; bool arg_int_decimal = all_decimal;
...@@ -8632,6 +8634,19 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -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; tree arg_real = NULL_TREE;
for (unsigned int j = 1; j <= nargs; j++) for (unsigned int j = 1; j <= nargs; j++)
{ {
...@@ -8644,6 +8659,8 @@ c_parser_postfix_expression (c_parser *parser) ...@@ -8644,6 +8659,8 @@ c_parser_postfix_expression (c_parser *parser)
if (INTEGRAL_TYPE_P (type)) if (INTEGRAL_TYPE_P (type))
type = (arg_int_decimal type = (arg_int_decimal
? dfloat64_type_node ? dfloat64_type_node
: arg_int_float64
? float64_type_node
: double_type_node); : double_type_node);
if (arg_real == NULL_TREE) if (arg_real == NULL_TREE)
arg_real = type; arg_real = type;
......
...@@ -11848,7 +11848,9 @@ corresponding to @var{t} for each function. ...@@ -11848,7 +11848,9 @@ corresponding to @var{t} for each function.
The standard rules for @code{<tgmath.h>} macros are used to find a 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 common type @var{u} from the types of the arguments for parameters
whose types vary between the functions; complex integer types (a GNU 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, 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 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 an error if there is no such function. If the function return types
......
2018-03-21 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/builtin-tgmath-3.c: New test.
2018-03-21 Alexandre Oliva <aoliva@redhat.com> 2018-03-21 Alexandre Oliva <aoliva@redhat.com>
PR c++/71965 PR c++/71965
......
/* 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);
}
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