Created attachment 54194 [details] Example to reproduce incorrect optimizations Before gcc 11.0.0, the attached example compiled under -O3 would result in the whole function getting optimized into a single load instruction when volatile was not used. Adding a volatile access would lead to instructions for fetching the value from the stack getting generated. This appears to be conforming behavior, references ISO/IEC 9899:2018 5.1.2.3, particularly §2, §4 and §6. I believe gcc 10.4 or older behaves correctly. After gcc 11.0.0, the function is optimized regardless of if volatile is used or not. See attached example. With FREE_TO_OPTIMIZE defined, I would expect the compiler to optimize the code under -O3. Without it, I would expect the compiler to generate a read instruction since this is a "side effect". For convenience, here is also an online compiler example for x86-64 Linux https://godbolt.org/z/4qez1P746
Dup of bug 33053. C2x changes things which might be the reason for change in gcc 12. *** This bug has been marked as a duplicate of bug 33053 ***
This is not a dup of 33053 (see PR33053#c5 and PR33053#c6). Reopening, and confirmed. There should be a read from memory: that is a side effect, it has to be executed in the real machine as in the abstract machine.
(In reply to Segher Boessenkool from comment #2) > This is not a dup of 33053 (see PR33053#c5 and PR33053#c6). Reopening, and > confirmed. There should be a read from memory: that is a side effect, it has > to be executed in the real machine as in the abstract machine. This is however very much related to DR476 which is now implemented as per C23. So conformance to DR476 should be on the C23 TODO-list.
But please use PR33053 for that, or open a new PR? Let's keep this one for just this actual bug :-)
This is not x86-specific. Like on powerpc64 we get addi 3,3,3 # 11 [c=4 l=4] *addsi3/1 extsw 3,3 # 17 [c=4 l=4] extendsidi2/1 blr # 25 [c=4 l=4] simple_return Before RTL all is fine still: int foo (int a, int b, int c) { int _1; int _2; ;; basic block 2, loop depth 0 ;; pred: ENTRY _1 = a_3(D) + 1; b = _1; _2 ={v} MEM[(volatile int *)&b]; a_6 = _2 + 2; return a_6; ;; succ: EXIT } But it is expanded to something that is not going through memory: ;; _2 ={v} MEM[(volatile int *)&b]; (insn 10 9 0 (set (reg:SI 118 [ _2 ]) (subreg/s/u:SI (reg/v:DI 121 [ b+-4 ]) 4)) "108298.c":10:9 -1 (nil))
I think it started with r11-165-geb72dc663e9070b2.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69482#c7 addresses the big issue here I think.
Yes, and I think it's a duplicate in the end. *** This bug has been marked as a duplicate of bug 69482 ***
It cannot be a duplicate: this bug was introduced much later than when PR69482 was filed! But glad the same patch seems to have fixed both, sure :-)
On Mon, 9 Jan 2023, segher at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108298 > > --- Comment #9 from Segher Boessenkool <segher at gcc dot gnu.org> --- > It cannot be a duplicate: this bug was introduced much later than when > PR69482 was filed! It wasn't introduced - the present issue was exposed for this case ;-)