https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71372

            Bug ID: 71372
           Summary: GCC Optimization "tree-dse" does not respect access to
                    volatile* upon explicit cast.
           Product: gcc
           Version: 6.1.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hdu...@tangerine-soft.de
  Target Milestone: ---

GCC 6.1. seems to have an issue by using access to storage which __exlicitly__
is casted to an "volatile*" in conjunction with optimization flag –ftree-dse

This issue has been observed with a crosscompiler which is based on the GCC
6.1.0, host: cygwin (32 bit), 
for target architecture m68k.


In order to illustrate the issue see 3 Cases (see details below):

1) Code snippet __without__ any explicit type cast to (volatile*). 
   GCC 6.1.0 with this code produces correct code.

2) Code Snippet __with__ explicit typecast to “volatile short*”. 
   In conjunction with optimization level -O1/2/3/s this creates wrong code.

   The code is wrong that despite the memory location is marked to be volatile*
the 
   very first access does not happen and seems to be optimized away!

3) Code Snippet __with__ explicit typecast to “volatile short*”.

   In conjunction with optimization level -O1/2/3/s but __excluding__
optimization “tree-dse”. 
   Now GCC 6.1.0 generates right code. 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Example 1) ) Code snippet __without__ any explicit type cast. 
+ GCC 6.1.0 with this code produces correct code.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// testmodule.cpp

void fpoke (void *addr, short val, int times, int wait)
{
  volatile unsigned short* FLASH = (volatile unsigned short*)0x20000000;

  *(FLASH + 0) = 0xAA;
  *(FLASH + 1) = 0x55;
  *(FLASH + 0) = 0xA0;
}


hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/bin/m68k-elf-g++ -O3 testmodule.cpp -c

hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/m68k-elf/bin/objdump.exe -d ./testmodule.o

./testmodule.o:     file format elf32-m68k

Disassembly of section .text:

00000000 <_Z5fpokePvsii>:
   0:   4e56 0000       linkw %fp,#0
   4:   207c 2000 0000  moveal #536870912,%a0
   a:   4e5e            unlk %fp
   c:   7055            moveq #85,%d0
   e:   30bc 00aa       movew #170,%a0@
  12:   33c0 2000 0002  movew %d0,20000002 <_Z5fpokePvsii+0x20000002>
  18:   30bc 00a0       movew #160,%a0@
  1c:   4e75            rts

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Example 2) Code Snippet __with__ explicit typecast to “volatile short*”. 
+ In conjunction with optimization level -O1/2/3/s this creates __wrong code__.
+
+ The __very first__ access to the storage address $20000000 is missing!
+ (see remarks in the code snippet, below)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// testmodule.cpp

void fpoke (void *addr, short val, int times, int wait)
{
  volatile unsigned short* FLASH = (volatile unsigned short*)0x20000000;

  *(volatile unsigned short*)(FLASH + 0) = 0xAA; // this line will be optimized
away! Why?
  *(volatile unsigned short*)(FLASH + 1) = 0x55;
  *(volatile unsigned short*)(FLASH + 0) = 0xA0;
}

hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/bin/m68k-elf-g++ -O3 testmodule.cpp -c

hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/m68k-elf/bin/objdump.exe -d ./testmodule.o

./testmodule.o:     file format elf32-m68k

Disassembly of section .text:

00000000 <_Z5fpokePvsii>:
   0:   4e56 0000       linkw %fp,#0
   4:   7055            moveq #85,%d0
   6:   4e5e            unlk %fp
   8:   33c0 2000 0002  movew %d0,20000002 <_Z5fpokePvsii+0x20000002>
   e:   303c 00a0       movew #160,%d0
  12:   33c0 2000 0000  movew %d0,20000000 <_Z5fpokePvsii+0x20000000>
  18:   4e75            rts

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Example 3) Code Snippet __with__ explicit typecast to “volatile short*”. 
+ In conjunction with optimization level -O1/2/3/s but __excluding__
optimization “tree-dse”. 
+ Now GCC 6.1.0 creates right code. 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// testmodule.cpp (The same as on Issue 2)

void fpoke (void *addr, short val, int times, int wait)
{
  volatile unsigned short* FLASH = (volatile unsigned short*)0x20000000;

  *(volatile unsigned short*)(FLASH + 0) = 0xAA;
  *(volatile unsigned short*)(FLASH + 1) = 0x55;
  *(volatile unsigned short*)(FLASH + 0) = 0xA0;
}

hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/bin/m68k-elf-g++ -O3 -fno-tree-dse testmodule.cpp -c

hdusel@Merlin /cygdrive/w/tmp
$ /opt/gcc-6.1.0-myos/m68k-elf/bin/objdump.exe -d ./testmodule.o

./testmodule.o:     file format elf32-m68k


Disassembly of section .text:

00000000 <_Z5fpokePvsii>:
   0:   4e56 0000       linkw %fp,#0
   4:   207c 2000 0000  moveal #536870912,%a0
   a:   4e5e            unlk %fp
   c:   7055            moveq #85,%d0
   e:   30bc 00aa       movew #170,%a0@
  12:   33c0 2000 0002  movew %d0,20000002 <_Z5fpokePvsii+0x20000002>
  18:   30bc 00a0       movew #160,%a0@
  1c:   4e75            rts

Reply via email to