aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.cc
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2023-09-23 05:06:52 +0200
committerHans-Peter Nilsson <hp@bitrange.com>2023-09-26 23:39:46 +0200
commit8e6757b30d0f3f13d47d0f842801a751ba6293c2 (patch)
treea56aa786ab9b2835e64c7ba278331aad0f4d424a /gcc/builtins.cc
parentdd0c42cd37dab62f9f61ac834333ec899305dee4 (diff)
downloadgcc-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.cc5
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);