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)