[llvm-dev] alloca + strd issue on arm freebsd

karnajit wangkhem via llvm-dev llvm-dev at lists.llvm.org
Tue Oct 10 12:21:57 PDT 2017


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;
}
-------------------------------

$ cat strd_test.ll
; ModuleID = 'strd_test.c'
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv6kz--freebsd11.0-gnueabihf"

@.str = private unnamed_addr constant [15 x i8] c"dst addr = %p\0A\00",
align 1
@.str.1 = private unnamed_addr constant [14 x i8] c"value = %llx\0A\00",
align 1

; Function Attrs: nounwind
define void @test_strd(i64* %addr) #0 {
  %1 = alloca i64*, align 4
  %value = alloca i64, align 8
  store i64* %addr, i64** %1, align 4
  store i64 81985529206420566, i64* %value, align 8
  call void asm sideeffect "ldr     r4, [sp, #20];ldr     r3, [sp,
#12];ldr     r2, [sp, #8];strd    r2, r3, [r4];", ""() #2, !srcloc !3
  ret void
}

; Function Attrs: nounwind
define i32 @main() #0 {
  %1 = alloca i32, align 4
  %dst = alloca i64*, align 4
  store i32 0, i32* %1, align 4
  %2 = alloca i8
  %3 = alloca i8, i32 8
  %4 = bitcast i8* %3 to i64*
  store i64* %4, i64** %dst, align 4
  %5 = load i64*, i64** %dst, align 4
  %6 = bitcast i64* %5 to i8*
  %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8],
[15 x i8]* @.str, i32 0, i32 0), i8* %6)
  %8 = load i64*, i64** %dst, align 4
  call void @test_strd(i64* %8)
  %9 = load i64*, i64** %dst, align 4
  %10 = load i64, i64* %9, align 8
  %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8],
[14 x i8]* @.str.1, i32 0, i32 0), i64 %10)
  ret i32 0
}

declare i32 @printf(i8*, ...) #1

attributes #0 = { nounwind "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="arm1176jzf-s" "target-features"="+dsp,+strict-align,+vfp2"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="arm1176jzf-s"
"target-features"="+dsp,+strict-align,+vfp2" "unsafe-fp-math"="false"
"use-soft-float"="false" }
attributes #2 = { nounwind }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"min_enum_size", i32 4}
!2 = !{!"FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based
on LLVM 3.8.0)"}
!3 = !{i32 139}
-----------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171011/a2bd9a3d/attachment.html>


More information about the llvm-dev mailing list