diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2023-09-23 05:06:52 +0200 |
---|---|---|
committer | Hans-Peter Nilsson <hp@bitrange.com> | 2023-09-26 23:39:46 +0200 |
commit | 8e6757b30d0f3f13d47d0f842801a751ba6293c2 (patch) | |
tree | a56aa786ab9b2835e64c7ba278331aad0f4d424a /gcc/builtins.cc | |
parent | dd0c42cd37dab62f9f61ac834333ec899305dee4 (diff) | |
download | gcc-8e6757b30d0f3f13d47d0f842801a751ba6293c2.zip gcc-8e6757b30d0f3f13d47d0f842801a751ba6293c2.tar.gz gcc-8e6757b30d0f3f13d47d0f842801a751ba6293c2.tar.bz2 |
__atomic_test_and_set: Fall back to library, not non-atomic code
Make __atomic_test_and_set consistent with other __atomic_ and __sync_
builtins: call a matching library function instead of emitting
non-atomic code when the target has no direct insn support.
There's special-case code handling targetm.atomic_test_and_set_trueval
!= 1 trying a modified maybe_emit_sync_lock_test_and_set. Previously,
if that worked but its matching emit_store_flag_force returned NULL,
we'd segfault later on. Now that the caller handles NULL, gcc_assert
here instead.
While the referenced PR:s are ARM-specific, the issue is general.
PR target/107567
PR target/109166
* builtins.cc (expand_builtin) <case BUILT_IN_ATOMIC_TEST_AND_SET>:
Handle failure from expand_builtin_atomic_test_and_set.
* optabs.cc (expand_atomic_test_and_set): When all attempts fail to
generate atomic code through target support, return NULL
instead of emitting non-atomic code. Also, for code handling
targetm.atomic_test_and_set_trueval != 1, gcc_assert result
from calling emit_store_flag_force instead of returning NULL.
Diffstat (limited to 'gcc/builtins.cc')
-rw-r--r-- | gcc/builtins.cc | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 6e4274b..40dfd36 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -8387,7 +8387,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, break; case BUILT_IN_ATOMIC_TEST_AND_SET: - return expand_builtin_atomic_test_and_set (exp, target); + target = expand_builtin_atomic_test_and_set (exp, target); + if (target) + return target; + break; case BUILT_IN_ATOMIC_CLEAR: return expand_builtin_atomic_clear (exp); |