1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s 2 declare void @use_addr(i8*) 3 4 @addr = global i8* null 5 6 define void @test_bigframe() { 7 ; CHECK-LABEL: test_bigframe: 8 ; CHECK: .cfi_startproc 9 10 %var1 = alloca i8, i32 20000000 11 %var2 = alloca i8, i32 16 12 %var3 = alloca i8, i32 20000000 13 ; CHECK: sub sp, sp, #496 14 ; CHECK: .cfi_def_cfa sp, 496 15 ; CHECK: str x30, [sp, #488] 16 ; Total adjust is 39999536 17 ; CHECK: movz [[SUBCONST:x[0-9]+]], #22576 18 ; CHECK: movk [[SUBCONST]], #610, lsl #16 19 ; CHECK: sub sp, sp, [[SUBCONST]] 20 ; CHECK: .cfi_def_cfa sp, 40000032 21 ; CHECK: .cfi_offset x30, -8 22 23 ; Total offset is 20000024 24 ; CHECK: movz [[VAR1OFFSET:x[0-9]+]], #11544 25 ; CHECK: movk [[VAR1OFFSET]], #305, lsl #16 26 ; CHECK: add {{x[0-9]+}}, sp, [[VAR1OFFSET]] 27 store volatile i8* %var1, i8** @addr 28 29 %var1plus2 = getelementptr i8* %var1, i32 2 30 store volatile i8* %var1plus2, i8** @addr 31 32 ; CHECK: movz [[VAR2OFFSET:x[0-9]+]], #11528 33 ; CHECK: movk [[VAR2OFFSET]], #305, lsl #16 34 ; CHECK: add {{x[0-9]+}}, sp, [[VAR2OFFSET]] 35 store volatile i8* %var2, i8** @addr 36 37 %var2plus2 = getelementptr i8* %var2, i32 2 38 store volatile i8* %var2plus2, i8** @addr 39 40 store volatile i8* %var3, i8** @addr 41 42 %var3plus2 = getelementptr i8* %var3, i32 2 43 store volatile i8* %var3plus2, i8** @addr 44 45 ; CHECK: movz [[ADDCONST:x[0-9]+]], #22576 46 ; CHECK: movk [[ADDCONST]], #610, lsl #16 47 ; CHECK: add sp, sp, [[ADDCONST]] 48 ; CHECK: .cfi_endproc 49 ret void 50 } 51 52 define void @test_mediumframe() { 53 ; CHECK-LABEL: test_mediumframe: 54 %var1 = alloca i8, i32 1000000 55 %var2 = alloca i8, i32 16 56 %var3 = alloca i8, i32 1000000 57 ; CHECK: sub sp, sp, #496 58 ; CHECK: str x30, [sp, #488] 59 ; CHECK: sub sp, sp, #688 60 ; CHECK-NEXT: sub sp, sp, #488, lsl #12 61 62 store volatile i8* %var1, i8** @addr 63 ; CHECK: add [[VAR1ADDR:x[0-9]+]], sp, #600 64 ; CHECK: add [[VAR1ADDR]], [[VAR1ADDR]], #244, lsl #12 65 66 %var1plus2 = getelementptr i8* %var1, i32 2 67 store volatile i8* %var1plus2, i8** @addr 68 ; CHECK: add [[VAR1PLUS2:x[0-9]+]], {{x[0-9]+}}, #2 69 70 store volatile i8* %var2, i8** @addr 71 ; CHECK: add [[VAR2ADDR:x[0-9]+]], sp, #584 72 ; CHECK: add [[VAR2ADDR]], [[VAR2ADDR]], #244, lsl #12 73 74 %var2plus2 = getelementptr i8* %var2, i32 2 75 store volatile i8* %var2plus2, i8** @addr 76 ; CHECK: add [[VAR2PLUS2:x[0-9]+]], {{x[0-9]+}}, #2 77 78 store volatile i8* %var3, i8** @addr 79 80 %var3plus2 = getelementptr i8* %var3, i32 2 81 store volatile i8* %var3plus2, i8** @addr 82 83 ; CHECK: add sp, sp, #688 84 ; CHECK: add sp, sp, #488, lsl #12 85 ; CHECK: ldr x30, [sp, #488] 86 ; CHECK: add sp, sp, #496 87 ret void 88 } 89 90 91 @bigspace = global [8 x i64] zeroinitializer 92 93 ; If temporary registers are allocated for adjustment, they should *not* clobber 94 ; argument registers. 95 define void @test_tempallocation([8 x i64] %val) nounwind { 96 ; CHECK-LABEL: test_tempallocation: 97 %var = alloca i8, i32 1000000 98 ; CHECK: sub sp, sp, 99 100 ; Make sure the prologue is reasonably efficient 101 ; CHECK-NEXT: stp x29, x30, [sp, 102 ; CHECK-NEXT: stp x25, x26, [sp, 103 ; CHECK-NEXT: stp x23, x24, [sp, 104 ; CHECK-NEXT: stp x21, x22, [sp, 105 ; CHECK-NEXT: stp x19, x20, [sp, 106 107 ; Make sure we don't trash an argument register 108 ; CHECK-NOT: movz {{x[0-7],}} 109 ; CHECK: sub sp, sp, 110 111 ; CHECK-NOT: movz {{x[0-7],}} 112 113 ; CHECK: bl use_addr 114 call void @use_addr(i8* %var) 115 116 store [8 x i64] %val, [8 x i64]* @bigspace 117 ret void 118 ; CHECK: ret 119 } 120