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.