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