* [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
@ 2022-09-16 20:21 Jonathan Wakely
2022-10-31 15:34 ` Eric Botcazou
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Wakely @ 2022-09-16 20:21 UTC (permalink / raw)
To: libstdc++, gcc-patches
Tested x86_64-linux, pushed to trunk.
The test was only failing for me with -m32 (and not -m64), so I didn't
notice until now. That probably means we should make the test fail more
reliably if the padding isn't being cleared.
-- >8 --
This test was written assuming that std::atomic_ref clears its target's
padding on construction, but that could introduce data races. Change the
test to store a value after construction and check that its padding is
cleared by the store.
libstdc++-v3/ChangeLog:
* testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc:
Store value with non-zero padding bits after construction.
---
.../29_atomics/atomic_ref/compare_exchange_padding.cc | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc
index 1b1a12dddda..e9f8a4bdf2a 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc
@@ -20,14 +20,15 @@ int
main ()
{
S s;
- fill_struct(s);
- s.c = 'a';
- s.s = 42;
-
S ss{ s };
+ fill_struct(ss);
+ ss.c = 'a';
+ ss.s = 42;
+
std::atomic_ref<S> as{ s };
+ as.store(ss);
auto ts = as.load();
- VERIFY( !compare_struct(ss, ts) ); // padding cleared on construction
+ VERIFY( !compare_struct(ss, ts) ); // padding cleared on store
as.exchange(ss);
auto es = as.load();
VERIFY( compare_struct(ts, es) ); // padding cleared on exchange
--
2.37.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-09-16 20:21 [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref Jonathan Wakely
@ 2022-10-31 15:34 ` Eric Botcazou
2022-10-31 15:37 ` Jonathan Wakely
2023-09-01 15:21 ` Jonathan Wakely
0 siblings, 2 replies; 9+ messages in thread
From: Eric Botcazou @ 2022-10-31 15:34 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: libstdc++, gcc-patches
> The test was only failing for me with -m32 (and not -m64), so I didn't
> notice until now. That probably means we should make the test fail more
> reliably if the padding isn't being cleared.
The tests fail randomly for me on SPARC64/Linux:
FAIL: 29_atomics/atomic/compare_exchange_padding.cc execution test
FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
/home/ebotcazou/src/libstdc++-v3/testsuite/29_atomics/atomic_ref/
compare_exchange_padding.cc:34: int main(): Assertion 'compare_struct(ts, es)'
failed.
FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
std::atomic<S> as{ s };
auto ts = as.load();
VERIFY( !compare_struct(s, ts) ); // padding cleared on construction
as.exchange(s);
auto es = as.load();
VERIFY( compare_struct(ts, es) ); // padding cleared on exchange
How is it supposed to pass exactly? AFAICS you have no control on the padding
bits of ts or es and, indeed, at -O2 the loads are scalarized:
__buf$c_81 = MEM[(struct S *)&__buf].c;
__buf$s_59 = MEM[(struct S *)&__buf].s;
__buf ={v} {CLOBBER(eol)};
ts.c = __buf$c_81;
ts.s = __buf$s_59;
[...]
__buf$c_100 = MEM[(struct S *)&__buf].c;
__buf$s_35 = MEM[(struct S *)&__buf].s;
__buf ={v} {CLOBBER(eol)};
es.c = __buf$c_100;
es.s = __buf$s_35;
_66 = MEM <unsigned int> [(char * {ref-all})&ts];
_101 = MEM <unsigned int> [(char * {ref-all})&es];
if (_66 != _101)
goto <bb 5>; [0.04%]
else
goto <bb 6>; [99.96%]
so the result of the 4-byte comparison is random.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-10-31 15:34 ` Eric Botcazou
@ 2022-10-31 15:37 ` Jonathan Wakely
2022-10-31 17:03 ` Eric Botcazou
2023-09-01 15:21 ` Jonathan Wakely
1 sibling, 1 reply; 9+ messages in thread
From: Jonathan Wakely @ 2022-10-31 15:37 UTC (permalink / raw)
To: Eric Botcazou; +Cc: libstdc++, gcc-patches
On Mon, 31 Oct 2022 at 15:34, Eric Botcazou <botcazou@adacore.com> wrote:
>
> > The test was only failing for me with -m32 (and not -m64), so I didn't
> > notice until now. That probably means we should make the test fail more
> > reliably if the padding isn't being cleared.
>
> The tests fail randomly for me on SPARC64/Linux:
>
> FAIL: 29_atomics/atomic/compare_exchange_padding.cc execution test
> FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
>
> /home/ebotcazou/src/libstdc++-v3/testsuite/29_atomics/atomic_ref/
> compare_exchange_padding.cc:34: int main(): Assertion 'compare_struct(ts, es)'
> failed.
> FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
>
> std::atomic<S> as{ s };
> auto ts = as.load();
> VERIFY( !compare_struct(s, ts) ); // padding cleared on construction
> as.exchange(s);
> auto es = as.load();
> VERIFY( compare_struct(ts, es) ); // padding cleared on exchange
>
> How is it supposed to pass exactly? AFAICS you have no control on the padding
> bits of ts or es and, indeed, at -O2 the loads are scalarized:
>
> __buf$c_81 = MEM[(struct S *)&__buf].c;
> __buf$s_59 = MEM[(struct S *)&__buf].s;
> __buf ={v} {CLOBBER(eol)};
> ts.c = __buf$c_81;
> ts.s = __buf$s_59;
> [...]
> __buf$c_100 = MEM[(struct S *)&__buf].c;
> __buf$s_35 = MEM[(struct S *)&__buf].s;
> __buf ={v} {CLOBBER(eol)};
> es.c = __buf$c_100;
> es.s = __buf$s_35;
> _66 = MEM <unsigned int> [(char * {ref-all})&ts];
> _101 = MEM <unsigned int> [(char * {ref-all})&es];
> if (_66 != _101)
> goto <bb 5>; [0.04%]
> else
> goto <bb 6>; [99.96%]
>
> so the result of the 4-byte comparison is random.
I suppose we could use memcmp on the as variable itself, to inspect
the actual stored padding rather than the returned copy of it.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-10-31 15:37 ` Jonathan Wakely
@ 2022-10-31 17:03 ` Eric Botcazou
2022-10-31 17:05 ` Jonathan Wakely
0 siblings, 1 reply; 9+ messages in thread
From: Eric Botcazou @ 2022-10-31 17:03 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: gcc-patches, libstdc++
> I suppose we could use memcmp on the as variable itself, to inspect
> the actual stored padding rather than the returned copy of it.
Yes, that's probably the only safe stance when optimization is enabled.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-10-31 17:03 ` Eric Botcazou
@ 2022-10-31 17:05 ` Jonathan Wakely
2022-11-01 13:53 ` Jonathan Wakely
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Wakely @ 2022-10-31 17:05 UTC (permalink / raw)
To: Eric Botcazou; +Cc: gcc-patches, libstdc++
On Mon, 31 Oct 2022 at 17:03, Eric Botcazou <botcazou@adacore.com> wrote:
>
> > I suppose we could use memcmp on the as variable itself, to inspect
> > the actual stored padding rather than the returned copy of it.
>
> Yes, that's probably the only safe stance when optimization is enabled.
Strictly speaking, it's not safe, because it's undefined to use memcmp
on an object of a non-trivial type. But it should work.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-10-31 17:05 ` Jonathan Wakely
@ 2022-11-01 13:53 ` Jonathan Wakely
2022-11-01 15:26 ` Eric Botcazou
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Wakely @ 2022-11-01 13:53 UTC (permalink / raw)
To: Eric Botcazou; +Cc: gcc-patches, libstdc++
On Mon, 31 Oct 2022 at 17:05, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Mon, 31 Oct 2022 at 17:03, Eric Botcazou <botcazou@adacore.com> wrote:
> >
> > > I suppose we could use memcmp on the as variable itself, to inspect
> > > the actual stored padding rather than the returned copy of it.
> >
> > Yes, that's probably the only safe stance when optimization is enabled.
>
>
> Strictly speaking, it's not safe, because it's undefined to use memcmp
> on an object of a non-trivial type. But it should work.
Do those loads still get scalarized at -O0?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref
2022-10-31 15:34 ` Eric Botcazou
2022-10-31 15:37 ` Jonathan Wakely
@ 2023-09-01 15:21 ` Jonathan Wakely
2023-09-01 18:14 ` Eric Botcazou
1 sibling, 1 reply; 9+ messages in thread
From: Jonathan Wakely @ 2023-09-01 15:21 UTC (permalink / raw)
To: Eric Botcazou; +Cc: libstdc++, gcc-patches
On Mon, 31 Oct 2022 at 15:34, Eric Botcazou wrote:
>
> > The test was only failing for me with -m32 (and not -m64), so I didn't
> > notice until now. That probably means we should make the test fail more
> > reliably if the padding isn't being cleared.
>
> The tests fail randomly for me on SPARC64/Linux:
>
> FAIL: 29_atomics/atomic/compare_exchange_padding.cc execution test
> FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
>
> /home/ebotcazou/src/libstdc++-v3/testsuite/29_atomics/atomic_ref/
> compare_exchange_padding.cc:34: int main(): Assertion 'compare_struct(ts, es)'
> failed.
> FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test
>
> std::atomic<S> as{ s };
> auto ts = as.load();
> VERIFY( !compare_struct(s, ts) ); // padding cleared on construction
> as.exchange(s);
> auto es = as.load();
> VERIFY( compare_struct(ts, es) ); // padding cleared on exchange
>
> How is it supposed to pass exactly? AFAICS you have no control on the padding
> bits of ts or es and, indeed, at -O2 the loads are scalarized:
>
> __buf$c_81 = MEM[(struct S *)&__buf].c;
> __buf$s_59 = MEM[(struct S *)&__buf].s;
> __buf ={v} {CLOBBER(eol)};
> ts.c = __buf$c_81;
> ts.s = __buf$s_59;
> [...]
> __buf$c_100 = MEM[(struct S *)&__buf].c;
> __buf$s_35 = MEM[(struct S *)&__buf].s;
> __buf ={v} {CLOBBER(eol)};
> es.c = __buf$c_100;
> es.s = __buf$s_35;
> _66 = MEM <unsigned int> [(char * {ref-all})&ts];
> _101 = MEM <unsigned int> [(char * {ref-all})&es];
> if (_66 != _101)
> goto <bb 5>; [0.04%]
> else
> goto <bb 6>; [99.96%]
>
> so the result of the 4-byte comparison is random.
This should be fixed now. I rewrote the test to check the padding byte
directly, instead of inspecting a copy of it which might not preserve
the padding bits.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-09-02 8:03 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-16 20:21 [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref Jonathan Wakely
2022-10-31 15:34 ` Eric Botcazou
2022-10-31 15:37 ` Jonathan Wakely
2022-10-31 17:03 ` Eric Botcazou
2022-10-31 17:05 ` Jonathan Wakely
2022-11-01 13:53 ` Jonathan Wakely
2022-11-01 15:26 ` Eric Botcazou
2023-09-01 15:21 ` Jonathan Wakely
2023-09-01 18:14 ` Eric Botcazou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).