diff options
author | Joseph Myers <joseph@codesourcery.com> | 2023-01-06 19:31:26 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2023-01-06 19:31:26 +0000 |
commit | 5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e (patch) | |
tree | d5951144716ceb901447d8ef2d4449cab1f991c3 /gcc/testsuite | |
parent | f3707a55acb980fbcd412ceb980b5621decb4dc0 (diff) | |
download | gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.zip gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.tar.gz gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.tar.bz2 |
c: C2x semantics for __builtin_tgmath
__builtin_tgmath implements <tgmath.h> semantics for integer generic
arguments that handle cases involving _FloatN / _FloatNx types as
specified in TS 18661-3 plus some defect fixes.
C2x has further changes to the semantics for <tgmath.h> macros with
such types, which should also be considered defect fixes (although
handled through the integration of TS 18661-3 in C2x rather than
through an issue tracking process). Specifically, the rules were
changed because of problems raised with using the macros with the
evaluation format types such as float_t and _Float32_t: the older
version of the rules didn't allow passing _FloatN / _FloatNx types to
the narrowing macros returning float or double, or passing float /
double / long double to the narrowing macros returning _FloatN /
_FloatNx, which was a problem with the evaluation format types which
could be either kind of type depending on the value of
FLT_EVAL_METHOD.
Thus the new rules allow cases of mixing types which were not allowed
before - which is not itself a problem for __builtin_tgmath - and, as
part of the changes, the handling of integer arguments was also
changed: if there is any _FloatNx generic argument, integer generic
arguments are treated as _Float32x (not double), while the rule about
treating integer arguments to narrowing macros returning _FloatN or
_FloatNx as _Float64 not double was removed (no longer needed now
double is a valid argument to such macros).
Implement the changes for __builtin_tgmath. (The changes also added a
rule that if any argument is _DecimalNx, integer arguments are treated
as _Decimal64x, but GCC doesn't support _DecimalNx types so nothing is
done about that.)
I have a corresponding glibc patch to update glibc test expectations
for C2x and also ensure that appropriate semantics are followed when
GCC 7 through 12 are used with <tgmath.h> (avoiding __builtin_tgmath
in cases where it doesn't match the C2x semantics).
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/
* doc/extend.texi (__builtin_tgmath): Do not restate standard rule
for handling real integer types.
gcc/c/
* c-parser.cc (c_parser_postfix_expression): Handle integer
generic arguments to functions passed to __builtin_tgmath as
_Float32x if any argument has _FloatNx or _Complex _FloatNx type.
Do not handle integer arguments to some narrowing functions as
_Float64.
gcc/testsuite/
* gcc.dg/builtin-tgmath-3.c: Update expectations and add more
tests.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-tgmath-3.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/builtin-tgmath-3.c b/gcc/testsuite/gcc.dg/builtin-tgmath-3.c index 35364ea..6521130 100644 --- a/gcc/testsuite/gcc.dg/builtin-tgmath-3.c +++ b/gcc/testsuite/gcc.dg/builtin-tgmath-3.c @@ -1,10 +1,12 @@ -/* Test __builtin_tgmath: integer arguments mapped to _Float64. */ +/* Test __builtin_tgmath: integer arguments with _FloatN / _FloatNx. */ /* { dg-do run } */ /* { dg-options "" } */ /* { dg-add-options float32 } */ /* { dg-add-options float64 } */ +/* { dg-add-options float32x } */ /* { dg-require-effective-target float32_runtime } */ /* { dg-require-effective-target float64_runtime } */ +/* { dg-require-effective-target float32x_runtime } */ extern void abort (void); extern void exit (int); @@ -18,7 +20,11 @@ extern void exit (int); } \ while (0) +extern double var_d; extern _Float32 var_f32; +extern _Float64 var_f64; +extern _Float32x var_f32x; +extern _Complex _Float32x var_cf32x; _Float32 t1f (float x) { return x + 1; } _Float32 t1d (double x) { return x + 2; } @@ -39,12 +45,45 @@ test_1 (void) 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); + CHECK_CALL (t1v (i), 7, var_f32); +} + +float t2f (float x, float y) { return 10 * x + y; } +double t2d (double x, double y) { return 100 * x + y; } +long double t2l (long double x, long double y) { return 1000 * x + y; } +_Float32x t2f32x (_Float32x x, _Float32x y) { return 10000 * x + y; } +_Float64 t2f64 (_Float64 x, _Float64 y) { return 100000 * x + y; } + +_Complex _Float32x +ct2f32x (_Complex _Float32x x, _Complex _Float32x y) +{ + return 1000000 * x + y; +} + +#define t2v(x, y) __builtin_tgmath (t2f, t2d, t2l, t2f32x, t2f64, ct2f32x, x, y) + +static void +test_2 (void) +{ + double d = 3; + _Float64 f64 = 6; + _Float32x f32x = 7; + int i = 5; + _Complex _Float32x cf32x = 8; + CHECK_CALL (t2v (f32x, i), 70005, var_f32x); + CHECK_CALL (t2v (i, f32x), 50007, var_f32x); + CHECK_CALL (t2v (f64, i), 600005, var_f64); + CHECK_CALL (t2v (i, f64), 500006, var_f64); + CHECK_CALL (t2v (d, i), 305, var_d); + CHECK_CALL (t2v (i, d), 503, var_d); + CHECK_CALL (t2v (cf32x, i), 8000005, var_cf32x); + CHECK_CALL (t2v (i, cf32x), 5000008, var_cf32x); } int main (void) { test_1 (); + test_2 (); exit (0); } |