From: Matthew Malcomson <mmalcom...@nvidia.com> N.b. including docs maintainers to ask about whether this flag should be documented in invoke.texi -- I suspect that would be determined partly based on the feedback I get on this patch about whether it should be something mostly for the testsuite and otherwise internally derived based on other factors or whether it should be something available for a user to adjust directly.
-------------- >8 ------- 8< ----------- As it stands the floating point exception handling needs to include libatomic. I plan to include libatomic by default when compiling as per PR/81358. However even that won't help when a target has no libatomic. Bare metal cross compilers get built without libatomic often. Rather than disable this feature for bare metal targets we provide a fallback through a command line argument that allows disabling the emition of floating point exception handling code in calls to __atomic_fetch_add and similar. This is also useful for the testsuite, since it enables more testing of this feature on targets which have not built libatomic. N.b. I would appreciate any feedback about how one should handle such a situation when working with C11 _Atomic types. They have the same problem that they require libatomic and sometimes libatomic is not available. Is this just something that will stay as a known limitation for certain platforms? Is there something in the works to make it more viable? Similarly I would open the question up to others about whether it seems sensible to turn this flag on by default when the compiler is configured with `--disable-libatomic`. I'm not confident on that since I don't know how often people disable building libatomic and instead test against a system libatomic. gcc/c-family/ChangeLog: * c-common.cc (atomic_alttyped_fetch_using_cas_loop): Avoid emitting floating point exception handling code if new flag given. * c.opt: Introduce new -fatomic-fp-fetchop-exceptions flag. gcc/testsuite/ChangeLog: * gcc.dg/atomic-op-fp.c: Use new flag to avoid requiring libatomic when libatomic is not available. * gcc.dg/atomic-op-fpf.c: Likewise. * gcc.dg/atomic-op-fpf128.c: Likewise. * gcc.dg/atomic-op-fpf16.c: Likewise. * gcc.dg/atomic-op-fpf16b.c: Likewise. * gcc.dg/atomic-op-fpf32.c: Likewise. * gcc.dg/atomic-op-fpf32x.c: Likewise. * gcc.dg/atomic-op-fpf64.c: Likewise. * gcc.dg/atomic-op-fpf64x.c: Likewise. * gcc.dg/atomic-op-fpl.c: Likewise. * gcc.dg/atomic-op-fp-fenv-flag.c: New test. Signed-off-by: Matthew Malcomson <mmalcom...@nvidia.com> --- gcc/c-family/c-common.cc | 2 +- gcc/c-family/c.opt | 6 +++ gcc/testsuite/gcc.dg/atomic-op-fp-fenv-flag.c | 44 +++++++++++++++++++ gcc/testsuite/gcc.dg/atomic-op-fp.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf128.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf16.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf16b.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf32.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf32x.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf64.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpf64x.c | 1 + gcc/testsuite/gcc.dg/atomic-op-fpl.c | 1 + 13 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/atomic-op-fp-fenv-flag.c diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 17bdcbfedc3..50c177da4cd 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -8409,7 +8409,7 @@ atomic_alttyped_fetch_using_cas_loop (location_t loc, bool need_fenv = (flag_trapping_math && SCALAR_FLOAT_TYPE_P (nonatomic_lhs_type)); tree hold_call = NULL_TREE, clear_call = NULL_TREE, update_call = NULL_TREE; - if (need_fenv) + if (need_fenv && flag_atomic_fp_fetchop_exceptions) targetm.atomic_assign_expand_fenv (&hold_call, &clear_call, &update_call); if (hold_call) add_stmt (hold_call); diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 47d6f083ffe..6fc66a3bfe7 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1682,6 +1682,12 @@ fasm C ObjC C++ ObjC++ Var(flag_no_asm, 0) Recognize the \"asm\" keyword. +fatomic-fp-fetchop-exceptions +C C++ Var(flag_atomic_fp_fetchop_exceptions) Init(1) +Choose whether __atomic_fetch_add, __atomic_fetch_sub, __atomic_add_fetch, and +__atomic_sub_fetch on floating point types handle floating point exceptions. +This requires linking against libatomic. + ; Define extra predefined macros for use in libgcc. fbuilding-libgcc C ObjC C++ ObjC++ Undocumented Var(flag_building_libgcc) diff --git a/gcc/testsuite/gcc.dg/atomic-op-fp-fenv-flag.c b/gcc/testsuite/gcc.dg/atomic-op-fp-fenv-flag.c new file mode 100644 index 00000000000..1bb0ea4a26b --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic-op-fp-fenv-flag.c @@ -0,0 +1,44 @@ +/* Test that atomic floating point fetch routines do not emit code to handle + floating point exception information when expanding to a CAS loop *if* flag + specifically to avoid this is provided. + Usually one would want to have this behaviour, but if libatomic is not + available then disabling it seems reasonable. Hence providing a flag to + allow disabling. */ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" } */ + +extern volatile float vf, count_f; +extern volatile double vd, count_d; +extern volatile long double vld, count_ld; + +float +test_fetch_add_float (float ret) +{ + ret += __atomic_fetch_add (&vf, count_f, __ATOMIC_SEQ_CST); + ret += __atomic_add_fetch (&vf, count_f, __ATOMIC_SEQ_CST); + ret += __atomic_fetch_sub (&vf, count_f, __ATOMIC_SEQ_CST); + ret += __atomic_sub_fetch (&vf, count_f, __ATOMIC_SEQ_CST); + return ret; +} + +double +test_fetch_add_double (float ret) +{ + ret += __atomic_fetch_add (&vd, count_d, __ATOMIC_SEQ_CST); + ret += __atomic_add_fetch (&vd, count_d, __ATOMIC_SEQ_CST); + ret += __atomic_fetch_sub (&vd, count_d, __ATOMIC_SEQ_CST); + ret += __atomic_sub_fetch (&vd, count_d, __ATOMIC_SEQ_CST); + return ret; +} + +long double +test_fetch_add_long_double (float ret) +{ + ret += __atomic_fetch_add (&vld, count_ld, __ATOMIC_SEQ_CST); + ret += __atomic_add_fetch (&vld, count_ld, __ATOMIC_SEQ_CST); + ret += __atomic_fetch_sub (&vld, count_ld, __ATOMIC_SEQ_CST); + ret += __atomic_sub_fetch (&vld, count_ld, __ATOMIC_SEQ_CST); + return ret; +} + +/* { dg-final { scan-assembler-not "__atomic_feraiseexcept" } } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fp.c b/gcc/testsuite/gcc.dg/atomic-op-fp.c index 1477dbed058..9947bb91f96 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fp.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fp.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_double_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* Test the execution of the __atomic_*OP builtin routines for a double. */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf.c b/gcc/testsuite/gcc.dg/atomic-op-fpf.c index 467fc1348f5..2a88d0a00fd 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* Test the execution of the __atomic_*OP builtin routines for a float. */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf128.c b/gcc/testsuite/gcc.dg/atomic-op-fpf128.c index 86f6ab39565..abf5a1855da 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf128.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf128.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float128_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float128_runtime } */ /* { dg-add-options float128 } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf16.c b/gcc/testsuite/gcc.dg/atomic-op-fpf16.c index 81b54d819dd..375fdce8c9f 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf16.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf16.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float16_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float16_runtime } */ /* { dg-add-options float16 } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf16b.c b/gcc/testsuite/gcc.dg/atomic-op-fpf16b.c index 0ff38878d5a..13dfd9b0ac2 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf16b.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf16b.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_bfloat16_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target bfloat16_runtime } */ /* { dg-add-options bfloat16 } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf32.c b/gcc/testsuite/gcc.dg/atomic-op-fpf32.c index 29e59dc98c7..d9a89467a88 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf32.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf32.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float32_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float32_runtime } */ /* { dg-add-options float32 } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf32x.c b/gcc/testsuite/gcc.dg/atomic-op-fpf32x.c index 32526732846..296e34342b5 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf32x.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf32x.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float32x_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float32x_runtime } */ /* { dg-add-options float32x } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf64.c b/gcc/testsuite/gcc.dg/atomic-op-fpf64.c index be75f7c06b5..a4dbcad89b6 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf64.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf64.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float64_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float64_runtime } */ /* { dg-add-options float64 } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpf64x.c b/gcc/testsuite/gcc.dg/atomic-op-fpf64x.c index 89ee198dfd2..6d059e32bd5 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpf64x.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpf64x.c @@ -4,6 +4,7 @@ /* { dg-additional-options "-std=c23" } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_float64x_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* { dg-require-effective-target float64x_runtime } */ /* { dg-add-options float64x } */ diff --git a/gcc/testsuite/gcc.dg/atomic-op-fpl.c b/gcc/testsuite/gcc.dg/atomic-op-fpl.c index 06429855ae4..d311b76c215 100644 --- a/gcc/testsuite/gcc.dg/atomic-op-fpl.c +++ b/gcc/testsuite/gcc.dg/atomic-op-fpl.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* Can use fallback if libatomic is available, otherwise need hardware support. */ /* { dg-require-effective-target sync_long_double_runtime { target { ! libatomic_available } } } */ +/* { dg-additional-options "-fno-atomic-fp-fetchop-exceptions" { target { ! libatomic_available } } } */ /* Test the execution of the __atomic_*OP builtin routines for a long double. */ -- 2.43.0