1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2; RUN: llc -global-isel -mtriple=arm64-windows -stop-after=irtranslator -o - %s | FileCheck %s 3 4define void @local_escape() { 5 ; CHECK-LABEL: name: local_escape 6 ; CHECK: bb.1 (%ir-block.0): 7 ; CHECK-NEXT: LOCAL_ESCAPE <mcsymbol .Llocal_escape$frame_escape_1>, %stack.1.b 8 ; CHECK-NEXT: LOCAL_ESCAPE <mcsymbol .Llocal_escape$frame_escape_0>, %stack.0.a 9 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 10 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 13 11 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a 12 ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.b 13 ; CHECK-NEXT: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %ir.a) 14 ; CHECK-NEXT: G_STORE [[C1]](s32), [[FRAME_INDEX1]](p0) :: (store (s32) into %ir.b) 15 ; CHECK-NEXT: RET_ReallyLR 16 %a = alloca i32 17 %b = alloca i32, i32 2 18 call void (...) @llvm.localescape(ptr %a, ptr %b) 19 store i32 42, ptr %a 20 store i32 13, ptr %b 21 ret void 22} 23 24; Try some instructions before the localescape, and use a null 25define void @local_escape_insert_point() { 26 ; CHECK-LABEL: name: local_escape_insert_point 27 ; CHECK: bb.1 (%ir-block.0): 28 ; CHECK-NEXT: LOCAL_ESCAPE <mcsymbol .Llocal_escape_insert_point$frame_escape_2>, %stack.1.b 29 ; CHECK-NEXT: LOCAL_ESCAPE <mcsymbol .Llocal_escape_insert_point$frame_escape_0>, %stack.0.a 30 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 31 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 13 32 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a 33 ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.b 34 ; CHECK-NEXT: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %ir.a) 35 ; CHECK-NEXT: G_STORE [[C1]](s32), [[FRAME_INDEX1]](p0) :: (store (s32) into %ir.b) 36 ; CHECK-NEXT: RET_ReallyLR 37 %a = alloca i32 38 %b = alloca i32, i32 2 39 store i32 42, ptr %a 40 store i32 13, ptr %b 41 call void (...) @llvm.localescape(ptr %a, ptr null, ptr %b) 42 ret void 43} 44 45declare void @foo(ptr) 46 47; Check a cast of an alloca 48define void @local_escape_strip_ptr_cast() { 49 ; CHECK-LABEL: name: local_escape_strip_ptr_cast 50 ; CHECK: bb.1 (%ir-block.0): 51 ; CHECK-NEXT: LOCAL_ESCAPE <mcsymbol .Llocal_escape_strip_ptr_cast$frame_escape_0>, %stack.0.a 52 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 53 ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a 54 ; CHECK-NEXT: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %ir.a) 55 ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp 56 ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0) 57 ; CHECK-NEXT: BL @foo, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 58 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp 59 ; CHECK-NEXT: RET_ReallyLR 60 %a = alloca [128 x i32] 61 store i32 42, ptr %a 62 call void (...) @llvm.localescape(ptr %a, ptr null) 63 call void @foo(ptr %a) 64 ret void 65} 66 67declare void @llvm.localescape(...) #0 68 69attributes #0 = { nounwind } 70