[cfe-dev] Cortex-M4F Assembly Code Generation Incorrect for float casting, causing HardFaults

Stephen Canon via cfe-dev cfe-dev at lists.llvm.org
Thu Aug 10 07:57:13 PDT 2017


On Aug 10, 2017, at 10:36 AM, David Chisnall via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> This seems to be as expected.  This pair of lines:
> 
>>    auto valuePtr = reinterpret_cast<T*> (data);
>>    auto value = *valuePtr;
> 
> 
> Is asserting to the compiler that data is correctly aligned for T, which in your case is a float.  Dereferencing this pointer is therefore allowed to assume alignment.  If you have an underaligned pointer, then C++ provides the alignas keyword that allows you to specify an under-aligned type.  If the VLDR instruction is still generated with an alignas(1) type, then this is a bug, otherwise this is the compiler generating code that does what you instructed it to do.

Formally, alignas cannot be used to relax alignment:

10.6.2 p5:
"The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers appertaining to that entity were omitted.”

Clang and recent GCC both support relaxing alignment via the `__attribute__((aligned(N)))` extension; older GCCs are documented as not supporting relaxing alignment, though it may work in practice.

My usual advice for misaligned load/stores, however, is "just use memcpy”. Clang and GCC are both quite good at lowering the call and doing what you want: https://godbolt.org/g/AqzdX8

– Steve


More information about the cfe-dev mailing list