Linux/ARM: Fix +3000 bus errors of unit-test in case of O2/O3 levels (dotnet/coreclr...
authorGeunsik Lim <leemgs@users.noreply.github.com>
Tue, 26 Jul 2016 03:59:47 +0000 (12:59 +0900)
committerJan Kotas <jkotas@microsoft.com>
Tue, 26 Jul 2016 03:59:47 +0000 (20:59 -0700)
commitb8f9ec9dd2fdacaf132a6906d12c5ee8b0d0083a
treec61ad285bfe5a52ae9344ed686294c4f50657201
parent0aa128d195a298cfc0c17f88e159d49842e2d063
Linux/ARM: Fix +3000 bus errors of unit-test in case of O2/O3 levels (dotnet/coreclr#6379)

**PROBLEM**
This patch is to resolve +3000 bus errors that are generated whenever we use
the aggressive optimization levels of clang (issue dotnet/coreclr#5844 ).

When we enable the -O3 optimization level of the clang version(from clang 3.5
to clang 3.9(snapshot)), we have always got the lots of bus errors from the
coreCLR's unit tests. Actually, we can easily monitor SIGBUS signals (e.g.,
"misaligned memory access") with /proc/cpu/alignment facility in kernel space.
Using "echo 2 > /proc/cpu/alignment" makes Linux kernel fixes the problems
but the performance of the application will be degraded.
.source: http://lxr.free-electrons.com/source/Documentation/arm/mem_alignment

**VERSION 4**
. Use 'GET_UNALIGNED_VALXXX' macros in the CoreClr infra-structure without
  any need for ifdefs.

**VERSION 3**
.Apply this PR on only Linux/ARM for different system environment (Windows).

Here is .NET CI Report on Windows: Compile Error
error C2146: syntax error: missing ';' before identifier '__unaligned_int32'
(compiling source file D:\j\workspace\checked_windo---f6dc6fe4\src\jit\alloc.cpp)
[D:\j\workspace\checked_windo---f6dc6fe4\bin\obj\Windows_NT.x64.Checked\src\jit\
crossgen\clrjit_crossgen.vcxproj] Indication 1

**VERSION 2**
.Add UNALIGNED_ARM macro for handling ARM core specific optimization levels.
.Add RISC-based ARM core handling into the existing infra-structure of the
platform adaptation layer (PAL) for aggressive optimization cases on Linux/ARM.

**VERSION 1**
Basically, RISC-based ARM architecture requires aligned access with 4byte reads.
In order to support aggressive optimization levels such as O2/O3, let's use
attribute keyword of aligned(1) instead of using memcpy(2) in into
a properly aligned buffer or the packing attribute.

**BACKGROUND**
According to ARM information center(infocenter.arm.com), By default,
the ARM compiler expects normal C and C++ pointers to point
to an aligned word in memory. A type qualifier __packed is provided to
enable unaligned pointer access. If you want to define a pointer to a word
that can be at any address (that is, that can be at a non-natural alignment),
you must specify this using the __packed qualifier when defining the pointer:
__packed int *pi; // pointer to unaligned int

However, clang/llvm does not support the __packed qualifier such as
__attribute__((packed)) or __attribute__((packed, aligned(4)))

In -O0 (debug build) the innermost block is emitted as the following assembly,
which works properly:
 ldr r1, [r0, dotnet/coreclr#24]
 ldr r2, [r0, dotnet/coreclr#20]

In -O3 (release build) however the compiler realizes these fields are adjacent
and generates this assembly:
 ldrdeq  r2, r3, [r0, dotnet/coreclr#20]
Unfortunately, vldr/ldrdb instructions always generate an alignment fault
(in practice). It seems that clang uses ldrb instruction although GCC uses
ldr instruction because armv7 supports unaligned ldr instruction.

Note: If some arm architectures (e.g., Linux/ARM Emulator) does not support
unaligned ldr, this issue is not generated with aggressive optimization
levels (e.g., -O2 and -O3).

* Case study: How does the ARM Compiler support unaligned accesses?
  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html

* Case study: Indicating unaligned access to Clang for ARM compatibility
  http://stackoverflow.com/questions/9185811/indicating-unaligned-access-to-clang-for-arm-compatibility

* Case study: Chromium source for UnalignedLoad32() on ARM
  https://github.com/nwjs/chromium.src/blob/nw15/third_party/cld/base/basictypes.h#L302

Signed-off-by: Geunsik Lim <geunsik.lim@samsung.com>
Commit migrated from https://github.com/dotnet/coreclr/commit/561b64d2c210b4d999de7f1ac55756704eaba784
src/coreclr/src/jit/compiler.hpp
src/coreclr/src/pal/inc/pal_endian.h