https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71793
Bug ID: 71793 Summary: Volatile local variable passed by value is (wrongly?) optimised away, but the containing loop is not Product: gcc Version: 5.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- Here's the original SO thread with more info and/or meandering pondering: http://stackoverflow.com/questions/38235112/why-is-a-volatile-local-variable-optimised-differently-from-a-volatile-argument g++ seems to break in a simple situation involving a function argument passed by value and declared volatile, wherein it acts differently than if such variable is declared in-body. In the former case, it elides volatile reads. #include <cstddef> void f(void *const p, std::size_t n) { unsigned char *y = static_cast<unsigned char *>(p); volatile unsigned char const x = 42; while (n--) { *y++ = x; } } void g(void *const p, std::size_t n, volatile unsigned char const x) { unsigned char *y = static_cast<unsigned char *>(p); while (n--) { *y++ = x; } } void h(void *const p, std::size_t n, volatile unsigned char const &x) { unsigned char *y = static_cast<unsigned char *>(p); while (n--) { *y++ = x; } } int main(int, char **) { int y[1000]; f(&y, sizeof y); volatile unsigned char const x{99}; g(&y, sizeof y, x); h(&y, sizeof y, x); } => ASM main: .LFB3: .cfi_startproc # f() movb $42, -1(%rsp) movl $4000, %eax .p2align 4,,10 .p2align 3 .L21: subq $1, %rax movzbl -1(%rsp), %edx jne .L21 # x = 99 movb $99, -2(%rsp) movzbl -2(%rsp), %eax # g() movl $4000, %eax .p2align 4,,10 .p2align 3 .L22: subq $1, %rax jne .L22 # h() movl $4000, %eax .p2align 4,,10 .p2align 3 .L23: subq $1, %rax movzbl -2(%rsp), %edx jne .L23 Is g() non-conforming here because it elides reads to a volatile variable? That might represent a hardware register whose polling has side-effects, etc. And either way, how is it that the loop body can be totally elided, rightly or not - but the loop itself still executes? (It's like I'm back programming waits on a CPC 464! ;-) thanks