[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