[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / wineh-try-catch.ll
blobb27e5374b257623e604b75b7c28ecf364e6cf92f
1 ; RUN: llc -o - %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s
2 ; RUN: llc -o %t -filetype=obj %s -mtriple=aarch64-windows
3 ; RUN: llvm-readobj --unwind %t | FileCheck %s -check-prefix=UNWIND
5 ; We test the following
6 ; 1) That the unwind help object is created and that its offset from the stack
7 ;    pointer on entry is patched into the table fed to __CxxFrameHandler3
8 ; 2) That the stack update for the catch funclet only includes the callee saved
9 ;    registers
10 ; 3) That the locals are accessed using the frame pointer in both the funclet
11 ;    and the parent function.
13 ; The following checks that the unwind help object has -2 stored into it at
14 ; fp + 16, which is on-entry sp - 16.
15 ; We check this offset in the table later on.
17 ; CHECK-LABEL: "?func@@YAHXZ":
18 ; CHECK:       stp     x19, x20, [sp, #-64]!
19 ; CHECK:       str     x21, [sp, #16]
20 ; CHECK:       str     x28, [sp, #24]
21 ; CHECK:       stp     x29, x30, [sp, #32]
22 ; CHECK:       add     x29, sp, #32
23 ; CHECK:       sub     sp, sp, #624
24 ; CHECK:       mov     x19, sp
25 ; CHECK:       mov     x0, #-2
26 ; CHECK:       stur    x0, [x29, #16]
28 ; Now check that x is stored at fp - 20.  We check that this is the same
29 ; location accessed from the funclet to retrieve x.
30 ; CHECK:       mov     w8, #1
31 ; CHECK:       stur    w8, [x29, [[X_OFFSET:#-[1-9][0-9]+]]
33 ; Check the offset off the frame pointer at which B is located.
34 ; Check the same offset is used to pass the address of B to init2 in the
35 ; funclet.
36 ; CHECK:       sub     x0, x29, [[B_OFFSET:#[1-9][0-9]+]]
37 ; CHECK:       bl      "?init@@YAXPEAH@Z"
39 ; This is the label for the throw that is encoded in the ip2state.
40 ; We are inside the try block, where we make a call to func2
41 ; CHECK-LABEL: .Ltmp0:
42 ; CHECK:       bl      "?func2@@YAHXZ
44 ; CHECK:        [[CATCHRETDEST:.LBB0_[0-9]+]]:      // %catchret.dest
46 ; Check the catch funclet.
47 ; CHECK-LABEL: "?catch$4@?0??func@@YAHXZ@4HA":
49 ; Check that the stack space is allocated only for the callee saved registers.
50 ; CHECK:       stp     x19, x20, [sp, #-48]!
51 ; CHECK:       str     x21, [sp, #16]
52 ; CHECK:       str     x28, [sp, #24]
53 ; CHECK:       stp     x29, x30, [sp, #32]
54 ; CHECK:       add     x20, x19, #12
56 ; Check that there are no further stack updates.
57 ; CHECK-NOT:   sub     sp, sp
59 ; Check that the stack address passed to init2 is off the frame pointer, and
60 ; that it matches the address of B in the parent function.
61 ; CHECK:       sub     x0, x29, [[B_OFFSET]]
62 ; CHECK:       bl      "?init2@@YAXPEAH@Z"
64 ; Check that are storing x back to the same location off the frame pointer as in
65 ; the parent function.
66 ; CHECK:       stur    w8, [x29, [[X_OFFSET]]]
68 ; Check that the funclet branches back to the catchret destination
69 ; CHECK:       adrp    x0, .LBB0_2
70 ; CHECK-NEXT:  add     x0, x0, [[CATCHRETDEST]]
73 ; Now check that the offset of the unwind help object from the stack pointer on
74 ; entry to func is encoded in cppxdata that is passed to __CxxFrameHandler3.  As
75 ; computed above, this comes to -16.
76 ; CHECK-LABEL:        "$cppxdata$?func@@YAHXZ":
77 ; CHECK-NEXT:         .word   429065506               // MagicNumber
78 ; CHECK-NEXT:         .word   2                       // MaxState
79 ; CHECK-NEXT:         .word   ("$stateUnwindMap$?func@@YAHXZ")@IMGREL // UnwindMap
80 ; CHECK-NEXT:         .word   1                       // NumTryBlocks
81 ; CHECK-NEXT:         .word   ("$tryMap$?func@@YAHXZ")@IMGREL // TryBlockMap
82 ; CHECK-NEXT:         .word   4                       // IPMapEntries
83 ; CHECK-NEXT:         .word   ("$ip2state$?func@@YAHXZ")@IMGREL // IPToStateXData
84 ; CHECK-NEXT:         .word   -16                     // UnwindHelp
86 ; UNWIND: Function: ?func@@YAHXZ (0x0)
87 ; UNWIND: Prologue [
88 ; UNWIND-NEXT: ; add fp, sp, #32
89 ; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
90 ; UNWIND-NEXT: ; str x28, [sp, #24]
91 ; UNWIND-NEXT: ; str x21, [sp, #16]
92 ; UNWIND-NEXT: ; stp x19, x20, [sp, #-64]!
93 ; UNWIND-NEXT: ; end
94 ; UNWIND: Function: ?catch$4@?0??func@@YAHXZ@4HA
95 ; UNWIND: Prologue [
96 ; UNWIND-NEXT: ; stp x29, x30, [sp, #32]
97 ; UNWIND-NEXT: ; str x28, [sp, #24]
98 ; UNWIND-NEXT: ; str x21, [sp, #16]
99 ; UNWIND-NEXT: ; stp x19, x20, [sp, #-48]!
100 ; UNWIND-NEXT: ; end
102 target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
103 target triple = "aarch64-unknown-windows-msvc19.11.0"
105 %rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }
106 %eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
107 %eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
108 %eh.ThrowInfo = type { i32, i32, i32, i32 }
110 $"??_R0H@8" = comdat any
112 $"_CT??_R0H@84" = comdat any
114 $_CTA1H = comdat any
116 $_TI1H = comdat any
118 @"??_7type_info@@6B@" = external constant ptr
119 @"??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { ptr @"??_7type_info@@6B@", ptr null, [3 x i8] c".H\00" }, comdat
120 @__ImageBase = external dso_local constant i8
121 @"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??_R0H@8" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
122 @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"_CT??_R0H@84" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
123 @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @_CTA1H to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32) }, section ".xdata", comdat
125 ; Function Attrs: noinline optnone
126 define dso_local i32 @"?func@@YAHXZ"() #0 personality ptr @__CxxFrameHandler3 {
127 entry:
128   %B = alloca [50 x i32], align 4
129   %x = alloca i32, align 4
130   %tmp = alloca i32, align 4
131   %i = alloca i32, align 4
132   %C = alloca [100 x i32], align 4
133   store i32 1, ptr %x, align 4
134   call void @"?init@@YAXPEAH@Z"(ptr %B)
135   %call = invoke i32 @"?func2@@YAHXZ"()
136           to label %invoke.cont unwind label %catch.dispatch
138 invoke.cont:                                      ; preds = %entry
139   store i32 %call, ptr %tmp, align 4
140   invoke void @_CxxThrowException(ptr %tmp, ptr @_TI1H) #2
141           to label %unreachable unwind label %catch.dispatch
143 catch.dispatch:                                   ; preds = %invoke.cont, %entry
144   %0 = catchswitch within none [label %catch] unwind to caller
146 catch:                                            ; preds = %catch.dispatch
147   %1 = catchpad within %0 [ptr @"??_R0H@8", i32 0, ptr %i]
148   call void @"?init@@YAXPEAH@Z"(ptr %C) [ "funclet"(token %1) ]
149   call void @"?init2@@YAXPEAH@Z"(ptr %B) [ "funclet"(token %1) ]
150   %2 = load i32, ptr %i, align 4
151   %idxprom = sext i32 %2 to i64
152   %arrayidx = getelementptr inbounds [50 x i32], ptr %B, i64 0, i64 %idxprom
153   %3 = load i32, ptr %arrayidx, align 4
154   %4 = load i32, ptr %i, align 4
155   %idxprom3 = sext i32 %4 to i64
156   %arrayidx4 = getelementptr inbounds [100 x i32], ptr %C, i64 0, i64 %idxprom3
157   %5 = load i32, ptr %arrayidx4, align 4
158   %add = add nsw i32 %3, %5
159   %6 = load i32, ptr %i, align 4
160   %7 = load i32, ptr %i, align 4
161   %mul = mul nsw i32 %6, %7
162   %add5 = add nsw i32 %add, %mul
163   store i32 %add5, ptr %x, align 4
164   catchret from %1 to label %catchret.dest
166 catchret.dest:                                    ; preds = %catch
167   br label %try.cont
169 try.cont:                                         ; preds = %catchret.dest
170   %arrayidx6 = getelementptr inbounds [50 x i32], ptr %B, i64 0, i64 2
171   %8 = load i32, ptr %arrayidx6, align 4
172   %9 = load i32, ptr %x, align 4
173   %add7 = add nsw i32 %8, %9
174   ret i32 %add7
176 unreachable:                                      ; preds = %invoke.cont
177   unreachable
180 declare dso_local void @"?init@@YAXPEAH@Z"(ptr)
182 declare dso_local i32 @"?func2@@YAHXZ"()
184 declare dso_local i32 @__CxxFrameHandler3(...)
186 declare dllimport void @_CxxThrowException(ptr, ptr)
188 declare dso_local void @"?init2@@YAXPEAH@Z"(ptr)
190 attributes #0 = { noinline optnone }
191 attributes #2 = { noreturn }