karnajit wangkhem via llvm-dev
2017-Oct-11 04:16 UTC
[llvm-dev] 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; } ------------------------------- $ 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/a485de60/attachment.html>
Tim Northover via llvm-dev
2017-Oct-11 14:35 UTC
[llvm-dev] alloca + strd issue on arm freebsd
Hi Karnajit, On 10 October 2017 at 21:16, karnajit wangkhem via llvm-dev <llvm-dev at lists.llvm.org> wrote:> $ 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 8This 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.