https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71048
Bug ID: 71048 Summary: unexpected/invalid handling of partially aligned volatile Product: gcc Version: 5.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ledvinap+bugzilla at gmail dot com Target Milestone: --- Created attachment 38462 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38462&action=edit minimal test code When dereferencing volatile pointer that is half-word aligned (and gcc can infer it): - two half-word accesses are used - memory location is read too Test code: #define BTABLE (*(uint32_t*)100) *(volatile uint32_t*)(BTABLE * 2) = 101; generated assembly: movs r3, #100 @ tmp114, ldr r3, [r3] @ MEM[(uint32_t *)100B], MEM[(uint32_t *)100B] movs r0, #0 @ tmp117, lsls r3, r3, #1 @ D.4231, MEM[(uint32_t *)100B], ldrh r2, [r3] @, *_4 movs r2, #101 @ tmp119, strh r2, [r3] @ movhi @ tmp119, *_4 ldrh r2, [r3, #2] @, *_4 strh r0, [r3, #2] @ movhi @ tmp117, *_4 - memory is written using strh instruction on architecture that allows non-aligned access. This is not a bug, but is very confusing. - unexpected read instruction (ldrh) is emitted before read - access is read(lower halfword) / write(lower halfword) / read(upper halfword) / write(upper halfword) When dereferencing (BTABLE * 1), (BTABLE * 3), (BTABLE * 4), (BTABLE * 11), ((BTABLE * 2) & ~3) the generated code is reasonable (using single ldr instruction, only reading memory location): *(volatile uint32_t*)(BTABLE) = 101; movs r3, #100 @ tmp113, ldr r3, [r3] @ D.4230, MEM[(uint32_t *)100B] movs r2, #101 @ tmp114, str r2, [r3] @ tmp114, *_3 movs r0, #0 @, With (BTABLE * 6), mul instruction is used to get correct address, then read is identical to (BTABLE * 2) case. t1.c: #include <stdint.h> #define BTABLE (*(uint32_t*)100) int test(void) { *(volatile uint32_t*)((BTABLE * 2)) = 101; return 0; } void _start(void) { test(); } command to compile: arm-none-eabi-gcc -nostartfiles -mthumb -mcpu=cortex-m3 -Os -ffat-lto-objects -fverbose-asm -S t1.c Affected version (from https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2): arm-none-eabi-gcc -v Using built-in specs. COLLECT_GCC=arm-none-eabi-gcc COLLECT_LTO_WRAPPER=/home/ledvinap/gcc-arm-none-eabi-5_3-2016q1/bin/../lib/gcc/arm-none-eabi/5.3.1/lto-wrapper Target: arm-none-eabi Configured with: /home/build/work/GCC-5-0-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-5-0-build/install-native --libexecdir=/home/build/work/GCC-5-0-build/install-native/lib --infodir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-5-0-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r,armv8-m.base,armv8-m.main Thread model: single gcc version 5.3.1 20160307 (release) [ARM/embedded-5-branch revision 234589] (GNU Tools for ARM Embedded Processors)