[IR] Reformulate LLVM's EH funclet IR
[oota-llvm.git] / test / CodeGen / X86 / win-cleanuppad.ll
1 ; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s
2 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s
3
4 %struct.Dtor = type { i8 }
5
6 define void @simple_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
7 entry:
8   %o = alloca %struct.Dtor, align 1
9   invoke void @f(i32 1)
10           to label %invoke.cont unwind label %ehcleanup
11
12 invoke.cont:                                      ; preds = %entry
13   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2
14   ret void
15
16 ehcleanup:                                        ; preds = %entry
17   %0 = cleanuppad within none []
18   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2
19   cleanupret from %0 unwind to caller
20 }
21
22 ; CHECK: simple_cleanup:                         # @simple_cleanup
23 ; CHECK:         pushq   %rbp
24 ; CHECK:         subq    $48, %rsp
25 ; CHECK:         leaq    48(%rsp), %rbp
26 ; CHECK:         movq    $-2, -8(%rbp)
27 ; CHECK:         movl    $1, %ecx
28 ; CHECK:         callq   f
29 ; CHECK:         callq   "??1Dtor@@QAE@XZ"
30 ; CHECK:         nop
31 ; CHECK:         addq    $48, %rsp
32 ; CHECK:         popq    %rbp
33 ; CHECK:         retq
34
35 ; CHECK: "?dtor$2@?0?simple_cleanup@4HA":
36 ; CHECK:         callq   "??1Dtor@@QAE@XZ"
37 ; CHECK:         retq
38
39 ; CHECK: $cppxdata$simple_cleanup:
40 ; CHECK-NEXT:         .long   429065506
41 ; CHECK-NEXT:         .long   1
42 ; CHECK-NEXT:         .long   ($stateUnwindMap$simple_cleanup)@IMGREL
43 ; CHECK-NEXT:         .long   0
44 ; CHECK-NEXT:         .long   0
45 ; CHECK-NEXT:         .long   3
46 ; CHECK-NEXT:         .long   ($ip2state$simple_cleanup)@IMGREL
47 ; UnwindHelp offset should match the -2 store above
48 ; CHECK-NEXT:         .long   40
49 ; CHECK-NEXT:         .long   0
50 ; CHECK-NEXT:         .long   1
51
52 declare void @f(i32) #0
53
54 declare i32 @__CxxFrameHandler3(...)
55
56 ; Function Attrs: nounwind
57 declare x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor*) #1
58
59 define void @nested_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
60 entry:
61   %o1 = alloca %struct.Dtor, align 1
62   %o2 = alloca %struct.Dtor, align 1
63   invoke void @f(i32 1)
64           to label %invoke.cont unwind label %cleanup.outer
65
66 invoke.cont:                                      ; preds = %entry
67   invoke void @f(i32 2)
68           to label %invoke.cont.1 unwind label %cleanup.inner
69
70 invoke.cont.1:                                    ; preds = %invoke.cont
71   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2
72   invoke void @f(i32 3)
73           to label %invoke.cont.2 unwind label %cleanup.outer
74
75 invoke.cont.2:                                    ; preds = %invoke.cont.1
76   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2
77   ret void
78
79 cleanup.inner:                                        ; preds = %invoke.cont
80   %0 = cleanuppad within none []
81   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2
82   cleanupret from %0 unwind label %cleanup.outer
83
84 cleanup.outer:                                      ; preds = %invoke.cont.1, %cleanup.inner, %entry
85   %1 = cleanuppad within none []
86   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2
87   cleanupret from %1 unwind to caller
88 }
89
90 ; X86-LABEL: _nested_cleanup:
91 ; X86: movl    $1, (%esp)
92 ; X86: calll   _f
93 ; X86: movl    $2, (%esp)
94 ; X86: calll   _f
95 ; X86: movl    $3, (%esp)
96 ; X86: calll   _f
97
98 ; X86: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA":
99 ; X86: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
100 ; X86: pushl %ebp
101 ; X86: leal    {{.*}}(%ebp), %ecx
102 ; X86: calll   "??1Dtor@@QAE@XZ"
103 ; X86: popl %ebp
104 ; X86: retl
105
106 ; X86: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA":
107 ; X86: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
108 ; X86: pushl %ebp
109 ; X86: leal    {{.*}}(%ebp), %ecx
110 ; X86: calll   "??1Dtor@@QAE@XZ"
111 ; X86: popl %ebp
112 ; X86: retl
113
114 ; X86: L__ehtable$nested_cleanup:
115 ; X86:         .long   429065506
116 ; X86:         .long   2
117 ; X86:         .long   ($stateUnwindMap$nested_cleanup)
118 ; X86:         .long   0
119 ; X86:         .long   0
120 ; X86:         .long   0
121 ; X86:         .long   0
122 ; X86:         .long   0
123 ; X86:         .long   1
124 ; X86: $stateUnwindMap$nested_cleanup:
125 ; X86:         .long   -1
126 ; X86:         .long   "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA"
127 ; X86:         .long   0
128 ; X86:         .long   "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA"
129
130 ; X64-LABEL: nested_cleanup:
131 ; X64: .Lfunc_begin1:
132 ; X64: .Ltmp13:
133 ; X64: movl    $1, %ecx
134 ; X64: callq   f
135 ; X64: .Ltmp15:
136 ; X64: movl    $2, %ecx
137 ; X64: callq   f
138 ; X64: .Ltmp16:
139 ; X64: callq   "??1Dtor@@QAE@XZ"
140 ; X64: .Ltmp17:
141 ; X64: movl    $3, %ecx
142 ; X64: callq   f
143 ; X64: .Ltmp18:
144
145 ; X64: "?dtor$[[cleanup_inner:[0-9]+]]@?0?nested_cleanup@4HA":
146 ; X64: LBB1_[[cleanup_inner]]: # %cleanup.inner{{$}}
147 ; X64: pushq %rbp
148 ; X64: leaq    {{.*}}(%rbp), %rcx
149 ; X64: callq   "??1Dtor@@QAE@XZ"
150 ; X64: popq %rbp
151 ; X64: retq
152
153 ; X64:        .seh_handlerdata
154 ; X64:        .text
155 ; X64:        .seh_endproc
156
157 ; X64: "?dtor$[[cleanup_outer:[0-9]+]]@?0?nested_cleanup@4HA":
158 ; X64: LBB1_[[cleanup_outer]]: # %cleanup.outer{{$}}
159 ; X64: pushq %rbp
160 ; X64: leaq    {{.*}}(%rbp), %rcx
161 ; X64: callq   "??1Dtor@@QAE@XZ"
162 ; X64: popq %rbp
163 ; X64: retq
164
165 ; X64:        .section .xdata,"dr"
166 ; X64-NEXT: .align  4
167 ; X64: $cppxdata$nested_cleanup:
168 ; X64-NEXT: .long   429065506
169 ; X64-NEXT: .long   2
170 ; X64-NEXT: .long   ($stateUnwindMap$nested_cleanup)@IMGREL
171 ; X64-NEXT: .long   0
172 ; X64-NEXT: .long   0
173 ; X64-NEXT: .long   5
174 ; X64-NEXT: .long   ($ip2state$nested_cleanup)@IMGREL
175 ; X64-NEXT: .long   56
176 ; X64-NEXT: .long   0
177 ; X64-NEXT: .long   1
178
179 ; X64: $stateUnwindMap$nested_cleanup:
180 ; X64-NEXT: .long   -1
181 ; X64-NEXT: .long   "?dtor$[[cleanup_outer]]@?0?nested_cleanup@4HA"@IMGREL
182 ; X64-NEXT: .long   0
183 ; X64-NEXT: .long   "?dtor$[[cleanup_inner]]@?0?nested_cleanup@4HA"@IMGREL
184
185 ; X64: $ip2state$nested_cleanup:
186 ; X64-NEXT: .long   .Lfunc_begin1@IMGREL
187 ; X64-NEXT: .long   -1
188 ; X64-NEXT: .long   .Ltmp13@IMGREL
189 ; X64-NEXT: .long   0
190 ; X64-NEXT: .long   .Ltmp15@IMGREL
191 ; X64-NEXT: .long   1
192 ; X64-NEXT: .long   .Ltmp17@IMGREL
193 ; X64-NEXT: .long   0
194 ; X64-NEXT: .long   .Ltmp18@IMGREL+1
195 ; X64-NEXT: .long   -1
196
197 attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
198 attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
199 attributes #2 = { nounwind }