[cfe-dev] [ARM] Is code generation implemented for __unaligned?

James Y Knight via cfe-dev cfe-dev at lists.llvm.org
Fri Sep 11 10:50:31 PDT 2020


There seems to be *something* implemented, but it looks buggy. Compiling
the below example (https://godbolt.org/z/7rcErj) with "-O2 -fms-extensions
-emit-llvm" emits:
  store i64 5, i64* %2, align 1, !tbaa !2
in C, but
  store i64 5, i64* %2, align 8, !tbaa !2
in C++.

struct Foo {
  unsigned long x;
};

void foo(__unaligned struct Foo* out){
  out->x = 5;
}


On Fri, Sep 11, 2020 at 12:07 PM Jan Ole Hüser via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Dear all, Dear Roger Ferrer Ibáñez,
>
> at my company we have much Code, which uses the keyword "__unaligned" [1],
> which is a Microsoft extension.  I have read about an RFC called "Implement
> code generation for __unaligned" on the mailing list (from Feburary 2017)
> [2].
> But I could not find out, if it was actually implemented. Is it
> implemented? If
> it is, it does not work for ARM. (Tested with ARMv7-M.)
>
> Consider the following Code:
>
> ```
> struct GUID {
>   unsigned long  Data1;
>   unsigned short Data2;
>   unsigned short Data3;
>   unsigned char  Data4[8];
> };
>
> void load_and_store_uGUID(__unaligned GUID* in, __unaligned GUID* out){
>         *out = *in;
> }
> ```
>
> It produces the following assembly:
>
> ```
>         ldm.w   r0, {r2, r3, r12}
>         ldr     r0, [r0, #12]
>         stm.w   r1, {r2, r3, r12}
>         str     r0, [r1, #12]
>         bx      lr
> ```
>
> I have used the this commandline:
> C:\Program Files\LLVM\bin\clang++.exe -O2 -S
> --target=armv7m-none-windows-eabihf -munaligned-access -x c++
> -mcpu=cortex-M7 -fms-compatibility-version=19.16.27027.1 -fms-compatibility
> -fms-extensions
>
> The problem is, that LDM and STM (load and store multiple) are used, which
> cannot access one-byte-aligned addresses (aka. unaligned). LDR and STR
> however
> can be used for unaligned access.
>
> The following C++ code translates to code, which can access unalgined
> memory.
> ```
> extern "C" void* memcpy( void* dest, const void* src, decltype(sizeof(0))
> count );
>
> void load_and_store_memcpy(__unaligned GUID* in, __unaligned GUID* out){
>         memcpy(reinterpret_cast<char*>(out), reinterpret_cast<char*>(in),
>                 sizeof(__unaligned GUID));
> }
> ```
>
> The cast to a byte pointer is necessary.
>
> Here is the assembler Code:
> ```
>         ldr.w   r12, [r0]
>         ldr     r3, [r0, #4]
>         ldr     r2, [r0, #8]
>         ldr     r0, [r0, #12]
>         str     r0, [r1, #12]
>         str     r2, [r1, #8]
>         str     r3, [r1, #4]
>         str.w   r12, [r1]
>         bx      lr
> ```
>
>
> I could rewrite all that old code to use memcpy or use structs with
> __attribute__((packed)). But maybe --I hope-- there is some old patch for
> clang, that didn't get into trunk, but could help me out. Or maybe it is
> easy
> to implement. @Roger, is there a patch somewhere?
>
> Site Note:
> The problem with __attribute__((packed)) is, that it cannot be added to an
> existing type (for example: "typedef __attribute__((packed)) GUID
> pGUID;"), but
> the definition has to be changed. Another problem is, that it changes the
> offset
> of the members in the struct. Is that called "Record Layout"?
>
> Kind regards,
> Ole
>
> [1] https://docs.microsoft.com/en-us/cpp/cpp/unaligned
> [2] http://lists.llvm.org/pipermail/cfe-dev/2017-February/052739.html
> Beckhoff Automation GmbH & Co. KG | Managing Director: Dipl. Phys. Hans
> Beckhoff
> Registered office: Verl, Germany | Register court: Guetersloh HRA 7075
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200911/c02378d4/attachment.html>


More information about the cfe-dev mailing list