From: Matthew Malcomson <[email protected]>
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 <[email protected]>
---
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