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.

Reply via email to