Thread (121 messages) 121 messages, 13 authors, 2021-09-24

Re: [RFC] LKMM: Add volatile_if()

From: Segher Boessenkool <hidden>
Date: 2021-06-06 19:23:34
Also in: linux-toolchains, lkml

On Sun, Jun 06, 2021 at 11:25:46AM -0700, Linus Torvalds wrote:
On Sun, Jun 6, 2021 at 6:03 AM Segher Boessenkool
[off-list ref] wrote:
quoted
On Sat, Jun 05, 2021 at 08:41:00PM -0700, Linus Torvalds wrote:
quoted
I think it's something of a bug when it comes to "asm volatile", but
the documentation isn't exactly super-specific.
Why would that be?  "asm volatile" does not prevent optimisation.
Sure it does.

That's the whole and only *POINT* of the "volatile".

It's the same as a vol;atile memory access. That very much prevents
certain optimizations. You can't just join two volatile reads or
writes, because they have side effects.
You can though.  In exactly this same way:

volatile int x;
void g(int);
void f(int n) { if (n) g(x); else g(x); }

==>

f:
        movl    x(%rip), %edi
        jmp     g

You can do whatever you want with code with side effects.  The only
thing required is that the side effects are executed as often as before
and in the same order.  Merging identical sides of a diamond is just
fine.
And the exact same thing is true of inline asm. Even when they are
*identical*, inline asms have side effects that gcc simply doesn't
understand.
Only volatile asm does (including all asm without outputs).  But that
still does not mean GCC cannot manipulate the asm!
And yes, those side effects can - and do - include "you can't just merge these".
They do not.  That is not what a side effect is.
quoted
It says this code has some unspecified side effect, and that is all!
And that should be sufficient. But gcc then violates it, because gcc
doesn't understand the side effects.

Now, the side effects may be *subtle*, but they are very very real.
Just placement of code wrt a branch will actually affect memory
ordering, as that one example was.
You have a different definition of "side effect" than C does apparently.

5.1.2.3/2:
  Accessing a volatile object, modifying an object, modifying a file, or
  calling a function that does any of those operations are all side
  effects, which are changes in the state of the execution environment.
  Evaluation of an expression in general includes both value
  computations and initiation of side effects.  Value computation for an
  lvalue expression includes determining the identity of the designated
  object.
But that's what we need a compiler barrier for in the first place -
the compiler certainly doesn't understand about this very subtle
memory ordering issue, and we want to make sure that the code sequence
*remains* that "if A then write B".
The compiler doesn't magically understand your intention, no.  Some real
work will need to be done to make this work.


Segher
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help