alloca + strd issue on arm freebsd

Hi All,

Below code is compiled with clang on raspberry pi2(bcm2836) + freebsd11.0. But it doesn’t work well if address from alloca is not 32-bit aligned. I am trying to put down a scenario encountered on a large build system, but I am unable to generate strd with a simple c example so using asm here. This problem is encountered only on strd instruction and not on str. If strd instruction has a alignment requirement why is alloca returning an unaligned memory address(Not telling in the context of this example)? Please help me understand what is the best way to handle this issue.

$ clang -v
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0)
Target: armv6–freebsd11.0-gnueabihf
Thread model: posix
InstalledDir: /usr/bin

$ ./a.out
dst addr = 0xbfbfecaf
Bus error (core dumped)

But, if the address is 32-bit aligned

$ ./a.out
dst addr = 0xbfbfecb0
value = 123456789123456

Regards,
Karan

--------- CODE -----------

#include <stdio.h>
#include <stdlib.h>

void test_strd(unsigned long long* addr)
{
unsigned long long value = 0x123456789123456;
asm(“ldr r4, [sp, #20];”
“ldr r3, [sp, #12];”
“ldr r2, [sp, #8];”
“strd r2, r3, [r4];”);
}

/* void test_strd(unsigned long long* addr) /
/
{ /
/
unsigned long long value = 0x123456789123456; /
/
asm(“ldr r4, [sp, #20];” /
/
“ldr r3, [sp, #12];” /
/
“ldr r2, [sp, #8];” /
/
“str r3, [r4, #4];” /
/
“str r2, [r4];”); /
/
} */

int main()
{
alloca(1);
/* alloca(1); /
/
alloca(1); /
/
alloca(1); */
unsigned long long *dst = (unsigned long long *)alloca(sizeof(unsigned long long));
printf(“dst addr = %p\n”, (void *)dst);
test_strd(dst);
printf(“value = %llx\n”, *dst);

return 0;
}

Hi Karnajit,

$ clang -v
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM
3.8.0)
Target: armv6--freebsd11.0-gnueabihf
Thread model: posix
InstalledDir: /usr/bin

[...]

  %2 = alloca i8
  %3 = alloca i8, i32 8

This looks like a bug in how the alloca function is handled in Clang
3.8. Those instructions should be tagged with some ABI-sensible
alignment, and they are in newer versions of Clang but obviously not
back then.

So you probably either need to upgrade your compiler or work around
the bug by allocating more than you need and manually aligning the
result.

Cheers.

Tim.