https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88562
Bug ID: 88562 Summary: Incorrect pointer incrementing on ST-SH4 Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: zavadovsky.yan at gmail dot com Target Milestone: --- Created attachment 45268 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45268&action=edit code to trigger the bug Hello. I have got some piece of source code which incorrectly works after optimized compilation for ST-SH4 architecture. But it works good with some other CPUs - checked on x86-64, armv8 and mips. And works good with some optimizations off. Details: Here is the minimal piece of code to trigger this bug: <code begin> unsigned Read32(const unsigned char* ptr); const unsigned char* ReadQm(const unsigned char* ptr, const unsigned char* end) { const unsigned char* ret = 0; while(ptr < end) { unsigned char tag = *ptr++; unsigned len = Read32(ptr); ptr += 4; if (!tag || !len) break; if (ptr + len > end) break; ret = ptr; ptr += len; } return ret; } <code end> The error is in 'ptr += 4;' statement. It is compiled like 'ptr += 5;'. This leads to non-working assembler opcodes. But some changes to this code will prevent this error. I've checked these variants: - replace 'return ret;' with 'return ptr;' - add line 'AnyFuncWhichTakesPointerAsArgument(ptr);' before 'return ret;' - compile without some optimizations How to compile and get the bug: 'sh4-unknown-linux-gnu-g++ -Os -S -c ReadQm.cpp' Assembler output with some comments: <asm begin> // r4 == ptr cmp/hs r11,r4 bt/s .L8 mov r10,r0 mov r4,r8 // r8 = ptr mov.b @r8+,r9 // r9 = tag, r8 = (ptr + 1) mov r8,r4 jsr @r12 // call Read32(ptr + 1) add #5,r8 // r8 = ((ptr + 1) + 5) HERE IS ERROR, must be '+=4' <asm end> How to compile and DON'T get the bug: 'sh4-unknown-linux-gnu-g++ -Os -fno-expensive-optimizations -S -c ReadQm.cpp' Assembler output with some comments: <asm begin> // r8 == ptr mov r8,r4 // r4 = ptr jsr @r12 // call Read32(ptr + 1), note: this line is executed after next because of SH4's 'delayed slot' stuff mov.b @r4+,r9 // r9 = tag, r4 = (ptr + 1) tst r9,r9 mov r8,r1 // r1 = ptr bt/s .L5 add #5,r1 // r1 = ((ptr + 1) + 4) ALL GOOD HERE <asm end> GCC info: yan@ws-zavadovskiy:~/000_sh4_qmreader$ ./820/bin/sh4-unknown-linux-gnu-g++ -v Using built-in specs. COLLECT_GCC=./820/bin/sh4-unknown-linux-gnu-g++ COLLECT_LTO_WRAPPER=/yan/000_sh4_qmreader/820/bin/../libexec/gcc/sh4-unknown-linux-gnu/8.2.0/lto-wrapper Target: sh4-unknown-linux-gnu Configured with: /yan/000_sh4_gcc/ct-ng/.build/sh4-unknown-linux-gnu/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=sh4-unknown-linux-gnu --prefix=/yan/000_sh4_gcc/ct-ng/../sh4-unknown-linux-gnu --with-sysroot=/yan/000_sh4_gcc/sh4-unknown-linux-gnu/sh4-unknown-linux-gnu/sysroot --enable-languages=c,c++ --with-pkgversion='crosstool-NG 1.23.0.580-eb72b4e' --enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libsanitizer --disable-libmpx --with-gmp=/yan/000_sh4_gcc/ct-ng/.build/sh4-unknown-linux-gnu/buildtools --with-mpfr=/yan/000_sh4_gcc/ct-ng/.build/sh4-unknown-linux-gnu/buildtools --with-mpc=/yan/000_sh4_gcc/ct-ng/.build/sh4-unknown-linux-gnu/buildtools --with-isl=/yan/000_sh4_gcc/ct-ng/.build/sh4-unknown-linux-gnu/buildtools --disable-lto --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++ -lm' --enable-threads=posix --enable-target-optspace --disable-plugin --disable-nls --enable-multiarch --with-local-prefix=/yan/000_sh4_gcc/sh4-unknown-linux-gnu/sh4-unknown-linux-gnu/sysroot --enable-long-long Thread model: posix gcc version 8.2.0 (crosstool-NG 1.23.0.580-eb72b4e) I've additionally checked some GCC versions: GCC 4.6 and 4.7 on st-sh4, x86-64, armv7, mips - no bug GCC 4.9.4 on st-sh4 - no bug GCC 5.4.0 on st-sh4 - has bug GCC 6.3.0 on armv8, mips - no bug GCC 6.3.0 on st-sh4 - has bug GCC 6.5.0 on st-sh4 - has bug GCC 7.4.0 on st-sh4 - has bug