Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-13 Thread Jonathan Wakely
On Fri, 13 Mar 2026, 02:02 Alexandre Oliva,  wrote:

> On Mar 11, 2026, Jonathan Wakely  wrote:
>
> > On Wed, 11 Mar 2026 at 10:56, Alexandre Oliva  wrote:
> >>
> >> On Mar 11, 2026, Jonathan Wakely  wrote:
> >>
> >> > On Wed, 11 Mar 2026, 05:29 Alexandre Oliva, 
> wrote:
> >> >>
> >> >> compare_exchange_weak is allowed to fail spuriously, and we're
> >> >> actually hitting such spurious failures quite often on ppc-vx7r2,
> >> >> presumably when random interrupts hit between ll and sc.
> >> >>
> >> >> Tolerate one such failure, hopefully that will suffice.
> >>
> >> > This is a bit of a problem, because we can't tell if the padding was
> >> > cleared or not. If it was not clear, the first compare_exchange_weak
> would
> >> > clear it, and the refund would succeed. But we want the test to fail
> in
> >> > that case.
> >>
> >> Erhm...  My understanding is that, when it returns false, no memory is
> >> changed, so the second attempt would start from exactly the same state
> >> as the first.
>
> > "Remarks: A weak compare-and-exchange operation may fail spuriously.
> > That is, even when the contents of memory referred to by expected and
> > ptr are equal, it may return false and store back to expected the same
> > memory contents that were originally there."
>
> > So `expected` is updated on a spurious failure, even if that doesn't
> > change any bits.
>
> Yeah, but if it stores back what was there to begin with, how can that
> be a problem?  Is there any reason to expect that "store back [of] the
> same memory contents" to not actually mean that, and end up messing with
> padding bits?
>

Yes, i think the wording is wrong and should have been changed by the paper
that required us to ignore padding bits in the comparison. I've asked for
confirmation from the committee and will open a library issue if needed.


> Anyhow, your near-rewrite of the test is also passing consistently.  I
> suspect it's not just because we're no longer likely to get the timing
> just right for an interrupt to cause a spurious failure.  I needed a few
> tens of retries to hit the problem, now I'm up to 500 without any hits.
>

Thanks, I'll push it then.



> --
> Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
> Free Software Activist FSFLA co-founder GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity.
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive!
>


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-12 Thread Alexandre Oliva
On Mar 11, 2026, Jonathan Wakely  wrote:

> On Wed, 11 Mar 2026 at 10:56, Alexandre Oliva  wrote:
>> 
>> On Mar 11, 2026, Jonathan Wakely  wrote:
>> 
>> > On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
>> >>
>> >> compare_exchange_weak is allowed to fail spuriously, and we're
>> >> actually hitting such spurious failures quite often on ppc-vx7r2,
>> >> presumably when random interrupts hit between ll and sc.
>> >>
>> >> Tolerate one such failure, hopefully that will suffice.
>> 
>> > This is a bit of a problem, because we can't tell if the padding was
>> > cleared or not. If it was not clear, the first compare_exchange_weak would
>> > clear it, and the refund would succeed. But we want the test to fail in
>> > that case.
>> 
>> Erhm...  My understanding is that, when it returns false, no memory is
>> changed, so the second attempt would start from exactly the same state
>> as the first.

> "Remarks: A weak compare-and-exchange operation may fail spuriously.
> That is, even when the contents of memory referred to by expected and
> ptr are equal, it may return false and store back to expected the same
> memory contents that were originally there."

> So `expected` is updated on a spurious failure, even if that doesn't
> change any bits.

Yeah, but if it stores back what was there to begin with, how can that
be a problem?  Is there any reason to expect that "store back [of] the
same memory contents" to not actually mean that, and end up messing with
padding bits?

Anyhow, your near-rewrite of the test is also passing consistently.  I
suspect it's not just because we're no longer likely to get the timing
just right for an interrupt to cause a spurious failure.  I needed a few
tens of retries to hit the problem, now I'm up to 500 without any hits.

