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)

Reply via email to