[Bug target/107567] __atomic_test_and_set generates non-atomic code on armv6-m

2023-09-26 Thread chris.n.copeland at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107567

--- Comment #3 from Chris Copeland  ---
Fantastic! Thank you for looking into it.

[Bug c/107567] New: __atomic_test_and_set generates non-atomic code on armv6-m

2022-11-07 Thread chris.n.copeland at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107567

Bug ID: 107567
   Summary: __atomic_test_and_set generates non-atomic code on
armv6-m
   Product: gcc
   Version: 11.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: chris.n.copeland at gmail dot com
  Target Milestone: ---

Created attachment 53847
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53847=edit
test and set via __atomic_test_and_set and via _atomic_exchange

armv6-m doesn't provide the the load/store exclusive instructions, and most of
the atomic builtins are compiled to calls to functions that don't exist for
that platform unless provided separately (e.g., using interrupt disable and
memory barriers). __atomic_test_and_set however generates a non-atomic sequence
no function calls or locking, etc. What I would expect is that the
__atomic_test_and_set code generates a similar call as the other builtins do.

Minimal example showing the problem:

_Bool test_and_set(_Bool *flag)
{
return __atomic_test_and_set(flag, __ATOMIC_SEQ_CST);
}

compiled with:
arm-none-eabi-gcc -S -Os -march=armv6-m -o test_and_set.S test_and_set.c

There's no preprocessor use in the example.

assembly output is this (directives and comments removed):

test_and_set:
movsr2, #1
ldrbr3, [r0]
strbr2, [r0]
uxtbr0, r3
bx  lr

Compare this with the equivalent operation using atomic exchange, compiled with
the same options:

_Bool test_and_set_exchange(_Bool *flag)
{
_Bool val = 1;
_Bool ret;
__atomic_exchange(flag, , , __ATOMIC_SEQ_CST);
return ret;
}

test_and_set_exchange:
push{r4, lr}
movsr2, #5
movsr1, #1
bl  __atomic_exchange_1
pop {r4, pc}

$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (Arm GNU Toolchain 11.3.Rel1) 11.3.1 20220712
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Here is a godbolt link as well showing that `clang` generates a call to
__atomic_exchange_1 in both cases: https://godbolt.org/z/an6TWqoq5