summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/AArch64
diff options
context:
space:
mode:
authorMandeep Singh Grang <mgrang@codeaurora.org>2019-01-16 19:52:59 +0000
committerMandeep Singh Grang <mgrang@codeaurora.org>2019-01-16 19:52:59 +0000
commit33c49c0c82a5878f8f9d71e3f1710eddfdbebfeb (patch)
treec590e8ffacedef444feaa07faa1167458d8c8edd /llvm/test/CodeGen/AArch64
parent4121eaf0a547b0d6a34ecb27da4fbbc2c091d9ae (diff)
downloadbcm5719-llvm-33c49c0c82a5878f8f9d71e3f1710eddfdbebfeb.tar.gz
bcm5719-llvm-33c49c0c82a5878f8f9d71e3f1710eddfdbebfeb.zip
[COFF, ARM64] Implement support for SEH extensions __try/__except/__finally
Summary: This patch supports MS SEH extensions __try/__except/__finally. The intrinsics localescape and localrecover are responsible for communicating escaped static allocas from the try block to the handler. We need to preserve frame pointers for SEH. So we create a new function/property HasLocalEscape. Reviewers: rnk, compnerd, mstorsjo, TomTan, efriedma, ssijaric Reviewed By: rnk, efriedma Subscribers: smeenai, jrmuizel, alex, majnemer, ssijaric, ehsan, dmajor, kristina, javed.absar, kristof.beyls, chrib, llvm-commits Differential Revision: https://reviews.llvm.org/D53540 llvm-svn: 351370
Diffstat (limited to 'llvm/test/CodeGen/AArch64')
-rw-r--r--llvm/test/CodeGen/AArch64/seh-finally.ll67
-rw-r--r--llvm/test/CodeGen/AArch64/seh-localescape.ll30
2 files changed, 97 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/seh-finally.ll b/llvm/test/CodeGen/AArch64/seh-finally.ll
new file mode 100644
index 00000000000..3cbbd03385c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/seh-finally.ll
@@ -0,0 +1,67 @@
+; RUN: llc -mtriple arm64-windows -o - %s | FileCheck %s
+
+; Function Attrs: noinline optnone uwtable
+define dso_local i32 @foo() {
+entry:
+; CHECK-LABEL: foo
+; CHECK: orr w8, wzr, #0x1
+; CHECK: mov w0, wzr
+; CHECK: mov x1, x29
+; CHECK: .set .Lfoo$frame_escape_0, -4
+; CHECK: stur w8, [x29, #-4]
+; CHECK: bl "?fin$0@0@foo@@"
+; CHECK: ldur w0, [x29, #-4]
+
+ %count = alloca i32, align 4
+ call void (...) @llvm.localescape(i32* %count)
+ store i32 0, i32* %count, align 4
+ %0 = load i32, i32* %count, align 4
+ %add = add nsw i32 %0, 1
+ store i32 %add, i32* %count, align 4
+ %1 = call i8* @llvm.localaddress()
+ call void @"?fin$0@0@foo@@"(i8 0, i8* %1)
+ %2 = load i32, i32* %count, align 4
+ ret i32 %2
+}
+
+define internal void @"?fin$0@0@foo@@"(i8 %abnormal_termination, i8* %frame_pointer) {
+entry:
+; CHECK-LABEL: @"?fin$0@0@foo@@"
+; CHECK: sub sp, sp, #16
+; CHECK: str x1, [sp, #8]
+; CHECK: strb w0, [sp, #7]
+; CHECK: movz x8, #:abs_g1_s:.Lfoo$frame_escape_0
+; CHECK: movk x8, #:abs_g0_nc:.Lfoo$frame_escape_0
+; CHECK: add x8, x1, x8
+; CHECK: ldr w9, [x8]
+; CHECK: add w9, w9, #1
+; CHECK: str w9, [x8]
+
+ %frame_pointer.addr = alloca i8*, align 8
+ %abnormal_termination.addr = alloca i8, align 1
+ %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @foo to i8*), i8* %frame_pointer, i32 0)
+ %count = bitcast i8* %0 to i32*
+ store i8* %frame_pointer, i8** %frame_pointer.addr, align 8
+ store i8 %abnormal_termination, i8* %abnormal_termination.addr, align 1
+ %1 = zext i8 %abnormal_termination to i32
+ %cmp = icmp eq i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %2 = load i32, i32* %count, align 4
+ %add = add nsw i32 %2, 1
+ store i32 %add, i32* %count, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.localrecover(i8*, i8*, i32)
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.localaddress()
+
+; Function Attrs: nounwind
+declare void @llvm.localescape(...)
diff --git a/llvm/test/CodeGen/AArch64/seh-localescape.ll b/llvm/test/CodeGen/AArch64/seh-localescape.ll
new file mode 100644
index 00000000000..0a1675014f6
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/seh-localescape.ll
@@ -0,0 +1,30 @@
+; RUN: llc -mtriple arm64-windows %s -o - | FileCheck %s
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @foo() {
+entry:
+; CHECK-LABEL: foo
+; CHECK: .set .Lfoo$frame_escape_0, -4
+
+ %count = alloca i32, align 4
+ call void (...) @llvm.localescape(i32* %count)
+ ret i32 0
+}
+
+define internal i32 @"?filt$0@0@foo@@"(i8* %exception_pointers, i8* %frame_pointer) {
+entry:
+; CHECK-LABEL: @"?filt$0@0@foo@@"
+; CHECK: movz x8, #:abs_g1_s:.Lfoo$frame_escape_0
+; CHECK: movk x8, #:abs_g0_nc:.Lfoo$frame_escape_0
+
+ %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @foo to i8*), i8* %frame_pointer, i32 0)
+ %count = bitcast i8* %0 to i32*
+ %1 = load i32, i32* %count, align 4
+ ret i32 %1
+}
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.localrecover(i8*, i8*, i32) #2
+
+; Function Attrs: nounwind
+declare void @llvm.localescape(...) #3
OpenPOWER on IntegriCloud