-- 
Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Jonathan Wakely
On Wed, 11 Mar 2026 at 11:49, Jonathan Wakely  wrote:
>
> On Wed, 11 Mar 2026 at 11:41, Jonathan Wakely  wrote:
> >
> > On Wed, 11 Mar 2026 at 10:56, Alexandre Oliva  wrote:
> > >
> > > On Mar 11, 2026, Jonathan Wakely  wrote:
> > >
> > > > On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
> > > >>
> > > >> compare_exchange_weak is allowed to fail spuriously, and we're
> > > >> actually hitting such spurious failures quite often on ppc-vx7r2,
> > > >> presumably when random interrupts hit between ll and sc.
> > > >>
> > > >> Tolerate one such failure, hopefully that will suffice.
> > >
> > > > This is a bit of a problem, because we can't tell if the padding was
> > > > cleared or not. If it was not clear, the first compare_exchange_weak 
> > > > would
> > > > clear it, and the refund would succeed. But we want the test to fail in
> > > > that case.
> > >
> > > Erhm...  My understanding is that, when it returns false, no memory is
> > > changed, so the second attempt would start from exactly the same state
> > > as the first.
> >
> > "Remarks: A weak compare-and-exchange operation may fail spuriously.
> > That is, even when the contents of memory referred to by expected and
> > ptr are equal, it may return false and store back to expected the same
> > memory contents that were originally there."
> >
> > So `expected` is updated on a spurious failure, even if that doesn't
> > change any bits.
>
> I might have got a bit carried away, but I rewrote the whole test. How
> does this look? This should solve the problem with spurious weak
> failures, and no longer require -fno-tree-sra to retrieve the padding
> bits from the value in the atomic.

Oh and also changed the struct to ensure there actually *is* some
padding, otherwise on byte-aligned targets like cris-elf it's a 3-byte
struct with no padding. I'll add that to the commit message.


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Jonathan Wakely
On Wed, 11 Mar 2026 at 11:41, Jonathan Wakely  wrote:
>
> On Wed, 11 Mar 2026 at 10:56, Alexandre Oliva  wrote:
> >
> > On Mar 11, 2026, Jonathan Wakely  wrote:
> >
> > > On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
> > >>
> > >> compare_exchange_weak is allowed to fail spuriously, and we're
> > >> actually hitting such spurious failures quite often on ppc-vx7r2,
> > >> presumably when random interrupts hit between ll and sc.
> > >>
> > >> Tolerate one such failure, hopefully that will suffice.
> >
> > > This is a bit of a problem, because we can't tell if the padding was
> > > cleared or not. If it was not clear, the first compare_exchange_weak would
> > > clear it, and the refund would succeed. But we want the test to fail in
> > > that case.
> >
> > Erhm...  My understanding is that, when it returns false, no memory is
> > changed, so the second attempt would start from exactly the same state
> > as the first.
>
> "Remarks: A weak compare-and-exchange operation may fail spuriously.
> That is, even when the contents of memory referred to by expected and
> ptr are equal, it may return false and store back to expected the same
> memory contents that were originally there."
>
> So `expected` is updated on a spurious failure, even if that doesn't
> change any bits.

I might have got a bit carried away, but I rewrote the whole test. How
does this look? This should solve the problem with spurious weak
failures, and no longer require -fno-tree-sra to retrieve the padding
bits from the value in the atomic.
commit a50d1f44cbb9e14228f6287116e6c0e448e8f952
Author: Jonathan Wakely 
AuthorDate: Wed Mar 11 11:41:56 2026
Commit: Jonathan Wakely 
CommitDate: Wed Mar 11 11:48:14 2026

libstdc++: Rewrite test for compare_exchange padding

Add a new helper function to verify that the padding bits in a struct S
and in the std::atomic are zero, without needing to disable SRA. Then
rewrite the test in terms of that helper, so we check directly that the
atomic object has no padding bits, instead of loading a value (with
-fno-tree-sra to hopefully preserve padding) and then just using memcmp
on that value.

Also add a loop around the weak compare-exchange, to tolerate spurious
failures as described in
https://gcc.gnu.org/pipermail/gcc-patches/2026-March/710289.html

libstdc++-v3/ChangeLog:

* testsuite/29_atomics/atomic/compare_exchange_padding.cc:
Rewrite to be robust against spurious failures of weak compare
exchange, and to check padding bits more directly.

diff --git 
a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
index d9c7b90c1a5c..41c77da823a4 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
@@ -1,22 +1,52 @@
 // { dg-do run { target c++11 } }
 // { dg-require-atomic-cmpxchg-word "" }
 // { dg-add-options libatomic }
-// { dg-additional-options "-fno-tree-sra" }
 
 #include 
 #include 
+#include 
 
 #include 
 
-struct S { char c; short s; };
+struct S
+{
+char c;
+alignas(2) std::int16_t s;
+
+bool operator==(const S& rhs) const { return c == rhs.c && s == rhs.s; }
+};
 
 void __attribute__((noinline,noipa))
 fill_struct(S& s)
 { std::memset(&s, 0xff, sizeof(S)); }
 
+bool __attribute__((noinline,noipa))
+padding_is_zero(const S& s)
+{
+  unsigned char bytes[sizeof(S)];
+  std::memcpy(bytes, &s, sizeof(S));
+  return bytes[1] == 0;
+}
+
 bool
