https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102306
Bug ID: 102306 Summary: Volatile pointer dereferenced twice Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cederman at gaisler dot com CC: ebotcazou at libertysurf dot fr, segher at kernel dot crashing.org Target Milestone: --- Created attachment 51448 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51448&action=edit Test case The following code (full case in attachment) generates two loads from the volatile "a" pointer on SPARC: C char b = *(volatile unsigned char *)a; if (!b) return; Asm sethi %hi(a), %g1 ld [%g1+%lo(a)], %g1 ldub [%g1], %g2 ldub [%g1], %g1 cmp %g1, 0 The code is intended to read a memory mapped register that will change after a read, so two reads will give the wrong value to the comparison. A bisect showed that this started to happen after "c4c5ad1d6d1e1e1fe7a: combine: Allow combining two insns to two insns". The compiler (on commit fc4a29c0781186269dc, latest master at the time) was configured with: configure --target=sparc-gaisler-elf --enable-languages=c --disable-nls --disable-libmudflap --disable-libssp --enable-version-specific-runtime-libs --disable-fixed-point --disable-decimal-float --disable-shared and the test was compiled with: sparc-gaisler-elf -mcpu=v8 -O2 I do not know if this is a generic problem or a SPARC specific one.