LoongArch: Fix atomic_exchange expanding [PR107713]
We used to expand atomic_exchange_n(ptr, new, mem_order) for subword types
into something like:
{
__typeof__(*ptr) t = atomic_load_n(ptr, mem_order);
atomic_compare_exchange_n(ptr, &t, new, true, mem_order, mem_order);
return t;
}
It's incorrect because another thread may store a different value into *ptr
after atomic_load_n. Then atomic_compare_exchange_n will not store into
*ptr, but atomic_exchange_n should always perform the store.
gcc/ChangeLog:
PR target/107713
* config/loongarch/sync.md
(atomic_cas_value_exchange_7_<mode>): New define_insn.
(atomic_exchange): Use atomic_cas_value_exchange_7_si instead of
atomic_cas_value_cmp_and_7_si.
gcc/testsuite/ChangeLog:
PR target/107713
* gcc.target/loongarch/pr107713-1.c: New test.
* gcc.target/loongarch/pr107713-2.c: New test.