-compare_struct(const S& a, const S& b)
-{ return std::memcmp(&a, &b, sizeof(S)) == 0; }
+padding_is_zero(std::atomic& a)
+{
+  const S dummy{};
+
+  // a.load() does not necessarily preserve padding bits, because the
+  // temporary returned from a.load() might get SRA'd so that the two
+  // data members are copied in separate registers and padding bits are
+  // not copied.
+  S s = a.load();
+
+  // So instead we use compare-exchange with an incorrect 'expected' value,
+  s.c = ~s.c;
+  // so that the compare will fail and return the value (including padding):
+  a.compare_exchange_weak(s, dummy);
+
+  // Now we can inspect the padding bits to check they are zero:
+  return padding_is_zero(s);
+}
 
 int
 main ()
@@ -27,18 +57,35 @@ main ()
   s.s = 42;
 
   std::atomic as{ s };
-  auto ts = as.load(); // SRA might prevent copying of padding bits here.
-  VERIFY( !compare_struct(s, ts) ); // padding cleared on construction
+  VERIFY( as.load() == s );  // members are set correctly
+  VERIFY( padding_is_zero(as) ); // but padding was cleared on construction
+
+  ++s.s;
   as.exchange(s);
-  auto es = as.load(); // SRA might prevent copying of padding bits here.
-  VERIFY( compare_struct(ts, es) ); // padding cleared on exchange
+  VERIFY( as.load() == s );  // members are set correctly
+  VERIFY( padding_is_zero(as) ); // but padding was cleared on c

Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Jonathan Wakely
On Wed, 11 Mar 2026 at 10:56, Alexandre Oliva  wrote:
>
> On Mar 11, 2026, Jonathan Wakely  wrote:
>
> > On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
> >>
> >> compare_exchange_weak is allowed to fail spuriously, and we're
> >> actually hitting such spurious failures quite often on ppc-vx7r2,
> >> presumably when random interrupts hit between ll and sc.
> >>
> >> Tolerate one such failure, hopefully that will suffice.
>
> > This is a bit of a problem, because we can't tell if the padding was
> > cleared or not. If it was not clear, the first compare_exchange_weak would
> > clear it, and the refund would succeed. But we want the test to fail in
> > that case.
>
> Erhm...  My understanding is that, when it returns false, no memory is
> changed, so the second attempt would start from exactly the same state
> as the first.

"Remarks: A weak compare-and-exchange operation may fail spuriously.
That is, even when the contents of memory referred to by expected and
ptr are equal, it may return false and store back to expected the same
memory contents that were originally there."

So `expected` is updated on a spurious failure, even if that doesn't
change any bits.


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Alexandre Oliva
On Mar 11, 2026, Jonathan Wakely  wrote:

> On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
>> 
>> compare_exchange_weak is allowed to fail spuriously, and we're
>> actually hitting such spurious failures quite often on ppc-vx7r2,
>> presumably when random interrupts hit between ll and sc.
>> 
>> Tolerate one such failure, hopefully that will suffice.

> This is a bit of a problem, because we can't tell if the padding was
> cleared or not. If it was not clear, the first compare_exchange_weak would
> clear it, and the refund would succeed. But we want the test to fail in
> that case.

Erhm...  My understanding is that, when it returns false, no memory is
changed, so the second attempt would start from exactly the same state
as the first.

-- 
Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Jonathan Wakely
On Wed, 11 Mar 2026, 08:58 Jonathan Wakely,  wrote:

>
>
> On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:
>
>>
>> compare_exchange_weak is allowed to fail spuriously, and we're
>> actually hitting such spurious failures quite often on ppc-vx7r2,
>> presumably when random interrupts hit between ll and sc.
>>
>> Tolerate one such failure, hopefully that will suffice.
>>
>
> This is a bit of a problem, because we can't tell if the padding was
> cleared or not. If it was not clear, the first compare_exchange_weak would
> clear it, and the refund would succeed. But we want the test to fail in
> that case.
>
> I'll have a think about this when I'm properly awake...
>


We could put a loop around it and redo both the fill struct call and the
weak cmpxchg until it succeeds.



