• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
6define void @simple_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
7entry:
8  %o = alloca %struct.Dtor, align 1
9  invoke void @f(i32 1)
10          to label %invoke.cont unwind label %ehcleanup
11
12invoke.cont:                                      ; preds = %entry
13  call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2
14  ret void
15
16ehcleanup:                                        ; preds = %entry
17  %0 = cleanuppad within none []
18  call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 [ "funclet"(token %0) ]
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
52declare void @f(i32) #0
53
54declare i32 @__CxxFrameHandler3(...)
55
56; Function Attrs: nounwind
57declare x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor*) #1
58
59define void @nested_cleanup() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
60entry:
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
66invoke.cont:                                      ; preds = %entry
67  invoke void @f(i32 2)
68          to label %invoke.cont.1 unwind label %cleanup.inner
69
70invoke.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
75invoke.cont.2:                                    ; preds = %invoke.cont.1
76  call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2
77  ret void
78
79cleanup.inner:                                        ; preds = %invoke.cont
80  %0 = cleanuppad within none []
81  call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 [ "funclet"(token %0) ]
82  cleanupret from %0 unwind label %cleanup.outer
83
84cleanup.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 [ "funclet"(token %1) ]
87  cleanupret from %1 unwind to caller
88}
89
90; X86-LABEL: _nested_cleanup:
91; X86: pushl   $1
92; X86: calll   _f
93; X86: pushl   $2
94; X86: calll   _f
95; X86: pushl   $3
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: .Ltmp2:
133; X64: movl    $1, %ecx
134; X64: callq   f
135; X64: .Ltmp4:
136; X64: movl    $2, %ecx
137; X64: callq   f
138; X64: .Ltmp5:
139; X64: callq   "??1Dtor@@QAE@XZ"
140; X64: .Ltmp6:
141; X64: movl    $3, %ecx
142; X64: callq   f
143; X64: .Ltmp7:
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: .p2align  2
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   .Ltmp2@IMGREL
189; X64-NEXT: .long   0
190; X64-NEXT: .long   .Ltmp4@IMGREL
191; X64-NEXT: .long   1
192; X64-NEXT: .long   .Ltmp6@IMGREL
193; X64-NEXT: .long   0
194; X64-NEXT: .long   .Ltmp7@IMGREL+1
195; X64-NEXT: .long   -1
196
197attributes #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" }
198attributes #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" }
199attributes #2 = { nounwind }
200