1; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s 2declare void @use_addr(i8*) 3 4@addr = global i8* null 5 6define 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 52define 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. 95define 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