summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/AArch64/wineh-try-catch-nobase.ll49
-rw-r--r--llvm/test/CodeGen/AArch64/wineh-try-catch-realign.ll59
-rw-r--r--llvm/test/CodeGen/AArch64/wineh-try-catch-vla.ll52
-rw-r--r--llvm/test/CodeGen/AArch64/wineh-try-catch.ll197
4 files changed, 357 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch-nobase.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch-nobase.ll
new file mode 100644
index 00000000000..9d3af8043d7
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/wineh-try-catch-nobase.ll
@@ -0,0 +1,49 @@
+; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
+
+; Make sure we don't have a base pointer.
+; CHECK-LABEL: "?a@@YAXXZ":
+; CHECK-NOT: x19
+
+; Check that we compute the address relative to fp.
+; CHECK-LABEL: "?catch$2@?0??a@@YAXXZ@4HA":
+; CHECK: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-NEXT: sub x0, x29, #16 ; =16
+; CHECK-NEXT: mov x1, xzr
+; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z"
+; CHECK-NEXT: adrp x0, .LBB0_1
+; CHECK-NEXT: add x0, x0, .LBB0_1
+; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-NEXT: ret
+
+target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-windows-msvc19.11.0"
+
+define dso_local void @"?a@@YAXXZ"(i64 %p1) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %a = alloca i32, align 16
+ %0 = bitcast i32* %a to i8*
+ store i32 305419896, i32* %a, align 16
+ invoke void @"?bb@@YAXPEAHH@Z"(i32* nonnull %a, i32* null)
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %1 = catchswitch within none [label %catch] unwind to caller
+
+catch: ; preds = %catch.dispatch
+ %2 = catchpad within %1 [i8* null, i32 64, i8* null]
+ call void @"?bb@@YAXPEAHH@Z"(i32* nonnull %a, i32* null) [ "funclet"(token %2) ]
+ catchret from %2 to label %try.cont
+
+try.cont: ; preds = %entry, %catch
+ call void @"?cc@@YAXXZ"()
+ ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1)
+
+declare dso_local void @"?bb@@YAXPEAHH@Z"(i32*, i32*)
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+
+declare dso_local void @"?cc@@YAXXZ"()
+
diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch-realign.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch-realign.ll
new file mode 100644
index 00000000000..78255fbb166
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/wineh-try-catch-realign.ll
@@ -0,0 +1,59 @@
+; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
+
+; Make sure we have a base pointer.
+; CHECK-LABEL: "?a@@YAXXZ":
+; CHECK: and sp, x9, #0xffffffffffffffc0
+; CHECK: mov x19, sp
+
+; Make sure the funclet prologue/epilogue are correct: specifically,
+; it shouldn't access the parent's frame via sp, and the prologue and
+; epilogue should be symmetrical.
+; CHECK-LABEL: "?catch$2@?0??a@@YAXXZ@4HA":
+; CHECK: str x28, [sp, #-32]!
+; CHECK-NEXT: str x19, [sp, #8]
+; CHECK-NEXT: stp x29, x30, [sp, #16]
+; CHECK-NEXT: add x0, x19, #64
+; CHECK-NEXT: mov w1, wzr
+; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z"
+; CHECK-NEXT: adrp x0, .LBB0_1
+; CHECK-NEXT: add x0, x0, .LBB0_1
+; CHECK-NEXT: ldp x29, x30, [sp, #16]
+; CHECK-NEXT: ldr x19, [sp, #8]
+; CHECK-NEXT: ldr x28, [sp], #32
+; CHECK-NEXT: ret
+
+
+target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-windows-msvc19.11.0"
+
+define dso_local void @"?a@@YAXXZ"() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %a = alloca [100 x i32], align 64
+ %0 = bitcast [100 x i32]* %a to i8*
+ call void @llvm.memset.p0i8.i64(i8* nonnull align 64 %0, i8 0, i64 400, i1 false)
+ %1 = getelementptr inbounds [100 x i32], [100 x i32]* %a, i64 0, i64 0
+ store i32 305419896, i32* %1, align 64
+ invoke void @"?bb@@YAXPEAHH@Z"(i32* nonnull %1, i32 1)
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %2 = catchswitch within none [label %catch] unwind to caller
+
+catch: ; preds = %catch.dispatch
+ %3 = catchpad within %2 [i8* null, i32 64, i8* null]
+ call void @"?bb@@YAXPEAHH@Z"(i32* nonnull %1, i32 0) [ "funclet"(token %3) ]
+ catchret from %3 to label %try.cont
+
+try.cont: ; preds = %entry, %catch
+ call void @"?cc@@YAXXZ"()
+ ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1)
+
+declare dso_local void @"?bb@@YAXPEAHH@Z"(i32*, i32)
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+
+declare dso_local void @"?cc@@YAXXZ"()
+
diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch-vla.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch-vla.ll
new file mode 100644
index 00000000000..7ae5ca54ff9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/wineh-try-catch-vla.ll
@@ -0,0 +1,52 @@
+; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
+
+; Check we don't have a base pointer.
+; CHECK-LABEL: "?a@@YAXXZ":
+; CHECK-NOT: x19
+
+; Make sure the prologue and epilogue are sane. Make sure the
+; frame index is relative to the FP, since there is no base pointer.
+; (Funclets aren't allowed to contain dynamic allocas.)
+; CHECK-LABEL: "?catch$2@?0??a@@YAXXZ@4HA":
+; CHECK: stp x29, x30, [sp, #-16]!
+; CHECK-NEXT: ldur x0, [x29, #-8]
+; CHECK-NEXT: mov x1, x0
+; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z"
+; CHECK-NEXT: adrp x0, .LBB0_1
+; CHECK-NEXT: add x0, x0, .LBB0_1
+; CHECK-NEXT: ldp x29, x30, [sp], #16
+; CHECK-NEXT: ret
+
+target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-windows-msvc19.11.0"
+
+define dso_local void @"?a@@YAXXZ"(i64 %p1) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %a = alloca i32, i64 %p1, align 16
+ %0 = bitcast i32* %a to i8*
+ call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %0, i8 0, i64 400, i1 false)
+ store i32 305419896, i32* %a, align 16
+ invoke void @"?bb@@YAXPEAHH@Z"(i32* nonnull %a, i32* null)
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %1 = catchswitch within none [label %catch] unwind to caller
+
+catch: ; preds = %catch.dispatch
+ %2 = catchpad within %1 [i8* null, i32 64, i8* null]
+ call void @"?bb@@YAXPEAHH@Z"(i32* nonnull %a, i32* %a) [ "funclet"(token %2) ]
+ catchret from %2 to label %try.cont
+
+try.cont: ; preds = %entry, %catch
+ call void @"?cc@@YAXXZ"()
+ ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1)
+
+declare dso_local void @"?bb@@YAXPEAHH@Z"(i32*, i32*)
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+
+declare dso_local void @"?cc@@YAXXZ"()
+
diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll
new file mode 100644
index 00000000000..940a86282d3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll
@@ -0,0 +1,197 @@
+; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
+; RUN: llc -o %t -filetype=obj %s -mtriple=aarch64-windows
+; RUN: llvm-readobj -unwind %t | FileCheck %s -check-prefix=UNWIND
+
+; We test the following
+; 1) That the unwind help object is created and that its offset from the stack
+; pointer on entry is patched into the table fed to __CxxFrameHandler3
+; 2) That the stack update for the catch funclet only includes the callee saved
+; registers
+; 3) That the locals are accessed using the frame pointer in both the funclet
+; and the parent function.
+
+; The following checks that the unwind help object has -2 stored into it at
+; fp - 400 - 256 = fp - 656, which is on-entry sp - 48 + 32 - 656 =
+; on-entry sp - 672. We check this offset in the table later on.
+
+; CHECK-LABEL: "?func@@YAHXZ":
+; CHECK: str x28, [sp, #-48]!
+; CHECK: str x21, [sp, #8]
+; CHECK: stp x19, x20, [sp, #16]
+; CHECK: stp x29, x30, [sp, #32]
+; CHECK: add x29, sp, #32
+; CHECK: sub sp, sp, #624
+; CHECK: mov x19, sp
+; CHECK: orr x1, xzr, #0xfffffffffffffffe
+; CHECK: stur x1, [x19]
+
+; Now check that x is stored at fp - 20. We check that this is the same
+; location accessed from the funclet to retrieve x.
+; CHECK: orr w8, wzr, #0x1
+; CHECK: stur w8, [x29, [[X_OFFSET:#-[1-9][0-9]+]]
+
+; Check the offset off the frame pointer at which B is located.
+; Check the same offset is used to pass the address of B to init2 in the
+; funclet.
+; CHECK: sub x0, x29, [[B_OFFSET:#[1-9][0-9]+]]
+; CHECK: bl "?init@@YAXPEAH@Z"
+
+; This is the label for the throw that is encoded in the ip2state.
+; We are inside the try block, where we make a call to func2
+; CHECK-LABEL: .Ltmp0:
+; CHECK: bl "?func2@@YAHXZ
+
+; CHECK: [[CATCHRETDEST:.LBB0_[0-9]+]]: ; %catchret.dest
+
+; Check the catch funclet.
+; CHECK-LABEL: "?catch$2@?0??func@@YAHXZ@4HA":
+
+; Check that the stack space is allocated only for the callee saved registers.
+; CHECK: str x28, [sp, #-48]!
+; CHECK: str x21, [sp, #8]
+; CHECK: stp x19, x20, [sp, #16]
+; CHECK: stp x29, x30, [sp, #32]
+; CHECK: add x20, x19, #12
+
+; Check that there are no further stack updates.
+; CHECK-NOT: sub sp, sp
+
+; Check that the stack address passed to init2 is off the frame pointer, and
+; that it matches the address of B in the parent function.
+; CHECK: sub x0, x29, [[B_OFFSET]]
+; CHECK: bl "?init2@@YAXPEAH@Z"
+
+; Check that are storing x back to the same location off the frame pointer as in
+; the parent function.
+; CHECK: stur w8, [x29, [[X_OFFSET]]]
+
+; Check that the funclet branches back to the catchret destination
+; CHECK: adrp x0, .LBB0_3
+; CHECK-NEXT: add x0, x0, [[CATCHRETDEST]]
+
+
+; Now check that the offset of the unwind help object from the stack pointer on
+; entry to func is encoded in cppxdata that is passed to __CxxFrameHandler3. As
+; computed above, this comes to -672.
+; CHECK-LABEL: "$cppxdata$?func@@YAHXZ":
+; CHECK-NEXT: .word 429065506 ; MagicNumber
+; CHECK-NEXT: .word 2 ; MaxState
+; CHECK-NEXT: .word ("$stateUnwindMap$?func@@YAHXZ")@IMGREL ; UnwindMap
+; CHECK-NEXT: .word 1 ; NumTryBlocks
+; CHECK-NEXT: .word ("$tryMap$?func@@YAHXZ")@IMGREL ; TryBlockMap
+; CHECK-NEXT: .word 4 ; IPMapEntries
+; CHECK-NEXT: .word ("$ip2state$?func@@YAHXZ")@IMGREL ; IPToStateXData
+; CHECK-NEXT: .word -672 ; UnwindHelp
+
+; UNWIND: Function: ?func@@YAHXZ (0x0)
+; UNWIND: Prologue [
+; UNWIND-NEXT: ; nop
+; UNWIND-NEXT: ; sub sp, #624
+; UNWIND-NEXT: ; add fp, sp, #32
+; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
+; UNWIND-NEXT: ; stp x19, x20, [sp, #16]
+; UNWIND-NEXT: ; str x21, [sp, #8]
+; UNWIND-NEXT: ; str x28, [sp, #48]!
+; UNWIND-NEXT: ; end
+; UNWIND: Function: ?catch$2@?0??func@@YAHXZ@4HA
+; UNWIND: Prologue [
+; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
+; UNWIND-NEXT: ; stp x19, x20, [sp, #16]
+; UNWIND-NEXT: ; str x21, [sp, #8]
+; UNWIND-NEXT: ; str x28, [sp, #48]!
+; UNWIND-NEXT: ; end
+
+target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-windows-msvc19.11.0"
+
+%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
+%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
+%eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
+%eh.ThrowInfo = type { i32, i32, i32, i32 }
+
+$"??_R0H@8" = comdat any
+
+$"_CT??_R0H@84" = comdat any
+
+$_CTA1H = comdat any
+
+$_TI1H = comdat any
+
+@"??_7type_info@@6B@" = external constant i8*
+@"??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+@__ImageBase = external dso_local constant i8
+@"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor2* @"??_R0H@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
+@_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0H@84" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
+@_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @_CTA1H to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat
+
+; Function Attrs: noinline optnone
+define dso_local i32 @"?func@@YAHXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %B = alloca [50 x i32], align 4
+ %x = alloca i32, align 4
+ %tmp = alloca i32, align 4
+ %i = alloca i32, align 4
+ %C = alloca [100 x i32], align 4
+ store i32 1, i32* %x, align 4
+ %arraydecay = getelementptr inbounds [50 x i32], [50 x i32]* %B, i32 0, i32 0
+ call void @"?init@@YAXPEAH@Z"(i32* %arraydecay)
+ %call = invoke i32 @"?func2@@YAHXZ"()
+ to label %invoke.cont unwind label %catch.dispatch
+
+invoke.cont: ; preds = %entry
+ store i32 %call, i32* %tmp, align 4
+ %0 = bitcast i32* %tmp to i8*
+ invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #2
+ to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %invoke.cont, %entry
+ %1 = catchswitch within none [label %catch] unwind to caller
+
+catch: ; preds = %catch.dispatch
+ %2 = catchpad within %1 [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i32* %i]
+ %arraydecay1 = getelementptr inbounds [100 x i32], [100 x i32]* %C, i32 0, i32 0
+ call void @"?init@@YAXPEAH@Z"(i32* %arraydecay1) [ "funclet"(token %2) ]
+ %arraydecay2 = getelementptr inbounds [50 x i32], [50 x i32]* %B, i32 0, i32 0
+ call void @"?init2@@YAXPEAH@Z"(i32* %arraydecay2) [ "funclet"(token %2) ]
+ %3 = load i32, i32* %i, align 4
+ %idxprom = sext i32 %3 to i64
+ %arrayidx = getelementptr inbounds [50 x i32], [50 x i32]* %B, i64 0, i64 %idxprom
+ %4 = load i32, i32* %arrayidx, align 4
+ %5 = load i32, i32* %i, align 4
+ %idxprom3 = sext i32 %5 to i64
+ %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* %C, i64 0, i64 %idxprom3
+ %6 = load i32, i32* %arrayidx4, align 4
+ %add = add nsw i32 %4, %6
+ %7 = load i32, i32* %i, align 4
+ %8 = load i32, i32* %i, align 4
+ %mul = mul nsw i32 %7, %8
+ %add5 = add nsw i32 %add, %mul
+ store i32 %add5, i32* %x, align 4
+ catchret from %2 to label %catchret.dest
+
+catchret.dest: ; preds = %catch
+ br label %try.cont
+
+try.cont: ; preds = %catchret.dest
+ %arrayidx6 = getelementptr inbounds [50 x i32], [50 x i32]* %B, i64 0, i64 2
+ %9 = load i32, i32* %arrayidx6, align 4
+ %10 = load i32, i32* %x, align 4
+ %add7 = add nsw i32 %9, %10
+ ret i32 %add7
+
+unreachable: ; preds = %invoke.cont
+ unreachable
+}
+
+declare dso_local void @"?init@@YAXPEAH@Z"(i32*)
+
+declare dso_local i32 @"?func2@@YAHXZ"()
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+
+declare dllimport void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+
+declare dso_local void @"?init2@@YAXPEAH@Z"(i32*)
+
+attributes #0 = { noinline optnone }
+attributes #2 = { noreturn }
OpenPOWER on IntegriCloud