<div dir="ltr"><div>Hi all,</div><div><br></div><div>@James thanks a lot for the prompt diagnostic. <br></div><div><br></div><div>@Jan: I raised <a href="https://bugs.llvm.org/show_bug.cgi?id=47499">https://bugs.llvm.org/show_bug.cgi?id=47499</a> and I'll look into it ASAP.</div><div><br></div><div>I think we want to keep both languages in sync, so bring the C behaviour to C++.</div><div><br></div><div>C++ users that might be impacted by this (clang in Windows I presume) might want to weigh in just in case this is a bad idea.</div><div><br></div><div>My understanding is that __unaligned is a specifier that came from the Windows Itanium era. A quick check (using James' testcase) shows that x86 assembly output is not impacted. I assume that the X86 backend can be lenient when it comes to alignment due to what x86 has historically done there, correct me if I'm wrong.</div><div><br></div><div>Kind regards,<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Missatge de James Y Knight <<a href="mailto:jyknight@google.com">jyknight@google.com</a>> del dia dv., 11 de set. 2020 a les 19:50:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">There seems to be <i>something</i> implemented, but it looks buggy. Compiling the below example (<a href="https://godbolt.org/z/7rcErj" target="_blank">https://godbolt.org/z/7rcErj</a>) with "-O2 -fms-extensions -emit-llvm" emits: <br>  store i64 5, i64* %2, align 1, !tbaa !2<br><div>in C, but</div><div>  store i64 5, i64* %2, align 8, !tbaa !2<br></div><div>in C++.</div><div><div><br></div><div>struct Foo {<br>  unsigned long x;<br>};<br><br>void foo(__unaligned struct Foo* out){<br>  out->x = 5;<br>}<br><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 11, 2020 at 12:07 PM Jan Ole Hüser via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Dear all, Dear Roger Ferrer Ibáñez,<br>
<br>
at my company we have much Code, which uses the keyword "__unaligned" [1],<br>
which is a Microsoft extension.  I have read about an RFC called "Implement<br>
code generation for __unaligned" on the mailing list (from Feburary 2017) [2].<br>
But I could not find out, if it was actually implemented. Is it implemented? If<br>
it is, it does not work for ARM. (Tested with ARMv7-M.)<br>
<br>
Consider the following Code:<br>
<br>
```<br>
struct GUID {<br>
  unsigned long  Data1;<br>
  unsigned short Data2;<br>
  unsigned short Data3;<br>
  unsigned char  Data4[8];<br>
};<br>
<br>
void load_and_store_uGUID(__unaligned GUID* in, __unaligned GUID* out){<br>
        *out = *in;<br>
}<br>
```<br>
<br>
It produces the following assembly:<br>
<br>
```<br>
        ldm.w   r0, {r2, r3, r12}<br>
        ldr     r0, [r0, #12]<br>
        stm.w   r1, {r2, r3, r12}<br>
        str     r0, [r1, #12]<br>
        bx      lr<br>
```<br>
<br>
I have used the this commandline:<br>
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<br>
<br>
The problem is, that LDM and STM (load and store multiple) are used, which<br>
cannot access one-byte-aligned addresses (aka. unaligned). LDR and STR however<br>
can be used for unaligned access.<br>
<br>
The following C++ code translates to code, which can access unalgined memory.<br>
```<br>
extern "C" void* memcpy( void* dest, const void* src, decltype(sizeof(0)) count );<br>
<br>
void load_and_store_memcpy(__unaligned GUID* in, __unaligned GUID* out){<br>
        memcpy(reinterpret_cast<char*>(out), reinterpret_cast<char*>(in),<br>
                sizeof(__unaligned GUID));<br>
}<br>
```<br>
<br>
The cast to a byte pointer is necessary.<br>
<br>
Here is the assembler Code:<br>
```<br>
        ldr.w   r12, [r0]<br>
        ldr     r3, [r0, #4]<br>
        ldr     r2, [r0, #8]<br>
        ldr     r0, [r0, #12]<br>
        str     r0, [r1, #12]<br>
        str     r2, [r1, #8]<br>
        str     r3, [r1, #4]<br>
        str.w   r12, [r1]<br>
        bx      lr<br>
```<br>
<br>
<br>
I could rewrite all that old code to use memcpy or use structs with<br>
__attribute__((packed)). But maybe --I hope-- there is some old patch for<br>
clang, that didn't get into trunk, but could help me out. Or maybe it is easy<br>
to implement. @Roger, is there a patch somewhere?<br>
<br>
Site Note:<br>
The problem with __attribute__((packed)) is, that it cannot be added to an<br>
existing type (for example: "typedef __attribute__((packed)) GUID pGUID;"), but<br>
the definition has to be changed. Another problem is, that it changes the offset<br>
of the members in the struct. Is that called "Record Layout"?<br>
<br>
Kind regards,<br>
Ole<br>
<br>
[1] <a href="https://docs.microsoft.com/en-us/cpp/cpp/unaligned" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/cpp/cpp/unaligned</a><br>
[2] <a href="http://lists.llvm.org/pipermail/cfe-dev/2017-February/052739.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/cfe-dev/2017-February/052739.html</a><br>
Beckhoff Automation GmbH & Co. KG | Managing Director: Dipl. Phys. Hans Beckhoff<br>
Registered office: Verl, Germany | Register court: Guetersloh HRA 7075<br>
<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature">Roger Ferrer Ibáñez<br></div>