1; RUN: llc < %s -mtriple=thumb-apple-ios | FileCheck %s --check-prefix=CHECK --check-prefix=ALIGN4 2; RUN: llc < %s -mtriple=thumb-none-eabi | FileCheck %s --check-prefix=CHECK --check-prefix=ALIGN8 3; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-apple-ios 4; RUN: llvm-objdump -triple=thumbv6-apple-ios -d %t | FileCheck %s --check-prefix=CHECK --check-prefix=ALIGN4 5; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-none-eabi 6; RUN: llvm-objdump -triple=thumbv6-none-eabi -d %t | FileCheck %s --check-prefix=CHECK --check-prefix=ALIGN8 7 8; Largest stack for which a single tADDspi/tSUBspi is enough 9define void @test1() { 10; CHECK-LABEL: test1: 11; CHECK: sub sp, #508 12; CHECK: add sp, #508 13 %tmp = alloca [ 508 x i8 ] , align 4 14 ret void 15} 16 17; Largest stack for which three tADDspi/tSUBspis are enough 18define void @test100() { 19; CHECK-LABEL: test100: 20; CHECK: sub sp, #508 21; CHECK: sub sp, #508 22; CHECK: sub sp, #508 23; CHECK: add sp, #508 24; CHECK: add sp, #508 25; CHECK: add sp, #508 26 %tmp = alloca [ 1524 x i8 ] , align 4 27 ret void 28} 29 30; Largest stack for which three tADDspi/tSUBspis are enough 31define void @test100_nofpelim() "no-frame-pointer-elim"="true" { 32; CHECK-LABEL: test100_nofpelim: 33; CHECK: sub sp, #508 34; CHECK: sub sp, #508 35; CHECK: sub sp, #508 36; ALIGN4: subs r4, r7, #4 37; ALIGN8: subs r4, r7, #7 38; ALIGN8: subs r4, #1 39; CHECK: mov sp, r4 40 %tmp = alloca [ 1524 x i8 ] , align 4 41 ret void 42} 43 44; Smallest stack for which we use a constant pool 45define void @test2() { 46; CHECK-LABEL: test2: 47; CHECK: ldr [[TEMP:r[0-7]]], 48; CHECK: add sp, [[TEMP]] 49; CHECK: ldr [[TEMP:r[0-7]]], 50; CHECK: add sp, [[TEMP]] 51 %tmp = alloca [ 1528 x i8 ] , align 4 52 ret void 53} 54 55; Smallest stack for which we use a constant pool 56define void @test2_nofpelim() "no-frame-pointer-elim"="true" { 57; CHECK-LABEL: test2_nofpelim: 58; CHECK: ldr [[TEMP:r[0-7]]], 59; CHECK: add sp, [[TEMP]] 60; ALIGN4: subs r4, r7, #4 61; ALIGN8: subs r4, r7, #7 62; ALIGN8: subs r4, #1 63; CHECK: mov sp, r4 64 %tmp = alloca [ 1528 x i8 ] , align 4 65 ret void 66} 67 68define i32 @test3() { 69; CHECK-LABEL: test3: 70; CHECK: ldr [[TEMP:r[0-7]]], 71; CHECK: add sp, [[TEMP]] 72; CHECK: ldr [[TEMP2:r[0-7]]], 73; CHECK: add [[TEMP2]], sp 74; CHECK: ldr [[TEMP3:r[0-7]]], 75; CHECK: add sp, [[TEMP3]] 76 %retval = alloca i32, align 4 77 %tmp = alloca i32, align 4 78 %a = alloca [805306369 x i8], align 4 79 store i32 0, i32* %tmp 80 %tmp1 = load i32, i32* %tmp 81 ret i32 %tmp1 82} 83 84define i32 @test3_nofpelim() "no-frame-pointer-elim"="true" { 85; CHECK-LABEL: test3_nofpelim: 86; CHECK: ldr [[TEMP:r[0-7]]], 87; CHECK: add sp, [[TEMP]] 88; CHECK: ldr [[TEMP2:r[0-7]]], 89; CHECK: add [[TEMP2]], sp 90; CHECK: subs r4, r7, 91; CHECK: mov sp, r4 92 %retval = alloca i32, align 4 93 %tmp = alloca i32, align 4 94 %a = alloca [805306369 x i8], align 8 95 store i32 0, i32* %tmp 96 %tmp1 = load i32, i32* %tmp 97 ret i32 %tmp1 98} 99 100; Here, the adds get optimized out because they are dead, but the calculation 101; of the address of stack_a is dead but not optimized out. When the address 102; calculation gets expanded to two instructions, we need to avoid reading a 103; dead register. 104; No CHECK lines (just test for crashes), as we hope this will be optimised 105; better in future. 106define i32 @test4() { 107entry: 108 %stack_a = alloca i8, align 1 109 %stack_b = alloca [256 x i32*], align 4 110 %int = ptrtoint i8* %stack_a to i32 111 %add = add i32 %int, 1 112 br label %block2 113 114block2: 115 %add2 = add i32 %add, 1 116 ret i32 0 117} 118