brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · fd6b3fd Raw
274 lines · plain
1; RUN: llc -mtriple arm64-windows -o - %s | FileCheck %s2 3; struct S { int x; };4; void foo(int n);5; void foo(struct S o);6; void simple_seh() {7;   struct S o;8; 9;   __try { foo(o.x); }10;   __finally { foo(o.x); }11; }12; void stack_realign() {13;   struct S __declspec(align(32)) o;14; 15;   __try { foo(o.x); }16;   __finally { foo(o.x); }17; }18; void vla_present(int n) {19;   int vla[n];20; 21;   __try { foo(n); }22;   __finally { foo(n); }23; }24; void vla_and_realign(int n) {25;   struct S __declspec(align(32)) o;26;   int vla[n];27; 28;   __try { foo(o.x); }29;   __finally { foo(o.x); }30; }31 32%struct.S = type { i32 }33 34; Test simple SEH (__try/__finally).35define void @simple_seh() #0 personality ptr @__C_specific_handler {36entry:37; CHECK-LABEL: simple_seh38; CHECK: add     x29, sp, #1639; CHECK: mov     x0, #-240; CHECK: stur    x0, [x29, #16]41; CHECK: .Lsimple_seh$frame_escape_0 = -842; CHECK: ldur    w0, [x29, #-8]43; CHECK: bl      foo44 45  %o = alloca %struct.S, align 846  call void (...) @llvm.localescape(ptr %o)47  %0 = load i32, ptr %o, align 448  invoke void @foo(i32 %0) #549          to label %invoke.cont unwind label %ehcleanup50 51invoke.cont:                                      ; preds = %entry52  %1 = call ptr @llvm.localaddress()53  call void @fin_simple_seh(i8 0, ptr %1)54  ret void55 56ehcleanup:                                        ; preds = %entry57  %2 = cleanuppad within none []58  %3 = call ptr @llvm.localaddress()59  call void @fin_simple_seh(i8 1, ptr %3) [ "funclet"(token %2) ]60  cleanupret from %2 unwind to caller61}62 63define void @fin_simple_seh(i8 %abnormal_termination, ptr %frame_pointer) {64entry:65; CHECK-LABEL: fin_simple_seh66; CHECK: movz    x8, #:abs_g1_s:.Lsimple_seh$frame_escape_067; CHECK: movk    x8, #:abs_g0_nc:.Lsimple_seh$frame_escape_068; CHECK: strb    w0, [sp, #15]69; CHECK: ldr     w8, [x1, x8]70; CHECK: bl      foo71 72  %frame_pointer.addr = alloca ptr, align 873  %abnormal_termination.addr = alloca i8, align 174  %0 = call ptr @llvm.localrecover(ptr @simple_seh, ptr %frame_pointer, i32 0)75  store ptr %frame_pointer, ptr %frame_pointer.addr, align 876  store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 177  %1 = load i32, ptr %0, align 478  call void @foo(i32 %1)79  ret void80}81 82; Test SEH when stack realignment is needed in case highly aligned stack objects are present.83define void @stack_realign() #0 personality ptr @__C_specific_handler {84entry:85; CHECK-LABEL: stack_realign86; CHECK: add     x29, sp, #887; CHECK: sub     x9, sp, #1688; CHECK: and     sp, x9, #0xffffffffffffffe089; CHECK: mov     x19, sp90; CHECK: mov     x0, #-291; CHECK: stur    x0, [x29, #24]92; CHECK: .Lstack_realign$frame_escape_0 = 093; CHECK: ldr     w0, [x19]94; CHECK: bl      foo95 96  %o = alloca %struct.S, align 3297  call void (...) @llvm.localescape(ptr %o)98  %0 = load i32, ptr %o, align 3299  invoke void @foo(i32 %0) #5100          to label %invoke.cont unwind label %ehcleanup101 102invoke.cont:                                      ; preds = %entry103  %1 = call ptr @llvm.localaddress()104  call void @fin_stack_realign(i8 0, ptr %1)105  ret void106 107ehcleanup:                                        ; preds = %entry108  %2 = cleanuppad within none []109  %3 = call ptr @llvm.localaddress()110  call void @fin_stack_realign(i8 1, ptr %3) [ "funclet"(token %2) ]111  cleanupret from %2 unwind to caller112}113 114define void @fin_stack_realign(i8 %abnormal_termination, ptr %frame_pointer) {115entry:116; CHECK-LABEL: fin_stack_realign117; CHECK: movz    x8, #:abs_g1_s:.Lstack_realign$frame_escape_0118; CHECK: movk    x8, #:abs_g0_nc:.Lstack_realign$frame_escape_0119; CHECK: strb    w0, [sp, #15]120; CHECK: ldr     w8, [x1, x8]121; CHECK: bl      foo122 123  %frame_pointer.addr = alloca ptr, align 8124  %abnormal_termination.addr = alloca i8, align 1125  %0 = call ptr @llvm.localrecover(ptr @stack_realign, ptr %frame_pointer, i32 0)126  store ptr %frame_pointer, ptr %frame_pointer.addr, align 8127  store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 1128  %1 = load i32, ptr %0, align 32129  call void @foo(i32 %1)130  ret void131}132 133; Test SEH when variable size objects are present on the stack. Note: Escaped vla's are current not supported by SEH.134define void @vla_present(i32 %n) #0 personality ptr @__C_specific_handler {135entry:136; CHECK-LABEL: vla_present137; CHECK: add     x29, sp, #32138; CHECK: mov     x1, #-2139; CHECK: stur    x1, [x29, #16]140; CHECK: .Lvla_present$frame_escape_0 = -4141; CHECK: stur    w0, [x29, #-4]142; CHECK: ldur    w8, [x29, #-4]143; CHECK: mov     x9, sp144; CHECK: stur    x9, [x29, #-16]145; CHECK: stur    x8, [x29, #-24]146; CHECK: ldur    w0, [x29, #-4]147; CHECK: bl      foo148 149  %n.addr = alloca i32, align 4150  %saved_stack = alloca ptr, align 8151  %__vla_expr0 = alloca i64, align 8152  call void (...) @llvm.localescape(ptr %n.addr)153  store i32 %n, ptr %n.addr, align 4154  %0 = load i32, ptr %n.addr, align 4155  %1 = zext i32 %0 to i64156  %2 = call ptr @llvm.stacksave()157  store ptr %2, ptr %saved_stack, align 8158  %vla = alloca i32, i64 %1, align 4159  store i64 %1, ptr %__vla_expr0, align 8160  %3 = load i32, ptr %n.addr, align 4161  invoke void @foo(i32 %3) #5162          to label %invoke.cont unwind label %ehcleanup163 164invoke.cont:                                      ; preds = %entry165  %4 = call ptr @llvm.localaddress()166  call void @fin_vla_present(i8 0, ptr %4)167  %5 = load ptr, ptr %saved_stack, align 8168  call void @llvm.stackrestore(ptr %5)169  ret void170 171ehcleanup:                                        ; preds = %entry172  %6 = cleanuppad within none []173  %7 = call ptr @llvm.localaddress()174  call void @fin_vla_present(i8 1, ptr %7) [ "funclet"(token %6) ]175  cleanupret from %6 unwind to caller176}177 178define void @fin_vla_present(i8 %abnormal_termination, ptr %frame_pointer) {179entry:180; CHECK-LABEL: fin_vla_present181; CHECK: movz    x8, #:abs_g1_s:.Lvla_present$frame_escape_0182; CHECK: movk    x8, #:abs_g0_nc:.Lvla_present$frame_escape_0183; CHECK: strb    w0, [sp, #15]184; CHECK: ldr     w8, [x1, x8]185; CHECK: bl      foo186 187  %frame_pointer.addr = alloca ptr, align 8188  %abnormal_termination.addr = alloca i8, align 1189  %0 = call ptr @llvm.localrecover(ptr @vla_present, ptr %frame_pointer, i32 0)190  store ptr %frame_pointer, ptr %frame_pointer.addr, align 8191  store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 1192  %1 = load i32, ptr %0, align 4193  call void @foo(i32 %1)194  ret void195}196 197; Test when both vla's and highly aligned objects are present on stack.198define void @vla_and_realign(i32 %n) #0 personality ptr @__C_specific_handler {199entry:200; CHECK-LABEL: vla_and_realign201; CHECK: add     x29, sp, #8202; CHECK: sub     x9, sp, #48203; CHECK: and     sp, x9, #0xffffffffffffffe0204; CHECK: mov     x19, sp205; CHECK: mov     x1, #-2206; CHECK: stur    x1, [x29, #24]207; CHECK: .Lvla_and_realign$frame_escape_0 = 32208; CHECK: str     w0, [x29, #36]209; CHECK: ldr     w8, [x29, #36]210; CHECK: mov     x9, sp211; CHECK: str     x9, [x29, #16]212; CHECK: str     x8, [x19, #24]213; CHECK: ldr     w0, [x19, #32]214; CHECK: bl      foo215 216  %n.addr = alloca i32, align 4217  %o = alloca %struct.S, align 32218  %saved_stack = alloca ptr, align 8219  %__vla_expr0 = alloca i64, align 8220  call void (...) @llvm.localescape(ptr %o)221  store i32 %n, ptr %n.addr, align 4222  %0 = load i32, ptr %n.addr, align 4223  %1 = zext i32 %0 to i64224  %2 = call ptr @llvm.stacksave()225  store ptr %2, ptr %saved_stack, align 8226  %vla = alloca i32, i64 %1, align 4227  store i64 %1, ptr %__vla_expr0, align 8228  %3 = load i32, ptr %o, align 32229  invoke void @foo(i32 %3) #5230          to label %invoke.cont unwind label %ehcleanup231 232invoke.cont:                                      ; preds = %entry233  %4 = call ptr @llvm.localaddress()234  call void @fin_vla_and_realign(i8 0, ptr %4)235  %5 = load ptr, ptr %saved_stack, align 8236  call void @llvm.stackrestore(ptr %5)237  ret void238 239ehcleanup:                                        ; preds = %entry240  %6 = cleanuppad within none []241  %7 = call ptr @llvm.localaddress()242  call void @fin_vla_and_realign(i8 1, ptr %7) [ "funclet"(token %6) ]243  cleanupret from %6 unwind to caller244}245 246define void @fin_vla_and_realign(i8 %abnormal_termination, ptr %frame_pointer) {247entry:248; CHECK-LABEL: fin_vla_and_realign249; CHECK: movz    x8, #:abs_g1_s:.Lvla_and_realign$frame_escape_0250; CHECK: movk    x8, #:abs_g0_nc:.Lvla_and_realign$frame_escape_0251; CHECK: strb    w0, [sp, #15]252; CHECK: ldr     w8, [x1, x8]253; CHECK: bl      foo254 255  %frame_pointer.addr = alloca ptr, align 8256  %abnormal_termination.addr = alloca i8, align 1257  %0 = call ptr @llvm.localrecover(ptr @vla_and_realign, ptr %frame_pointer, i32 0)258  store ptr %frame_pointer, ptr %frame_pointer.addr, align 8259  store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 1260  %1 = load i32, ptr %0, align 32261  call void @foo(i32 %1)262  ret void263}264 265declare void @foo(i32)266declare void @llvm.stackrestore(ptr)267declare ptr @llvm.stacksave()268declare ptr @llvm.localrecover(ptr, ptr, i32)269declare ptr @llvm.localaddress()270declare void @llvm.localescape(...)271declare i32 @__C_specific_handler(...)272 273attributes #0 = { noinline optnone }274