4

The following msvc command line option suggests that memory fences are introduced using the option /volatile:ms (default) but not when using /volatile:iso. I have not been able to come up with any example code that does this.

For example one of my random attempts

https://godbolt.org/z/qrz18j3h9

volatile int A, B;


void foo()
{
    A = B+1;
    B = A+1;
}

generates the following asm

int volatile A DD        01H DUP (?)                   ; A
int volatile B DD        01H DUP (?)                   ; B
voltbl  SEGMENT
_volmd  DB  00H
        DB      08H
        DB      0eH
        DB      016H
voltbl  ENDS

void foo(void) PROC                                        ; foo, COMDAT
        mov     eax, DWORD PTR int volatile B                    ; B
        inc     eax
        mov     DWORD PTR int volatile A, eax                    ; A
        mov     eax, DWORD PTR int volatile A                    ; A
        inc     eax
        mov     DWORD PTR int volatile B, eax                    ; B
        ret     0
void foo(void) ENDP  

irrespective of whether I use option /volatile:ms or /volatile:iso with Visual Studio 2019.

Can somebody provide an example where the above two options do make a difference to the output assembly code?

bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217
  • It looks like this might only apply to ARM. If I use your link and use the ARM version of MSVC, then changing `/volatile:ms` to `/volatile:iso` does change the assembly. – NathanOliver Aug 11 '21 at 13:17
  • `volatile` is never going to compile to memory barrier instructions on x86 (32 or 64-bit); x86's strong memory model doesn't need them for the release/acquire semantics that `/volatile:ms` guarantees. On x86 it just needs to limit compile-time reordering. (I don't think it's meaningless on x86, @NathanOliver) Presumably MSVC's optimizer used to happen to do that, and people took advantage, and now it's enshrined as officially supported via this option even if the current optimizer can for example do dead-store elimination or other reordering across `volatile` if you don't stop it. – Peter Cordes Aug 11 '21 at 13:17
  • That's a good question! I wish it had been titled "What are cases where ... observe difference...". We have too many "please provide..." questions :-) (most of which are not as good, though) – Jeffrey Aug 11 '21 at 13:30
  • @Jeffrey I guess there is no way to change the title! – bradgonesurfing Aug 11 '21 at 13:40
  • @PeterCordes Do you have some references that describe x86 *strong memory model*? – bradgonesurfing Aug 11 '21 at 13:45
  • @bradgonesurfing lol. I would suggest an edit, but I have *too much* reputation, it will only let me it edit directly. I don't like editing question when people clearly are on top of their game. When I asked on meta, people told me: in those cases you should use the comments to suggest OP edits it ;-). That's why I didn't edit directly – Jeffrey Aug 11 '21 at 13:47
  • @Jeffrey Sorry. I'm multitasking today and expected the title to become editable when I pressed edit. However there is an edit box for it lower down. Missed it. – bradgonesurfing Aug 11 '21 at 13:58
  • https://godbolt.org/z/n9n4o5s6q – Marek R Aug 11 '21 at 14:00
  • 1
    @bradgonesurfing: [C++ How is release-and-acquire achieved on x86 only using MOV?](https://stackoverflow.com/q/60314179) explains acquire / release, and has some good links, including Jeff Preshing's great articles. Also to a rigorous *formal* description of the x86 memory model (which is pretty much incomprehensible for mere mortals), in case you want that. :P – Peter Cordes Aug 11 '21 at 14:11
  • @MarekR: That's only highlighting a difference in the `voltbl SEGMENT` data, whatever that is / whatever MSVC uses it for. No difference in the asm instructions, so it doesn't seem interesting. – Peter Cordes Aug 11 '21 at 14:18
  • I played around some myself on Godbolt, but even with `/volatile:iso` MSVC ignores a bunch of legal optimizations. https://godbolt.org/z/eha85s3bT. So maybe there is only an effect on non-x86 ISAs after all, like @NathanOliver suggested. My first comment was based on the assumption that `/volatile:iso` would let it optimize similar to how GCC does, but maybe that never happens and it is just about adding memory barrier instructions. – Peter Cordes Aug 11 '21 at 14:19
  • 1
    @MarekR, one is x64 and the other is x86, if this difference is eliminated, the code becomes exactly the same – Alex Guteniev Aug 11 '21 at 14:20
  • @PeterCordes I've noticed, I just provided better link which uses diff functionality on godbolt what is more handy. Maybe I should edit link in a question instead posting it as a comment?? – Marek R Aug 11 '21 at 14:21
  • @MarekR: It's usually more than fine to just use two panes side by side. If there's a difference here, it'll be noticeable with that. The diff pane is just kind of more clutter when playing around with the source to maybe find something that MSVC will optimize. (Usually you'll only be looking at the volatile:iso pane and seeing if MSVC did any optimization of a load or store across a volatile access, instead of treating it like a compiler memory barrier which seems to be what's happening in cases I've tried.) – Peter Cordes Aug 11 '21 at 14:36

0 Answers0