https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552

--- Comment #47 from Linus Torvalds <torva...@linux-foundation.org> ---
(In reply to Richard Biener from comment #45)
> For user code
> 
> volatile long long x;
> void foo () { x++; }
> 
> emitting inc + adc with memory operands is only "incorrect" in re-ordering
> the subword reads with the subword writes, the reads and writes still happen
> architecturally ...

But the thing is, the ordering *is* very much defined for volatile accesses.
"volatile" is not a "the access happens architecturally", it's very much
defined "the access is _visible_ architecturally, and ordering matters".

So with the "volatile long long x" code, I think any language lawyer will say
that generating it as

    add $1,mem
    adc $0,mem+4

is unquestionably a compiler bug.

It may be what the user *wants* (and it's obviously what the gcov code would
like), but it's simply not a valid volatile access to 'x'.

So the gcov code would really want something slightly weaker than 'volatile'.
Something that just does 'guaranteed access' and disallows combining stores or
doing re-loads, without the ordering constraints.

Side note: we would use such a "weaker volatile" in the kernel too. We already
have that concept in the form of READ_ONCE() and WRITE_ONCE(), and it uses
"volatile" internally, and it works fine for us. But if we had another way to
just describe "guaranteed access", that could be useful.

I suspect the memory ordering primitives would be a better model than
'volatile' for this.  What are the rules for doing it as load/store with
'memory_order_relaxed'? That should at least guarantee that the load is never
re-done (getting two different values for anybody who does a load), but maybe
the stores can be combined?

And gcc should already have all that infrastructure in place. Hmm?

Reply via email to