diff options
Diffstat (limited to 'test/CodeGen/ARM/thumb1-varalloc.ll')
-rw-r--r-- | test/CodeGen/ARM/thumb1-varalloc.ll | 105 |
1 files changed, 103 insertions, 2 deletions
diff --git a/test/CodeGen/ARM/thumb1-varalloc.ll b/test/CodeGen/ARM/thumb1-varalloc.ll index e07e8aa..8d5888d 100644 --- a/test/CodeGen/ARM/thumb1-varalloc.ll +++ b/test/CodeGen/ARM/thumb1-varalloc.ll @@ -1,13 +1,15 @@ ; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s ; RUN: llc < %s -mtriple=thumbv6-apple-darwin -regalloc=basic | FileCheck %s -; rdar://8819685 +; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-apple-darwin +; RUN: llvm-objdump -triple=thumbv6-apple-darwin -d %t | FileCheck %s @__bar = external hidden global i8* @__baz = external hidden global i8* +; rdar://8819685 define i8* @_foo() { entry: -; CHECK: foo: +; CHECK-LABEL: foo: %size = alloca i32, align 4 %0 = load i8** @__bar, align 4 @@ -40,3 +42,102 @@ bb3: declare noalias i8* @strdup(i8* nocapture) nounwind declare i32 @_called_func(i8*, i32*) nounwind + +; Variable ending up at unaligned offset from sp (i.e. not a multiple of 4) +define void @test_local_var_addr() { +; CHECK-LABEL: test_local_var_addr: + + %addr1 = alloca i8 + %addr2 = alloca i8 + +; CHECK: mov r0, sp +; CHECK: adds r0, #{{[0-9]+}} +; CHECK: blx + call void @take_ptr(i8* %addr1) + +; CHECK: mov r0, sp +; CHECK: adds r0, #{{[0-9]+}} +; CHECK: blx + call void @take_ptr(i8* %addr2) + + ret void +} + +; Simple variable ending up *at* sp. +define void @test_simple_var() { +; CHECK-LABEL: test_simple_var: + + %addr32 = alloca i32 + %addr8 = bitcast i32* %addr32 to i8* + +; CHECK: mov r0, sp +; CHECK-NOT: adds r0 +; CHECK: blx + call void @take_ptr(i8* %addr8) + ret void +} + +; Simple variable ending up at aligned offset from sp. +define void @test_local_var_addr_aligned() { +; CHECK-LABEL: test_local_var_addr_aligned: + + %addr1.32 = alloca i32 + %addr1 = bitcast i32* %addr1.32 to i8* + %addr2.32 = alloca i32 + %addr2 = bitcast i32* %addr2.32 to i8* + +; CHECK: add r0, sp, #{{[0-9]+}} +; CHECK: blx + call void @take_ptr(i8* %addr1) + +; CHECK: mov r0, sp +; CHECK-NOT: add r0 +; CHECK: blx + call void @take_ptr(i8* %addr2) + + ret void +} + +; Simple variable ending up at aligned offset from sp. +define void @test_local_var_big_offset() { +; CHECK-LABEL: test_local_var_big_offset: + %addr1.32 = alloca i32, i32 257 + %addr1 = bitcast i32* %addr1.32 to i8* + %addr2.32 = alloca i32, i32 257 + +; CHECK: add [[RTMP:r[0-9]+]], sp, #1020 +; CHECK: adds [[RTMP]], #8 +; CHECK: blx + call void @take_ptr(i8* %addr1) + + ret void +} + +; Max range addressable with tADDrSPi +define void @test_local_var_offset_1020() { +; CHECK-LABEL: test_local_var_offset_1020 + %addr1 = alloca i8, i32 4 + %addr2 = alloca i8, i32 1020 + +; CHECK: add r0, sp, #1020 +; CHECK-NEXT: blx + call void @take_ptr(i8* %addr1) + + ret void +} + +; Max range addressable with tADDrSPi + tADDi8 +define void @test_local_var_offset_1275() { +; CHECK-LABEL: test_local_var_offset_1275 + %addr1 = alloca i8, i32 1 + %addr2 = alloca i8, i32 1275 + +; CHECK: add r0, sp, #1020 +; CHECK: adds r0, #255 +; CHECK-NEXT: blx + call void @take_ptr(i8* %addr1) + + ret void +} + +declare void @take_ptr(i8*) |