>
>
>> Regstrapped on x86_64-linux-gnu, also tested with gcc-15 for ppc-vx7r2.
>> Ok to install?
>>
>>
>> for  libstdc++-v3/ChangeLog
>>
>> * testsuite/29_atomics/atomic/compare_exchange_padding.cc:
>> Tolerate one compare_exchange_weak spurious failure.
>> ---
>>  .../29_atomics/atomic/compare_exchange_padding.cc  |4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git
>> a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
>> b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
>> index d9c7b90c1a5c1..3fc2f6b4f8031 100644
>> --- a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
>> +++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
>> @@ -37,8 +37,8 @@ main ()
>>fill_struct(n);
>>n.c = 'b';
>>n.s = 71;
>> -  // padding cleared on compexchg
>> -  VERIFY( as.compare_exchange_weak(s, n) );
>> +  // padding cleared on compexchg.  tolerate one spurious _weak failure.
>> +  VERIFY( as.compare_exchange_weak(s, n) || as.compare_exchange_weak(s,
>> n) );
>>VERIFY( as.compare_exchange_strong(n, s) );
>>return 0;
>>  }
>>
>> --
>> Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
>> Free Software Activist FSFLA co-founder GNU Toolchain Engineer
>> More tolerance and less prejudice are key for inclusion and diversity.
>> Excluding neuro-others for not behaving ""normal"" is *not* inclusive!
>>
>


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-11 Thread Jonathan Wakely
On Wed, 11 Mar 2026, 05:29 Alexandre Oliva,  wrote:

>
> compare_exchange_weak is allowed to fail spuriously, and we're
> actually hitting such spurious failures quite often on ppc-vx7r2,
> presumably when random interrupts hit between ll and sc.
>
> Tolerate one such failure, hopefully that will suffice.
>

This is a bit of a problem, because we can't tell if the padding was
cleared or not. If it was not clear, the first compare_exchange_weak would
clear it, and the refund would succeed. But we want the test to fail in
that case.

I'll have a think about this when I'm properly awake...



> Regstrapped on x86_64-linux-gnu, also tested with gcc-15 for ppc-vx7r2.
> Ok to install?
>
>
> for  libstdc++-v3/ChangeLog
>
> * testsuite/29_atomics/atomic/compare_exchange_padding.cc:
> Tolerate one compare_exchange_weak spurious failure.
> ---
>  .../29_atomics/atomic/compare_exchange_padding.cc  |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git
> a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> index d9c7b90c1a5c1..3fc2f6b4f8031 100644
> --- a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> +++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> @@ -37,8 +37,8 @@ main ()
>fill_struct(n);
>n.c = 'b';
>n.s = 71;
> -  // padding cleared on compexchg
> -  VERIFY( as.compare_exchange_weak(s, n) );
> +  // padding cleared on compexchg.  tolerate one spurious _weak failure.
> +  VERIFY( as.compare_exchange_weak(s, n) || as.compare_exchange_weak(s,
> n) );
>VERIFY( as.compare_exchange_strong(n, s) );
>return 0;
>  }
>
> --
> Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
> Free Software Activist FSFLA co-founder GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity.
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive!
>


Re: testsuite: tolerate compare_exchange_weak spurious failure

2026-03-10 Thread Andrew Pinski
On Tue, Mar 10, 2026 at 10:30 PM Alexandre Oliva  wrote:
>
>
> compare_exchange_weak is allowed to fail spuriously, and we're
> actually hitting such spurious failures quite often on ppc-vx7r2,
> presumably when random interrupts hit between ll and sc.
>
> Tolerate one such failure, hopefully that will suffice.
>
> Regstrapped on x86_64-linux-gnu, also tested with gcc-15 for ppc-vx7r2.
> Ok to install?

LGTM.
I am also worried that 2 weak compare exchanges would not be enough
and still cause a spurious failure
but at least it is easier to understand based on the comment there.

Thanks,
Andrew


>
>
> for  libstdc++-v3/ChangeLog
>
> * testsuite/29_atomics/atomic/compare_exchange_padding.cc:
> Tolerate one compare_exchange_weak spurious failure.
> ---
>  .../29_atomics/atomic/compare_exchange_padding.cc  |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git 
> a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc 
> b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> index d9c7b90c1a5c1..3fc2f6b4f8031 100644
> --- a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> +++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> @@ -37,8 +37,8 @@ main ()
>fill_struct(n);
>n.c = 'b';
>n.s = 71;
> -  // padding cleared on compexchg
> -  VERIFY( as.compare_exchange_weak(s, n) );
> +  // padding cleared on compexchg.  tolerate one spurious _weak failure.
> +  VERIFY( as.compare_exchange_weak(s, n) || as.compare_exchange_weak(s, n) );
>VERIFY( as.compare_exchange_strong(n, s) );
>return 0;
>  }
>
> --
> Alexandre Oliva, happy hackerhttps://blog.lx.oliva.nom.br/
> Free Software Activist FSFLA co-founder GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity.
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive!